Skip to content

Commit

Permalink
feat: new error dialog design (Uniswap#511)
Browse files Browse the repository at this point in the history
* feat: new error view

* fix: expandos for settings

* fix: merge and delete file

* fix: rename column

* fix: use global x icon
  • Loading branch information
just-toby authored Mar 2, 2023
1 parent 5d8b93c commit 241b21c
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 127 deletions.
40 changes: 20 additions & 20 deletions src/components/Error/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { DEFAULT_ERROR_ACTION, DEFAULT_ERROR_HEADER, WidgetError } from 'errors'
import { t } from '@lingui/macro'
import { DEFAULT_ERROR_HEADER, WidgetError } from 'errors'
import { Component, ErrorInfo, PropsWithChildren, useCallback, useState } from 'react'

import Dialog from '../Dialog'
import ErrorDialog from './ErrorDialog'
import ErrorView from './ErrorView'

export type OnError = (error: Error, info?: ErrorInfo) => void

Expand Down Expand Up @@ -53,30 +53,30 @@ export default class ErrorBoundary extends Component<PropsWithChildren<ErrorBoun
this.props.onError?.(error, errorInfo)
}

renderErrorDialog(error: Error) {
renderErrorView(error: Error) {
const header = error instanceof WidgetError ? error.header : DEFAULT_ERROR_HEADER
const action = error instanceof WidgetError ? error.action : DEFAULT_ERROR_ACTION
return (
<Dialog color="dialog" forceContain>
<ErrorDialog
message={header}
error={error}
action={action}
onClick={
error instanceof WidgetError && error.dismissable
? () => {
this.setState({ error: undefined })
}
: () => window.location.reload()
}
/>
</Dialog>
<ErrorView
message={header}
error={error}
action={t`Get support`}
onDismiss={
error instanceof WidgetError && error.dismissable
? () => {
this.setState({ error: undefined })
}
: () => window.location.reload()
}
onClick={() => {
window.open('https://support.uniswap.org/', '_blank', 'noopener,noreferrer')
}}
/>
)
}

render() {
if (this.state.error) {
return this.renderErrorDialog(this.state.error)
return this.renderErrorView(this.state.error)
}
return this.props.children
}
Expand Down
105 changes: 0 additions & 105 deletions src/components/Error/ErrorDialog.tsx

This file was deleted.

86 changes: 86 additions & 0 deletions src/components/Error/ErrorView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Trans } from '@lingui/macro'
import ActionButton from 'components/ActionButton'
import Column from 'components/Column'
import Expando from 'components/Expando'
import Row from 'components/Row'
import { AlertTriangle, Icon, LargeIcon, StyledXButton } from 'icons'
import { ReactNode, useState } from 'react'
import styled from 'styled-components/macro'
import { Color, ThemedText } from 'theme'

const HeaderIcon = styled(LargeIcon)`
flex-grow: 1;
margin: 2em 0;
`

interface StatusHeaderProps {
icon: Icon
iconColor?: Color
iconSize?: number
children: ReactNode
}

export function StatusHeader({ icon: Icon, iconColor, iconSize = 2.5, children }: StatusHeaderProps) {
return (
<>
<Column flex style={{ flexGrow: 1 }}>
<HeaderIcon icon={Icon} color={iconColor} size={iconSize} />
<Column gap={0.75} flex style={{ textAlign: 'center' }}>
{children}
</Column>
</Column>
</>
)
}

const ExpandoContent = styled(ThemedText.Code)`
margin: 0.5em;
`

const ErrorDialogWrapper = styled(Column)`
background-color: ${({ theme }) => theme.container};
`

interface ErrorDialogProps {
header?: ReactNode
message: ReactNode
error?: Error
action: ReactNode
onClick: () => void
onDismiss: () => void
}

export default function ErrorDialog({ header, message, error, action, onClick, onDismiss }: ErrorDialogProps) {
const [open, setOpen] = useState(false)

return (
<ErrorDialogWrapper flex padding="1em 0.5em 0.25em" gap={0.5} align="stretch">
<Row flex flow="row-reverse">
<LargeIcon icon={StyledXButton} onClick={onDismiss} />
</Row>
<StatusHeader icon={AlertTriangle} iconColor="warning" iconSize={2.5}>
<Column gap={0.75}>
<ThemedText.H4>{header || <Trans>Something went wrong</Trans>}</ThemedText.H4>
<ThemedText.Body1 color="secondary">{message}</ThemedText.Body1>
</Column>
</StatusHeader>
{error ? (
<Expando
title={open ? <Trans>Show less</Trans> : <Trans>Show more</Trans>}
open={open}
onExpand={() => setOpen((open) => !open)}
maxHeight={11.5 /* em */}
>
<Column flex grow padded>
<ExpandoContent userSelect>{error.toString()}</ExpandoContent>
</Column>
</Expando>
) : (
<Column style={{ height: '7.5em' }} />
)}
<ActionButton color="accentSoft" onClick={onClick} narrow>
{action}
</ActionButton>
</ErrorDialogWrapper>
)
}
6 changes: 4 additions & 2 deletions src/components/Swap/Status/StatusDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Trans } from '@lingui/macro'
import ErrorDialog, { StatusHeader } from 'components/Error/ErrorDialog'
import ErrorView from 'components/Error/ErrorView'
import { StatusHeader } from 'components/Error/ErrorView'
import EtherscanLink from 'components/EtherscanLink'
import Row from 'components/Row'
import SwapSummary from 'components/Swap/Summary'
Expand Down Expand Up @@ -56,7 +57,7 @@ function TransactionStatus({ tx, onClose }: TransactionStatusProps) {

export default function TransactionStatusDialog({ tx, onClose }: TransactionStatusProps) {
return tx.receipt?.status === 0 ? (
<ErrorDialog
<ErrorView
header={<Trans>Your swap failed.</Trans>}
message={
<Trans>
Expand All @@ -67,6 +68,7 @@ export default function TransactionStatusDialog({ tx, onClose }: TransactionStat
}
action={<Trans>Dismiss</Trans>}
onClick={onClose}
onDismiss={onClose}
/>
) : (
<TransactionStatus tx={tx} onClose={onClose} />
Expand Down

0 comments on commit 241b21c

Please sign in to comment.