Merge pull request #1689 from RafaelTaranto/chore/sumsub-rebase-simplified
chore: sumsub rebase simplified
This commit is contained in:
commit
09c3fb8a70
29 changed files with 828 additions and 73 deletions
53
new-lamassu-admin/src/components/buttons/DeleteButton.js
Normal file
53
new-lamassu-admin/src/components/buttons/DeleteButton.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import classnames from 'classnames'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { ReactComponent as DeleteIcon } from 'src/styling/icons/button/cancel/zodiac.svg'
|
||||
import { zircon, zircon2, comet, fontColor, white } from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
button: {
|
||||
extend: p,
|
||||
border: 'none',
|
||||
backgroundColor: zircon,
|
||||
cursor: 'pointer',
|
||||
outline: 0,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: 167,
|
||||
height: 48,
|
||||
color: fontColor,
|
||||
'&:hover': {
|
||||
backgroundColor: zircon2
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: comet,
|
||||
color: white,
|
||||
'& svg g *': {
|
||||
stroke: white
|
||||
}
|
||||
},
|
||||
'& svg': {
|
||||
marginRight: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const SimpleButton = memo(({ className, children, ...props }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<button className={classnames(classes.button, className)} {...props}>
|
||||
<DeleteIcon />
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
})
|
||||
|
||||
export default SimpleButton
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import ActionButton from './ActionButton'
|
||||
import AddButton from './AddButton'
|
||||
import Button from './Button'
|
||||
import DeleteButton from './DeleteButton'
|
||||
import FeatureButton from './FeatureButton'
|
||||
import IDButton from './IDButton'
|
||||
import IconButton from './IconButton'
|
||||
|
|
@ -19,5 +20,6 @@ export {
|
|||
IDButton,
|
||||
AddButton,
|
||||
SupportLinkButton,
|
||||
SubpageButton
|
||||
SubpageButton,
|
||||
DeleteButton
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ const Photo = ({ show, src }) => {
|
|||
|
||||
const CustomerData = ({
|
||||
locale,
|
||||
customer,
|
||||
customer = {},
|
||||
updateCustomer,
|
||||
replacePhoto,
|
||||
editCustomer,
|
||||
|
|
@ -399,6 +399,33 @@ const CustomerData = ({
|
|||
})
|
||||
}, R.keys(smsData) ?? [])
|
||||
|
||||
const externalCompliance = R.map(it => ({
|
||||
fields: [
|
||||
{
|
||||
name: 'externalId',
|
||||
label: 'Third Party ID',
|
||||
editable: false
|
||||
},
|
||||
{
|
||||
name: 'lastKnownStatus',
|
||||
label: 'Last Known Status',
|
||||
editable: false
|
||||
},
|
||||
{
|
||||
name: 'lastUpdated',
|
||||
label: 'Last Updated',
|
||||
editable: false
|
||||
}
|
||||
],
|
||||
titleIcon: <CardIcon className={classes.cardIcon} />,
|
||||
title: `External Info [${it.service}]`,
|
||||
initialValues: it ?? {
|
||||
externalId: '',
|
||||
lastKnownStatus: '',
|
||||
lastUpdated: ''
|
||||
}
|
||||
}))(customer.externalCompliance ?? [])
|
||||
|
||||
const editableCard = (
|
||||
{
|
||||
title,
|
||||
|
|
@ -440,6 +467,24 @@ const CustomerData = ({
|
|||
)
|
||||
}
|
||||
|
||||
const nonEditableCard = (
|
||||
{ title, state, titleIcon, fields, hasImage, initialValues, children },
|
||||
idx
|
||||
) => {
|
||||
return (
|
||||
<EditableCard
|
||||
title={title}
|
||||
key={idx}
|
||||
state={state}
|
||||
children={children}
|
||||
initialValues={initialValues}
|
||||
titleIcon={titleIcon}
|
||||
editable={false}
|
||||
hasImage={hasImage}
|
||||
fields={fields}></EditableCard>
|
||||
)
|
||||
}
|
||||
|
||||
const visibleCards = getVisibleCards(cards)
|
||||
|
||||
return (
|
||||
|
|
@ -514,6 +559,25 @@ const CustomerData = ({
|
|||
</Grid>
|
||||
</div>
|
||||
)}
|
||||
{!R.isEmpty(externalCompliance) && (
|
||||
<div className={classes.wrapper}>
|
||||
<span className={classes.separator}>
|
||||
External compliance information
|
||||
</span>
|
||||
<Grid container>
|
||||
<Grid container direction="column" item xs={6}>
|
||||
{externalCompliance.map((elem, idx) => {
|
||||
return isEven(idx) ? nonEditableCard(elem, idx) : null
|
||||
})}
|
||||
</Grid>
|
||||
<Grid container direction="column" item xs={6}>
|
||||
{externalCompliance.map((elem, idx) => {
|
||||
return !isEven(idx) ? nonEditableCard(elem, idx) : null
|
||||
})}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{retrieveAdditionalDataDialog}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ const GET_CUSTOMER = gql`
|
|||
isTestCustomer
|
||||
subscriberInfo
|
||||
phoneOverride
|
||||
externalCompliance
|
||||
customFields {
|
||||
id
|
||||
label
|
||||
|
|
@ -153,6 +154,7 @@ const SET_CUSTOMER = gql`
|
|||
lastTxClass
|
||||
subscriberInfo
|
||||
phoneOverride
|
||||
externalCompliance
|
||||
}
|
||||
}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import { useState, React } from 'react'
|
|||
import ErrorMessage from 'src/components/ErrorMessage'
|
||||
import PromptWhenDirty from 'src/components/PromptWhenDirty'
|
||||
import { MainStatus } from 'src/components/Status'
|
||||
// import { HoverableTooltip } from 'src/components/Tooltip'
|
||||
import { ActionButton } from 'src/components/buttons'
|
||||
import { Label1, P, H3 } from 'src/components/typography'
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
import { useQuery } from '@apollo/react-hooks'
|
||||
import { makeStyles } from '@material-ui/core'
|
||||
import Grid from '@material-ui/core/Grid'
|
||||
|
|
@ -6,7 +5,7 @@ import BigNumber from 'bignumber.js'
|
|||
import classnames from 'classnames'
|
||||
import gql from 'graphql-tag'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
import { Label2 } from 'src/components/typography'
|
||||
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||
|
|
@ -38,7 +37,7 @@ const Footer = () => {
|
|||
const withCommissions = R.path(['cryptoRates', 'withCommissions'])(data) ?? {}
|
||||
const classes = useStyles()
|
||||
const config = R.path(['config'])(data) ?? {}
|
||||
const canExpand = R.keys(withCommissions).length > 4
|
||||
// const canExpand = R.keys(withCommissions).length > 4
|
||||
|
||||
const wallets = fromNamespace('wallets')(config)
|
||||
const cryptoCurrencies = R.path(['cryptoCurrencies'])(data) ?? []
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import itbit from './itbit'
|
|||
import kraken from './kraken'
|
||||
import mailgun from './mailgun'
|
||||
import scorechain from './scorechain'
|
||||
import sumsub from './sumsub'
|
||||
import telnyx from './telnyx'
|
||||
import trongrid from './trongrid'
|
||||
import twilio from './twilio'
|
||||
|
|
@ -35,5 +36,6 @@ export default {
|
|||
[scorechain.code]: scorechain,
|
||||
[trongrid.code]: trongrid,
|
||||
[binance.code]: binance,
|
||||
[bitfinex.code]: bitfinex
|
||||
[bitfinex.code]: bitfinex,
|
||||
[sumsub.code]: sumsub
|
||||
}
|
||||
|
|
|
|||
44
new-lamassu-admin/src/pages/Services/schemas/sumsub.js
Normal file
44
new-lamassu-admin/src/pages/Services/schemas/sumsub.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import * as Yup from 'yup'
|
||||
|
||||
import { SecretInput, TextInput } from 'src/components/inputs/formik'
|
||||
|
||||
import { secretTest } from './helper'
|
||||
|
||||
const schema = {
|
||||
code: 'sumsub',
|
||||
name: 'Sumsub',
|
||||
title: 'Sumsub (Compliance)',
|
||||
elements: [
|
||||
{
|
||||
code: 'apiToken',
|
||||
display: 'API Token',
|
||||
component: SecretInput
|
||||
},
|
||||
{
|
||||
code: 'secretKey',
|
||||
display: 'Secret Key',
|
||||
component: SecretInput
|
||||
},
|
||||
{
|
||||
code: 'applicantLevel',
|
||||
display: 'Applicant Level',
|
||||
component: TextInput,
|
||||
face: true
|
||||
}
|
||||
],
|
||||
getValidationSchema: account => {
|
||||
return Yup.object().shape({
|
||||
apiToken: Yup.string('The API token must be a string')
|
||||
.max(100, 'The API token is too long')
|
||||
.test(secretTest(account?.apiToken, 'API token')),
|
||||
secretKey: Yup.string('The secret key must be a string')
|
||||
.max(100, 'The secret key is too long')
|
||||
.test(secretTest(account?.secretKey, 'secret key')),
|
||||
applicantLevel: Yup.string('The applicant level must be a string')
|
||||
.max(100, 'The applicant level is too long')
|
||||
.required('The applicant level is required')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default schema
|
||||
|
|
@ -28,8 +28,9 @@ const TriggerView = ({
|
|||
config,
|
||||
toggleWizard,
|
||||
addNewTriger,
|
||||
customInfoRequests,
|
||||
emailAuth
|
||||
emailAuth,
|
||||
complianceServices,
|
||||
customInfoRequests
|
||||
}) => {
|
||||
const currency = R.path(['fiatCurrency'])(
|
||||
fromNamespace(namespaces.LOCALE)(config)
|
||||
|
|
@ -78,7 +79,9 @@ const TriggerView = ({
|
|||
save={add}
|
||||
onClose={() => toggleWizard(true)}
|
||||
customInfoRequests={customInfoRequests}
|
||||
complianceServices={complianceServices}
|
||||
emailAuth={emailAuth}
|
||||
triggers={triggers}
|
||||
/>
|
||||
)}
|
||||
{R.isEmpty(triggers) && (
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ const GET_CONFIG = gql`
|
|||
query getData {
|
||||
config
|
||||
accounts
|
||||
accountsConfig {
|
||||
code
|
||||
display
|
||||
class
|
||||
cryptos
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
|
|
@ -75,6 +81,9 @@ const Triggers = () => {
|
|||
const emailAuth =
|
||||
data?.config?.triggersConfig_customerAuthentication === 'EMAIL'
|
||||
|
||||
const complianceServices = R.filter(R.propEq('class', 'compliance'))(
|
||||
data?.accountsConfig || []
|
||||
)
|
||||
const triggers = fromServer(data?.config?.triggers ?? [])
|
||||
const complianceConfig =
|
||||
data?.config && fromNamespace('compliance')(data.config)
|
||||
|
|
@ -135,7 +144,7 @@ const Triggers = () => {
|
|||
return (
|
||||
<>
|
||||
<TitleSection
|
||||
title="Compliance Triggers"
|
||||
title="Compliance triggers"
|
||||
buttons={[
|
||||
{
|
||||
text: 'Advanced settings',
|
||||
|
|
@ -219,8 +228,9 @@ const Triggers = () => {
|
|||
config={data?.config ?? {}}
|
||||
toggleWizard={toggleWizard('newTrigger')}
|
||||
addNewTriger={addNewTriger}
|
||||
customInfoRequests={enabledCustomInfoRequests}
|
||||
emailAuth={emailAuth}
|
||||
complianceServices={complianceServices}
|
||||
customInfoRequests={enabledCustomInfoRequests}
|
||||
/>
|
||||
)}
|
||||
{!loading && subMenu === 'advancedSettings' && (
|
||||
|
|
|
|||
|
|
@ -48,14 +48,27 @@ const styles = {
|
|||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const getStep = (step, currency, customInfoRequests, emailAuth) => {
|
||||
const getStep = (
|
||||
{ step, config },
|
||||
currency,
|
||||
customInfoRequests,
|
||||
complianceServices,
|
||||
emailAuth,
|
||||
triggers
|
||||
) => {
|
||||
switch (step) {
|
||||
// case 1:
|
||||
// return txDirection
|
||||
case 1:
|
||||
return type(currency)
|
||||
case 2:
|
||||
return requirements(customInfoRequests, emailAuth)
|
||||
return requirements(
|
||||
config,
|
||||
triggers,
|
||||
customInfoRequests,
|
||||
complianceServices,
|
||||
emailAuth
|
||||
)
|
||||
default:
|
||||
return Fragment
|
||||
}
|
||||
|
|
@ -166,6 +179,8 @@ const getRequirementText = (config, classes) => {
|
|||
return <>blocked</>
|
||||
case 'custom':
|
||||
return <>asked to fulfill a custom requirement</>
|
||||
case 'external':
|
||||
return <>redirected to an external verification process</>
|
||||
default:
|
||||
return orUnderline(null, classes)
|
||||
}
|
||||
|
|
@ -210,7 +225,9 @@ const Wizard = ({
|
|||
error,
|
||||
currency,
|
||||
customInfoRequests,
|
||||
emailAuth
|
||||
complianceServices,
|
||||
emailAuth,
|
||||
triggers
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
|
||||
|
|
@ -220,7 +237,14 @@ const Wizard = ({
|
|||
})
|
||||
|
||||
const isLastStep = step === LAST_STEP
|
||||
const stepOptions = getStep(step, currency, customInfoRequests, emailAuth)
|
||||
const stepOptions = getStep(
|
||||
{ step, config },
|
||||
currency,
|
||||
customInfoRequests,
|
||||
complianceServices,
|
||||
emailAuth,
|
||||
triggers
|
||||
)
|
||||
|
||||
const onContinue = async it => {
|
||||
const newConfig = R.merge(config, stepOptions.schema.cast(it))
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { NumberInput, RadioGroup, Dropdown } from 'src/components/inputs/formik'
|
|||
import { H4, Label2, Label1, Info1, Info2 } from 'src/components/typography'
|
||||
import { errorColor } from 'src/styling/variables'
|
||||
import { transformNumber } from 'src/utils/number'
|
||||
import { onlyFirstToUpper } from 'src/utils/string'
|
||||
|
||||
// import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||
// import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
||||
|
|
@ -82,6 +83,14 @@ const useStyles = makeStyles({
|
|||
dropdownField: {
|
||||
marginTop: 16,
|
||||
minWidth: 155
|
||||
},
|
||||
externalFields: {
|
||||
'& > *': {
|
||||
marginRight: 15
|
||||
},
|
||||
'& > *:last-child': {
|
||||
marginRight: 0
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -488,6 +497,13 @@ const requirementSchema = Yup.object()
|
|||
otherwise: Yup.string()
|
||||
.nullable()
|
||||
.transform(() => '')
|
||||
}),
|
||||
externalService: Yup.string().when('requirement', {
|
||||
is: value => value === 'external',
|
||||
then: Yup.string(),
|
||||
otherwise: Yup.string()
|
||||
.nullable()
|
||||
.transform(() => '')
|
||||
})
|
||||
}).required()
|
||||
})
|
||||
|
|
@ -502,6 +518,10 @@ const requirementSchema = Yup.object()
|
|||
return requirement.requirement === type
|
||||
? !R.isNil(requirement.customInfoRequestId)
|
||||
: true
|
||||
case 'external':
|
||||
return requirement.requirement === type
|
||||
? !R.isNil(requirement.externalService)
|
||||
: true
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
|
@ -518,6 +538,12 @@ const requirementSchema = Yup.object()
|
|||
path: 'requirement',
|
||||
message: 'You must select an item'
|
||||
})
|
||||
|
||||
if (requirement && !requirementValidator(requirement, 'external'))
|
||||
return context.createError({
|
||||
path: 'requirement',
|
||||
message: 'You must select an item'
|
||||
})
|
||||
})
|
||||
|
||||
const requirementOptions = [
|
||||
|
|
@ -530,7 +556,8 @@ const requirementOptions = [
|
|||
{ display: 'US SSN', code: 'usSsn' },
|
||||
// { display: 'Super user', code: 'superuser' },
|
||||
{ display: 'Suspend', code: 'suspend' },
|
||||
{ display: 'Block', code: 'block' }
|
||||
{ display: 'Block', code: 'block' },
|
||||
{ display: 'External Verification', code: 'external' }
|
||||
]
|
||||
|
||||
const hasRequirementError = (errors, touched, values) =>
|
||||
|
|
@ -545,7 +572,18 @@ const hasCustomRequirementError = (errors, touched, values) =>
|
|||
(!values.requirement?.customInfoRequestId ||
|
||||
!R.isNil(values.requirement?.customInfoRequestId))
|
||||
|
||||
const Requirement = ({ customInfoRequests, emailAuth }) => {
|
||||
const hasExternalRequirementError = (errors, touched, values) =>
|
||||
!!errors.requirement &&
|
||||
!!touched.requirement?.externalService &&
|
||||
!values.requirement?.externalService
|
||||
|
||||
const Requirement = ({
|
||||
config = {},
|
||||
triggers,
|
||||
emailAuth,
|
||||
complianceServices,
|
||||
customInfoRequests = []
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const {
|
||||
touched,
|
||||
|
|
@ -557,27 +595,55 @@ const Requirement = ({ customInfoRequests, emailAuth }) => {
|
|||
|
||||
const isSuspend = values?.requirement?.requirement === 'suspend'
|
||||
const isCustom = values?.requirement?.requirement === 'custom'
|
||||
const isExternal = values?.requirement?.requirement === 'external'
|
||||
|
||||
const customRequirementsInUse = R.reduce(
|
||||
(acc, value) => {
|
||||
if (value.requirement.requirement === 'custom')
|
||||
acc.push({
|
||||
triggerType: value.triggerType,
|
||||
id: value.requirement.customInfoRequestId
|
||||
})
|
||||
return acc
|
||||
},
|
||||
[],
|
||||
triggers
|
||||
)
|
||||
|
||||
const availableCustomRequirements = R.filter(
|
||||
it =>
|
||||
!R.includes(
|
||||
{ triggerType: config.triggerType, id: it.id },
|
||||
customRequirementsInUse
|
||||
),
|
||||
customInfoRequests
|
||||
)
|
||||
|
||||
const makeCustomReqOptions = () =>
|
||||
customInfoRequests.map(it => ({
|
||||
availableCustomRequirements.map(it => ({
|
||||
value: it.id,
|
||||
display: it.customRequest.name
|
||||
}))
|
||||
|
||||
const enableCustomRequirement = customInfoRequests?.length > 0
|
||||
const enableCustomRequirement = !R.isEmpty(availableCustomRequirements)
|
||||
|
||||
const customInfoOption = {
|
||||
display: 'Custom information requirement',
|
||||
code: 'custom'
|
||||
}
|
||||
|
||||
const itemToRemove = emailAuth ? 'sms' : 'email'
|
||||
const reqOptions = requirementOptions.filter(it => it.code !== itemToRemove)
|
||||
const options = enableCustomRequirement
|
||||
? [...reqOptions, customInfoOption]
|
||||
: [...reqOptions]
|
||||
const options = R.clone(reqOptions)
|
||||
|
||||
enableCustomRequirement && options.push(customInfoOption)
|
||||
|
||||
const titleClass = {
|
||||
[classes.error]:
|
||||
(!!errors.requirement && !isSuspend && !isCustom) ||
|
||||
(isSuspend && hasRequirementError(errors, touched, values)) ||
|
||||
(isCustom && hasCustomRequirementError(errors, touched, values))
|
||||
(isCustom && hasCustomRequirementError(errors, touched, values)) ||
|
||||
(isExternal && hasExternalRequirementError(errors, touched, values))
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -620,22 +686,50 @@ const Requirement = ({ customInfoRequests, emailAuth }) => {
|
|||
/>
|
||||
</div>
|
||||
)}
|
||||
{isExternal && (
|
||||
<div className={classes.externalFields}>
|
||||
<Field
|
||||
className={classes.dropdownField}
|
||||
component={Dropdown}
|
||||
label="Service"
|
||||
name="requirement.externalService"
|
||||
options={complianceServices.map(it => ({
|
||||
value: it.code,
|
||||
display: it.display
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const requirements = (customInfoRequests, emailAuth) => ({
|
||||
const requirements = (
|
||||
config,
|
||||
triggers,
|
||||
customInfoRequests,
|
||||
complianceServices,
|
||||
emailAuth
|
||||
) => ({
|
||||
schema: requirementSchema,
|
||||
options: requirementOptions,
|
||||
Component: Requirement,
|
||||
props: { customInfoRequests, emailAuth },
|
||||
props: {
|
||||
config,
|
||||
triggers,
|
||||
customInfoRequests,
|
||||
emailAuth,
|
||||
complianceServices
|
||||
},
|
||||
hasRequirementError: hasRequirementError,
|
||||
hasCustomRequirementError: hasCustomRequirementError,
|
||||
hasExternalRequirementError: hasExternalRequirementError,
|
||||
initialValues: {
|
||||
requirement: {
|
||||
requirement: '',
|
||||
suspensionDays: '',
|
||||
customInfoRequestId: ''
|
||||
customInfoRequestId: '',
|
||||
externalService: ''
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -665,7 +759,7 @@ const customReqIdMatches = customReqId => it => {
|
|||
return it.id === customReqId
|
||||
}
|
||||
|
||||
const RequirementInput = ({ customInfoRequests }) => {
|
||||
const RequirementInput = ({ customInfoRequests = [] }) => {
|
||||
const { values } = useFormikContext()
|
||||
const classes = useStyles()
|
||||
|
||||
|
|
@ -700,7 +794,8 @@ const RequirementView = ({
|
|||
requirement,
|
||||
suspensionDays,
|
||||
customInfoRequestId,
|
||||
customInfoRequests
|
||||
externalService,
|
||||
customInfoRequests = []
|
||||
}) => {
|
||||
const classes = useStyles()
|
||||
const display =
|
||||
|
|
@ -708,6 +803,8 @@ const RequirementView = ({
|
|||
? R.path(['customRequest', 'name'])(
|
||||
R.find(customReqIdMatches(customInfoRequestId))(customInfoRequests)
|
||||
) ?? ''
|
||||
: requirement === 'external'
|
||||
? `External Verification (${onlyFirstToUpper(externalService)})`
|
||||
: getView(requirementOptions, 'display')(requirement)
|
||||
const isSuspend = requirement === 'suspend'
|
||||
return (
|
||||
|
|
@ -840,7 +937,7 @@ const getElements = (currency, classes, customInfoRequests) => [
|
|||
{
|
||||
name: 'requirement',
|
||||
size: 'sm',
|
||||
width: 230,
|
||||
width: 260,
|
||||
bypassField: true,
|
||||
input: () => <RequirementInput customInfoRequests={customInfoRequests} />,
|
||||
view: it => (
|
||||
|
|
@ -850,7 +947,7 @@ const getElements = (currency, classes, customInfoRequests) => [
|
|||
{
|
||||
name: 'threshold',
|
||||
size: 'sm',
|
||||
width: 284,
|
||||
width: 254,
|
||||
textAlign: 'right',
|
||||
input: () => <ThresholdInput currency={currency} />,
|
||||
view: (it, config) => <ThresholdView config={config} currency={currency} />
|
||||
|
|
@ -877,7 +974,7 @@ const sortBy = [
|
|||
)
|
||||
]
|
||||
|
||||
const fromServer = (triggers, customInfoRequests) => {
|
||||
const fromServer = triggers => {
|
||||
return R.map(
|
||||
({
|
||||
requirement,
|
||||
|
|
@ -885,12 +982,14 @@ const fromServer = (triggers, customInfoRequests) => {
|
|||
threshold,
|
||||
thresholdDays,
|
||||
customInfoRequestId,
|
||||
externalService,
|
||||
...rest
|
||||
}) => ({
|
||||
requirement: {
|
||||
requirement,
|
||||
suspensionDays,
|
||||
customInfoRequestId
|
||||
customInfoRequestId,
|
||||
externalService
|
||||
},
|
||||
threshold: {
|
||||
threshold,
|
||||
|
|
@ -908,6 +1007,7 @@ const toServer = triggers =>
|
|||
threshold: threshold.threshold,
|
||||
thresholdDays: threshold.thresholdDays,
|
||||
customInfoRequestId: requirement.customInfoRequestId,
|
||||
externalService: requirement.externalService,
|
||||
...rest
|
||||
}))(triggers)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue