feat: error handling for the tables and wizards

This commit is contained in:
Taranto 2020-10-30 17:51:57 +00:00 committed by Josh Harvey
parent 7d5d963685
commit 96b8e3d9a2
10 changed files with 55 additions and 44 deletions

View file

@ -51,7 +51,6 @@ function checkHasLightning (settings) {
function poll (req, res, next) {
const machineVersion = req.query.version
// TODO new-admin: pass this field from the machines
const machineModel = req.query.model
const deviceId = req.deviceId
const deviceTime = req.deviceTime

View file

@ -13,7 +13,7 @@ const NamespacedTable = ({
...props
}) => {
const innerSave = (...[, it]) => {
save(toNamespace(it.id)(R.omit(['id2'], it)))
return save(toNamespace(it.id)(R.omit(['id2'], it)))
}
const innerData = R.map(it => ({

View file

@ -34,10 +34,15 @@ const ActionCol = ({ disabled, editing }) => {
onToggle,
toggleWidth,
forceAdd,
clearError,
actionColSize
} = useContext(TableCtx)
const disableEdit = disabled || (disableRowEdit && disableRowEdit(values))
const cancel = () => {
clearError()
resetForm()
}
return (
<>
@ -51,7 +56,7 @@ const ActionCol = ({ disabled, editing }) => {
Save
</Link>
{!forceAdd && (
<Link color="secondary" onClick={resetForm}>
<Link color="secondary" onClick={cancel}>
Cancel
</Link>
)}
@ -170,6 +175,7 @@ const ERow = ({ editing, disabled, lastOfGroup }) => {
elements,
enableEdit,
enableDelete,
error,
enableToggle,
rowSize,
stripeWhen
@ -199,13 +205,18 @@ const ERow = ({ editing, disabled, lastOfGroup }) => {
}
const touchedErrors = R.pick(R.keys(touched), errors)
const hasTouchedErrors = touchedErrors && R.keys(touchedErrors).length > 0
const hasErrors = hasTouchedErrors || !!error
const errorMessage =
error || (touchedErrors && R.values(touchedErrors).join(', '))
return (
<Tr
className={classnames(classNames)}
size={rowSize}
error={touchedErrors && R.keys(touchedErrors).length > 0}
errorMessage={touchedErrors && R.values(touchedErrors).join(', ')}>
error={editing && hasErrors}
errorMessage={errorMessage}>
{innerElements.map((it, idx) => {
return (
<ECol

View file

@ -32,6 +32,7 @@ const ETable = ({
elements = [],
data = [],
save,
error: externalError,
rowSize = 'md',
validationSchema,
enableCreate,
@ -58,8 +59,14 @@ const ETable = ({
const [editingId, setEditingId] = useState(null)
const [adding, setAdding] = useState(false)
const [saving, setSaving] = useState(false)
const [error, setError] = useState(null)
useEffect(() => setError(externalError), [externalError])
useEffect(() => {
setError(null)
setAdding(forceAdd)
}, [forceAdd])
useEffect(() => setAdding(forceAdd), [forceAdd])
const innerSave = async value => {
if (saving) return
@ -70,9 +77,9 @@ const ETable = ({
const list = index !== -1 ? R.update(index, it, data) : R.prepend(it, data)
if (!R.equals(data[index], it)) {
// no response means the save failed
const response = await save({ [name]: list }, it)
if (!response) {
try {
await save({ [name]: list }, it)
} catch (err) {
setSaving(false)
return
}
@ -98,11 +105,13 @@ const ETable = ({
const onEdit = it => {
if (shouldOverrideEdit && shouldOverrideEdit(it)) return editOverride(it)
setEditingId(it)
setError(null)
setEditing && setEditing(it, true)
}
const addField = () => {
setAdding(true)
setError(null)
setEditing && setEditing(true, true)
}
@ -129,6 +138,8 @@ const ETable = ({
elements,
enableEdit,
onEdit,
clearError: () => setError(null),
error: error,
disableRowEdit,
editWidth,
enableDelete,

View file

@ -48,18 +48,15 @@ const GET_INFO = gql`
const CashOut = ({ name: SCREEN_KEY }) => {
const classes = useStyles()
const [wizard, setWizard] = useState(false)
const [error, setError] = useState(false)
const { data } = useQuery(GET_INFO)
const [saveConfig] = useMutation(SAVE_CONFIG, {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
onError: () => setError(true),
refetchQueries: () => ['getData']
})
const save = (rawConfig, accounts) => {
const config = toNamespace(SCREEN_KEY)(rawConfig)
setError(false)
return saveConfig({ variables: { config, accounts } })
}
@ -76,7 +73,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
return (
<>
<TitleSection title="Cash-out" error={error}>
<TitleSection title="Cash-out">
<div className={classes.fudgeFactor}>
<P>Transaction fudge factor</P>
<Switch
@ -102,7 +99,6 @@ const CashOut = ({ name: SCREEN_KEY }) => {
</div>
</TitleSection>
<EditableTable
name="test"
namespaces={R.map(R.path(['deviceId']))(machines)}
data={config}
stripeWhen={it => !DenominationsSchema.isValidSync(it)}
@ -112,6 +108,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
toggleWidth={109}
onToggle={onToggle}
save={save}
error={error?.message}
validationSchema={DenominationsSchema}
disableRowEdit={R.compose(R.not, R.path(['active']))}
elements={getElements(machines, locale)}
@ -121,7 +118,7 @@ const CashOut = ({ name: SCREEN_KEY }) => {
machine={R.find(R.propEq('deviceId', wizard))(machines)}
onClose={() => setWizard(false)}
save={save}
error={error}
error={error?.message}
locale={locale}
/>
)}

View file

@ -41,7 +41,7 @@ const Commissions = ({ name: SCREEN_KEY }) => {
const [isEditingDefault, setEditingDefault] = useState(false)
const [isEditingOverrides, setEditingOverrides] = useState(false)
const { data } = useQuery(GET_DATA)
const [saveConfig] = useMutation(SAVE_CONFIG, {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
refetchQueries: () => ['getData']
})
@ -76,6 +76,7 @@ const Commissions = ({ name: SCREEN_KEY }) => {
<TitleSection title="Commissions" />
<Section>
<EditableTable
error={error?.message}
title="Default setup"
rowSize="lg"
titleLg
@ -92,6 +93,7 @@ const Commissions = ({ name: SCREEN_KEY }) => {
</Section>
<Section>
<EditableTable
error={error?.message}
title="Overrides"
titleLg
name="overrides"

View file

@ -102,13 +102,11 @@ const Locales = ({ name: SCREEN_KEY }) => {
const [cancelCryptoConfiguration, setCancelCryptoConfiguration] = useState(
null
)
const [error, setError] = useState(false)
const [isEditingDefault, setEditingDefault] = useState(false)
const [isEditingOverrides, setEditingOverrides] = useState(false)
const { data } = useQuery(GET_DATA)
const [saveConfig] = useMutation(SAVE_CONFIG, {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
onError: () => setError(true),
refetchQueries: () => ['getData']
})
@ -130,14 +128,14 @@ const Locales = ({ name: SCREEN_KEY }) => {
config.fiatCurrency &&
newConfig.locale_fiatCurrency !== config.fiatCurrency
)
setDataToSave(newConfig)
else save(newConfig)
return setDataToSave(newConfig)
return save(newConfig)
}
const save = config => {
setDataToSave(null)
setError(false)
saveConfig({ variables: { config } })
return saveConfig({ variables: { config } })
}
const saveOverrides = it => {
@ -169,6 +167,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
<Section>
<EditableTable
title="Default settings"
error={error?.message}
titleLg
name="locale"
enableEdit
@ -183,6 +182,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
</Section>
<Section>
<EditableTable
error={error?.message}
title="Overrides"
titleLg
name="overrides"
@ -213,7 +213,7 @@ const Locales = ({ name: SCREEN_KEY }) => {
save(toNamespace(namespaces.WALLETS)(rawConfig))
setCancelCryptoConfiguration(null)
}}
error={error}
error={error?.message}
cryptoCurrencies={cryptoCurrencies}
userAccounts={data?.config?.accounts}
accounts={accounts}

View file

@ -67,13 +67,8 @@ const CashCassettes = () => {
const { data } = useQuery(GET_MACHINES_AND_CONFIG)
const [resetCashOut] = useMutation(RESET_CASHOUT_BILLS, {
refetchQueries: () => ['getData'],
onError: ({ graphQLErrors, message }) => {
const errorMessage = graphQLErrors[0] ? graphQLErrors[0].message : message
// TODO new-admin : this should not be final
alert(JSON.stringify(errorMessage))
}
const [resetCashOut, { error }] = useMutation(RESET_CASHOUT_BILLS, {
refetchQueries: () => ['getData']
})
const cashout = data?.config && fromNamespace('cashOut')(data.config)
@ -145,6 +140,7 @@ const CashCassettes = () => {
<TitleSection title="Cash Cassettes" />
<EditableTable
error={error?.message}
name="cashboxes"
enableEdit
stripeWhen={isCashOutDisabled}

View file

@ -34,7 +34,6 @@ const GET_INFO = gql`
const Triggers = () => {
const classes = useStyles()
const [wizard, setWizard] = useState(false)
const [error, setError] = useState(false)
const { data, loading } = useQuery(GET_INFO)
const triggers = fromServer(data?.config?.triggers ?? [])
@ -43,9 +42,8 @@ const Triggers = () => {
data?.config && fromNamespace('compliance')(data.config)
const rejectAddressReuse = complianceConfig?.rejectAddressReuse ?? false
const [saveConfig] = useMutation(SAVE_CONFIG, {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
onError: () => setError(true),
refetchQueries: () => ['getData']
})
@ -53,7 +51,6 @@ const Triggers = () => {
const toSave = R.concat([{ id: v4(), direction: 'both', ...rawConfig }])(
triggers
)
setError(false)
return saveConfig({ variables: { config: { triggers: toServer(toSave) } } })
}
@ -63,7 +60,6 @@ const Triggers = () => {
}
const save = config => {
setError(false)
return saveConfig({
variables: { config: { triggers: toServer(config.triggers) } }
})
@ -121,6 +117,7 @@ const Triggers = () => {
sortBy={sortBy}
groupBy="triggerType"
enableDelete
error={error?.message}
save={save}
validationSchema={Schema}
elements={getElements(currency, classes)}
@ -128,7 +125,7 @@ const Triggers = () => {
{wizard && (
<Wizard
currency={currency}
error={error}
error={error?.message}
save={add}
onClose={() => setWizard(null)}
/>

View file

@ -49,12 +49,10 @@ const Wallet = ({ name: SCREEN_KEY }) => {
null
)
const [wizard, setWizard] = useState(false)
const [error, setError] = useState(false)
const { data } = useQuery(GET_INFO)
const [saveConfig] = useMutation(SAVE_CONFIG, {
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
onCompleted: () => setWizard(false),
onError: () => setError(true),
refetchQueries: () => ['getData']
})
@ -65,7 +63,6 @@ const Wallet = ({ name: SCREEN_KEY }) => {
const save = (rawConfig, accounts) => {
const config = toNamespace(SCREEN_KEY)(rawConfig)
setError(false)
return saveConfig({ variables: { config, accounts } })
}
@ -90,11 +87,12 @@ const Wallet = ({ name: SCREEN_KEY }) => {
return (
<>
<TitleSection title="Wallet Settings" error={error} />
<TitleSection title="Wallet Settings" />
<EditableTable
name="test"
namespaces={R.map(R.path(['code']))(cryptoCurrencies)}
data={config}
error={error?.message}
stripeWhen={it => !WalletSchema.isValidSync(it)}
enableEdit
shouldOverrideEdit={shouldOverrideEdit}
@ -113,7 +111,7 @@ const Wallet = ({ name: SCREEN_KEY }) => {
coin={R.find(R.propEq('code', wizard))(cryptoCurrencies)}
onClose={() => setWizard(false)}
save={save}
error={error}
error={error?.message}
cryptoCurrencies={cryptoCurrencies}
userAccounts={data?.config?.accounts}
accounts={accounts}