feat: error handling for the tables and wizards
This commit is contained in:
parent
7d5d963685
commit
96b8e3d9a2
10 changed files with 55 additions and 44 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 => ({
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue