fix: flat schema on operator info pages

This commit is contained in:
Taranto 2020-04-22 17:07:19 +01:00
parent d65482958a
commit ec73f0b022
10 changed files with 106 additions and 107 deletions

View file

@ -51,7 +51,8 @@ const ETable = ({
const [editingId, setEditingId] = useState(null)
const [adding, setAdding] = useState(false)
const innerSave = async it => {
const innerSave = async value => {
const it = validationSchema.cast(value)
const index = R.findIndex(R.propEq('id', it.id))(data)
const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data)

View file

@ -42,7 +42,6 @@ const EditableNumber = ({
name={name}
component={TextInput}
textAlign="right"
type="text"
width={width}
/>
)}

View file

@ -36,7 +36,7 @@ const SingleFieldEditableNumber = ({
enableReinitialize
initialValues={{ [name]: (data && data[name]) ?? '' }}
validationSchema={schema}
onSubmit={it => save(section, it)}
onSubmit={it => save(section, schema.cast(it))}
onReset={() => {
setEditing(name, false)
}}>

View file

@ -42,7 +42,7 @@ const FiatBalance = ({ section }) => {
fiatBalanceCassette2: data?.fiatBalanceCassette2 ?? ''
}}
validationSchema={schema}
onSubmit={it => save(section, it)}
onSubmit={it => save(section, schema.cast(it))}
onReset={() => {
setEditing(NAME, false)
}}>

View file

@ -23,7 +23,7 @@ const FiatBalanceOverrides = ({ section }) => {
const overridenMachines = R.map(override => override.machine, setupValues)
const suggestionFilter = R.filter(
it => !R.contains(it.code, overridenMachines)
it => !R.contains(it.deviceId, overridenMachines)
)
const suggestions = suggestionFilter(machines)
@ -50,17 +50,21 @@ const FiatBalanceOverrides = ({ section }) => {
.required()
})
const viewMachine = it =>
R.compose(R.path(['name']), R.find(R.propEq('deviceId', it)))(machines)
const elements = [
{
name: MACHINE_KEY,
width: 238,
size: 'sm',
view: R.path(['name']),
view: viewMachine,
input: Autocomplete,
inputProps: {
options: it => R.concat(suggestions, findSuggestion(it)),
limit: null,
getOptionSelected: R.eqProps('display')
valueProp: 'deviceId',
getLabel: R.path(['name'])
}
},
{
@ -90,7 +94,7 @@ const FiatBalanceOverrides = ({ section }) => {
enableDelete
enableEdit
enableCreate
save={it => save(section, it)}
save={it => save(section, validationSchema.cast(it))}
initialValues={initialValues}
validationSchema={validationSchema}
forceDisable={isDisabled(NAME) || !machines}

View file

@ -1,6 +1,7 @@
import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core/styles'
import { gql } from 'apollo-boost'
import * as R from 'ramda'
import React, { useState, memo } from 'react'
import Popper from 'src/components/Popper'
@ -9,6 +10,7 @@ import { Button } from 'src/components/buttons'
import { Switch } from 'src/components/inputs'
import { H4, P, Label2 } from 'src/components/typography'
import { ReactComponent as HelpIcon } from 'src/styling/icons/action/help/zodiac.svg'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import { mainStyles } from './CoinATMRadar.styles'
@ -48,17 +50,25 @@ const CoinATMRadar = memo(() => {
// TODO: treat errors on useMutation and useQuery
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: configResponse =>
setCoinAtmRadarConfig(configResponse.saveConfig.coinAtmRadar)
setCoinAtmRadarConfig(
fromNamespace(namespaces.COIN_ATM_RADAR, configResponse.saveConfig)
)
})
useQuery(GET_CONFIG, {
onCompleted: configResponse => {
setCoinAtmRadarConfig(
configResponse?.config?.coinAtmRadar ?? initialValues
const response = fromNamespace(
namespaces.COIN_ATM_RADAR,
configResponse.config
)
const values = R.merge(initialValues, response)
setCoinAtmRadarConfig(values)
}
})
const save = it => saveConfig({ variables: { config: { coinAtmRadar: it } } })
const save = it =>
saveConfig({
variables: { config: toNamespace(namespaces.COIN_ATM_RADAR, it) }
})
const handleOpenHelpPopper = event => {
setHelpPopperAnchorEl(helpPopperAnchorEl ? null : event.currentTarget)

View file

@ -1,30 +1,37 @@
import React, { useState } from 'react'
import classnames from 'classnames'
import * as R from 'ramda'
import * as Yup from 'yup'
import { gql } from 'apollo-boost'
import { Form, Formik, Field as FormikField } from 'formik'
import { makeStyles } from '@material-ui/core'
import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core'
import { gql } from 'apollo-boost'
import classnames from 'classnames'
import { Form, Formik, Field as FormikField } from 'formik'
import * as R from 'ramda'
import React, { useState } from 'react'
import * as Yup from 'yup'
import { Info2, Info3, Label1 } from 'src/components/typography'
import TextInputFormik from 'src/components/inputs/formik/TextInput'
import RadioGroupFormik from 'src/components/inputs/formik/RadioGroup'
import {
PhoneNumberInputFormik,
maskValue,
mask
} from 'src/components/inputs/formik/PhoneNumberInput'
import { Link } from 'src/components/buttons'
import ErrorMessage from 'src/components/ErrorMessage'
import { Link } from 'src/components/buttons'
import RadioGroupFormik from 'src/components/inputs/formik/RadioGroup'
import TextInputFormik from 'src/components/inputs/formik/TextInput'
import { Info2, Info3, Label1, Label3 } from 'src/components/typography'
import { ReactComponent as EditIcon } from 'src/styling/icons/action/edit/enabled.svg'
import { ReactComponent as WarningIcon } from 'src/styling/icons/warning-icon/comet.svg'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import {
styles as globalStyles,
contactInfoStyles
} from './OperatorInfo.styles'
const validationSchema = Yup.object().shape({
infoCardEnabled: Yup.boolean().required(),
fullName: Yup.string().required(),
phoneNumber: Yup.string().required(),
email: Yup.string()
.email('Please enter a valid email address')
.required(),
website: Yup.string().required(),
companyNumber: Yup.string().required()
})
const fieldStyles = {
field: {
position: 'relative',
@ -38,12 +45,13 @@ const fieldStyles = {
'& > p:first-child': {
height: 16,
lineHeight: '16px',
paddingLeft: 3,
transform: 'scale(0.75)',
transformOrigin: 'left',
paddingLeft: 0,
margin: [[0, 0, 5, 0]]
},
'& > p:last-child': {
margin: 0,
paddingLeft: 4
margin: 0
}
}
}
@ -62,7 +70,7 @@ const Field = ({ editing, field, displayValue, ...props }) => {
<div className={classnames(classNames)}>
{!editing && (
<>
<Label1>{field.label}</Label1>
<Label3>{field.label}</Label3>
<Info3>{displayValue(field.value)}</Info3>
</>
)}
@ -93,9 +101,6 @@ const SAVE_CONFIG = gql`
}
`
const INFO_CARD_ENABLED = 'On'
const INFO_CARD_DISABLED = 'Off'
const styles = R.merge(globalStyles, contactInfoStyles)
const contactUseStyles = makeStyles(styles)
@ -106,8 +111,7 @@ const ContactInfo = () => {
const [error, setError] = useState(null)
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: data => {
const { operatorInfo } = data.saveConfig
setInfo(operatorInfo)
setInfo(fromNamespace(namespaces.CONTACT_INFO, data.saveConfig))
setEditing(false)
},
onError: e => setError(e)
@ -115,13 +119,14 @@ const ContactInfo = () => {
useQuery(GET_CONFIG, {
onCompleted: data => {
const { operatorInfo } = data.config
setInfo(operatorInfo ?? {})
setInfo(fromNamespace(namespaces.CONTACT_INFO, data.config))
}
})
const save = it => {
return saveConfig({ variables: { config: { operatorInfo: it } } })
return saveConfig({
variables: { config: toNamespace(namespaces.CONTACT_INFO, it) }
})
}
const classes = contactUseStyles()
@ -132,43 +137,37 @@ const ContactInfo = () => {
{
name: 'infoCardEnabled',
label: 'Info Card Enabled',
value: info.infoCardEnabled ?? INFO_CARD_DISABLED,
type: 'select',
value: String(info.infoCardEnabled),
component: RadioGroupFormik
},
{
name: 'fullName',
label: 'Full name',
value: info.fullName ?? '',
type: 'text',
component: TextInputFormik
},
{
name: 'phoneNumber',
label: 'Phone number',
value: maskValue(info.phoneNumber) ?? '',
type: 'text',
component: PhoneNumberInputFormik
value: info.phoneNumber ?? '',
component: TextInputFormik
},
{
name: 'email',
label: 'Email',
value: info.email ?? '',
type: 'text',
component: TextInputFormik
},
{
name: 'website',
label: 'Website',
value: info.website ?? '',
type: 'text',
component: TextInputFormik
},
{
name: 'companyNumber',
label: 'Company number',
value: info.companyNumber ?? '',
type: 'text',
component: TextInputFormik
}
]
@ -186,27 +185,7 @@ const ContactInfo = () => {
email: findValue('email'),
website: findValue('website'),
companyNumber: findValue('companyNumber')
},
validationSchema: Yup.object().shape({
fullName: Yup.string()
.max(100, 'Too long')
.required(),
phoneNumber: Yup.string()
.matches(mask, { excludeEmptyString: true })
.max(100, 'Too long')
.required(),
email: Yup.string()
.email('Please enter a valid email address')
.max(100, 'Too long')
.required(),
website: Yup.string()
.url('Please enter a valid url')
.max(100, 'Too long')
.required(),
companyNumber: Yup.string()
.max(30, 'Too long')
.required()
})
}
}
return (
@ -225,9 +204,9 @@ const ContactInfo = () => {
<Formik
enableReinitialize
initialValues={form.initialValues}
validationSchema={form.validationSchema}
onSubmit={values => save(values)}
onReset={(values, bag) => {
validationSchema={validationSchema}
onSubmit={values => save(validationSchema.cast(values))}
onReset={() => {
setEditing(false)
setError(null)
}}>
@ -236,10 +215,10 @@ const ContactInfo = () => {
<Field
field={findField('infoCardEnabled')}
editing={editing}
displayValue={displayTextValue}
displayValue={it => (it === 'true' ? 'On' : 'Off')}
options={[
{ label: 'On', value: INFO_CARD_ENABLED },
{ label: 'Off', value: INFO_CARD_DISABLED }
{ display: 'On', code: 'true' },
{ display: 'Off', code: 'false' }
]}
className={classes.radioButtons}
resetError={() => setError(null)}

View file

@ -1,27 +1,26 @@
import { makeStyles } from '@material-ui/core'
import * as R from 'ramda'
import Grid from '@material-ui/core/Grid'
import React, { useState } from 'react'
import Title from 'src/components/Title'
import Sidebar from 'src/components/layout/Sidebar'
import logsStyles from '../Logs.styles'
import TitleSection from 'src/components/layout/TitleSection'
import CoinAtmRadar from './CoinATMRadar'
import ContactInfo from './ContactInfo'
import ReceiptPrinting from './ReceiptPrinting'
import TermsConditions from './TermsConditions'
const localStyles = {
contentWrapper: {
width: '100%',
const styles = {
grid: {
flex: 1,
height: '100%'
},
content: {
marginLeft: 48,
paddingTop: 15
}
}
const styles = R.merge(logsStyles, localStyles)
const useStyles = makeStyles(styles)
const CONTACT_INFORMATION = 'Contact information'
@ -39,25 +38,21 @@ const OperatorInfo = () => {
return (
<>
<div className={classes.titleWrapper}>
<div className={classes.titleAndButtonsContainer}>
<Title>Operator information</Title>
</div>
</div>
<div className={classes.wrapper}>
<TitleSection title="Operator information"></TitleSection>
<Grid container className={classes.grid}>
<Sidebar
data={pages}
isSelected={isSelected}
displayName={it => it}
onClick={it => setSelected(it)}
/>
<div className={classes.contentWrapper}>
<div className={classes.content}>
{isSelected(CONTACT_INFORMATION) && <ContactInfo />}
{isSelected(RECEIPT) && <ReceiptPrinting />}
{isSelected(TERMS_CONDITIONS) && <TermsConditions />}
{isSelected(COIN_ATM_RADAR) && <CoinAtmRadar />}
</div>
</div>
</Grid>
</>
)
}

View file

@ -1,17 +1,18 @@
import React, { useState } from 'react'
import classnames from 'classnames'
import * as R from 'ramda'
import * as Yup from 'yup'
import { Form, Formik, Field } from 'formik'
import { gql } from 'apollo-boost'
import { makeStyles } from '@material-ui/core'
import { useQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles } from '@material-ui/core'
import { gql } from 'apollo-boost'
import classnames from 'classnames'
import { Form, Formik, Field } from 'formik'
import * as R from 'ramda'
import React, { useState } from 'react'
import * as Yup from 'yup'
import { Info2, Label2 } from 'src/components/typography'
import ErrorMessage from 'src/components/ErrorMessage'
import { Button } from 'src/components/buttons'
import { Switch } from 'src/components/inputs'
import TextInputFormik from 'src/components/inputs/formik/TextInput'
import { Button } from 'src/components/buttons'
import ErrorMessage from 'src/components/ErrorMessage'
import { Info2, Label2 } from 'src/components/typography'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import {
styles as globalStyles,
@ -40,7 +41,10 @@ const TermsConditions = () => {
const [error, setError] = useState(null)
const [saveConfig] = useMutation(SAVE_CONFIG, {
onCompleted: data => {
const { termsAndConditions } = data.saveConfig
const termsAndConditions = fromNamespace(
namespaces.TERMS_CONDITIONS,
data.saveConfig
)
setFormData(termsAndConditions)
setShowOnScreen(termsAndConditions.show)
setError(null)
@ -52,7 +56,10 @@ const TermsConditions = () => {
useQuery(GET_CONFIG, {
onCompleted: data => {
const { termsAndConditions } = data.config
const termsAndConditions = fromNamespace(
namespaces.TERMS_CONDITIONS,
data.config
)
setFormData(termsAndConditions ?? {})
setShowOnScreen(termsAndConditions?.show ?? false)
}
@ -61,7 +68,7 @@ const TermsConditions = () => {
const save = it => {
setError(null)
return saveConfig({
variables: { config: { termsAndConditions: it } }
variables: { config: toNamespace(namespaces.TERMS_CONDITIONS, it) }
})
}

View file

@ -7,7 +7,11 @@ const namespaces = {
NOTIFICATIONS: 'notifications',
SERVICES: 'services',
LOCALE: 'locale',
COMMISSIONS: 'commissions'
COMMISSIONS: 'commissions',
CONTACT_INFO: 'contactInfo',
RECEIPT: 'receipt',
COIN_ATM_RADAR: 'coinAtmRadar',
TERMS_CONDITIONS: 'termsConditions'
}
const mapKeys = R.curry((fn, obj) =>