vega-frontend-monorepo/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx
Matthew Russell 5eb06254de
feat (#896): large withdraws (#1180)
* feat: add deposits table to deposits tab on portfolio page

* feat: refactor use-withdraw hook to not invoke eth tx

* feat: rename hook for clarity

* feat: fix withdrawal creation test

* feat: update withdraw-manager and withrawals-table tests

* chore: fix lint

* feat: remove web3 input to avoid double dialog

* chore: use renderHook from testing-library/react

* chore: update to use non deprecated fields

* chore: remove usage of all bridge contract

* feat: correctly merge cache update in withdrawals table

* feat: changes to support token app withdrawals

* chore: add height to ag grid table wrapping element

* feat: add txhash col to withdraw table

* feat: provide better ui if withdrawal is not ready to be completed

* feat: use separate dialogs for txs

* feat: allow user to immediately complete withdrawal if delay not triggered

* feat: add withdraw store to tidy up state management

* chore: fix tests

* chore: convert callback to promises, fix tests, delete withdraw page

* chore: fix lint errors

* fix: withdrawals link in nav

* feat: style changes after design update

* fix: proposal form test

* chore: tidy error ui logic

* feat: review comments

* chore: lint

* feat: add better typing for tables

* chore: put withdrawals tab at the end

* chore: update i18n

* fix: dialog in positions manager due to rename

* chore: increase spacing in withdrawal form

* chore: update tests

* chore: lint

* chore: use new assetsConnection and update cy test

* fix: incorrect shape of withdrawal generate function

* feat: delete withdrawals page now that its shown on the portfolio page

* chore: update tests to check for withdrawals page

* chore: fix tests again

* fix: page title test
2022-09-05 18:30:13 -07:00

178 lines
4.7 KiB
TypeScript

import { useEnvironment } from '@vegaprotocol/environment';
import { formatLabel, t } from '@vegaprotocol/react-helpers';
import { Dialog, Icon, Intent, Loader } from '@vegaprotocol/ui-toolkit';
import type { ReactNode } from 'react';
import type { VegaTxState } from '../use-vega-transaction';
import { VegaTxStatus } from '../use-vega-transaction';
export interface VegaTransactionDialogProps {
isOpen: boolean;
onChange: (isOpen: boolean) => void;
transaction: VegaTxState;
children?: ReactNode;
intent?: Intent;
title?: string;
icon?: ReactNode;
}
export const VegaTransactionDialog = ({
isOpen,
onChange,
transaction,
children,
intent,
title,
icon,
}: VegaTransactionDialogProps) => {
const computedIntent = intent ? intent : getIntent(transaction);
const computedTitle = title ? title : getTitle(transaction);
const computedIcon = icon ? icon : getIcon(transaction);
// Each dialog can specify custom dialog content using data returned via
// the subscription that confirms the transaction. So if we get a success state
// and this custom content is provided, render it
const content =
transaction.status === VegaTxStatus.Complete && children ? (
children
) : (
<VegaDialog transaction={transaction} />
);
return (
<Dialog
open={isOpen}
onChange={onChange}
intent={computedIntent}
title={computedTitle}
icon={computedIcon}
size="small"
>
{content}
</Dialog>
);
};
interface VegaDialogProps {
transaction: VegaTxState;
}
/**
* Default dialog content
*/
export const VegaDialog = ({ transaction }: VegaDialogProps) => {
const { VEGA_EXPLORER_URL } = useEnvironment();
let content = null;
if (transaction.status === VegaTxStatus.Requested) {
content = (
<p data-testid={transaction.status}>
{t(
'Please open your wallet application and confirm or reject the transaction'
)}
</p>
);
}
if (transaction.status === VegaTxStatus.Error) {
content = (
<div data-testid={transaction.status}>
<p>{transaction.error && formatLabel(transaction.error)}</p>
{transaction.details && (
<p>{formatLabel(transaction.details.join(', '))}</p>
)}
</div>
);
}
if (transaction.status === VegaTxStatus.Pending) {
content = (
<div data-testid={transaction.status}>
<p className="break-all">
{t('Please wait for your transaction to be confirmed')} - &nbsp;
{transaction.txHash && (
<a
className="underline"
data-testid="tx-block-explorer"
href={`${VEGA_EXPLORER_URL}/txs/0x${transaction.txHash}`}
target="_blank"
rel="noreferrer"
>
{t('View in block explorer')}
</a>
)}
</p>
</div>
);
}
if (transaction.status === VegaTxStatus.Complete) {
content = (
<div data-testid={transaction.status}>
<p className="break-all">
{t('Your transaction has been confirmed')} - &nbsp;
{transaction.txHash && (
<a
className="underline"
data-testid="tx-block-explorer"
href={`${VEGA_EXPLORER_URL}/txs/0x${transaction.txHash}`}
target="_blank"
rel="noreferrer"
>
{t('View in block explorer')}
</a>
)}
</p>
</div>
);
}
return <div className="text-sm">{content}</div>;
};
const getIntent = (transaction: VegaTxState) => {
switch (transaction.status) {
case VegaTxStatus.Requested:
return Intent.Warning;
case VegaTxStatus.Pending:
return Intent.Warning;
case VegaTxStatus.Error:
return Intent.Danger;
case VegaTxStatus.Complete:
return Intent.Success;
default:
return Intent.None;
}
};
const getTitle = (transaction: VegaTxState) => {
switch (transaction.status) {
case VegaTxStatus.Requested:
return t('Confirm transaction in wallet');
case VegaTxStatus.Pending:
return t('Awaiting network confirmation');
case VegaTxStatus.Error:
return t('Transaction failed');
case VegaTxStatus.Complete:
return t('Transaction complete');
default:
return '';
}
};
const getIcon = (transaction: VegaTxState) => {
switch (transaction.status) {
case VegaTxStatus.Requested:
return <Icon name="hand-up" />;
case VegaTxStatus.Pending:
return (
<span className="mt-1">
<Loader size="small" />
</span>
);
case VegaTxStatus.Error:
return <Icon name="warning-sign" />;
case VegaTxStatus.Complete:
return <Icon name="tick" />;
default:
return '';
}
};