vega-frontend-monorepo/libs/wallet/src/use-vega-transaction.tsx
Matthew Russell a5f9ed90e8
Fix/Order dialog state (#850)
* feat: remove dialog state handling from dialog and split out edit dialog

* feat: add complete state to use-vega-transaction, fix cancel dialog

* feat: add custom dialog content for order submission

* feat: handle custom title and custom intent

* feat: separate components, make order dialog wrapper more generic

* feat: remove dialog wrapper and add icon to dialog

* chore: remove other dialog wrappers and use icon and title props on main dialog

* chore: adjust default color of dialog text

* fix: tests for tx dialog and vega tx hook

* fix: order edit and cancel hook tests

* chore: add edit dialog to stories

* fix: e2e test for deal ticket

* feat: return dialog from hook

* refactor: add use-order-event hook to dedupe bus event logic

* refactor: add custom title and intent to order submit dialog

* chore: remove console logs

* fix: type error due to component being named idalog

* chore: add helper function for converting nanoseconds

* chore: remove capitalization text transform to dialog titles

* chore: remove unused import

* feat: handle titles and intents for cancel and edit

* chore: remove unused var
2022-07-26 14:35:30 +01:00

128 lines
3.0 KiB
TypeScript

import type { ReactNode } from 'react';
import { useCallback, useMemo, useState } from 'react';
import type { TransactionSubmission } from './wallet-types';
import { useVegaWallet } from './use-vega-wallet';
import type { SendTxError } from './context';
import { VegaTransactionDialog } from './vega-transaction-dialog';
import type { Intent } from '@vegaprotocol/ui-toolkit';
export interface DialogProps {
children?: JSX.Element;
intent?: Intent;
title?: string;
icon?: ReactNode;
}
export enum VegaTxStatus {
Default = 'Default',
Requested = 'Requested',
Pending = 'Pending',
Error = 'Error',
Complete = 'Complete',
}
export interface VegaTxState {
status: VegaTxStatus;
error: object | null;
txHash: string | null;
signature: string | null;
dialogOpen: boolean;
}
export const initialState = {
status: VegaTxStatus.Default,
error: null,
txHash: null,
signature: null,
dialogOpen: false,
};
export const useVegaTransaction = () => {
const { sendTx } = useVegaWallet();
const [transaction, _setTransaction] = useState<VegaTxState>(initialState);
const setTransaction = useCallback((update: Partial<VegaTxState>) => {
_setTransaction((curr) => ({
...curr,
...update,
}));
}, []);
const handleError = useCallback(
(error: SendTxError) => {
setTransaction({ error, status: VegaTxStatus.Error });
},
[setTransaction]
);
const reset = useCallback(() => {
setTransaction(initialState);
}, [setTransaction]);
const setComplete = useCallback(() => {
setTransaction({ status: VegaTxStatus.Complete });
}, [setTransaction]);
const send = useCallback(
async (tx: TransactionSubmission) => {
setTransaction({
error: null,
txHash: null,
signature: null,
status: VegaTxStatus.Requested,
dialogOpen: true,
});
const res = await sendTx(tx);
if (res === null) {
setTransaction({ status: VegaTxStatus.Default });
return null;
}
if ('errors' in res) {
handleError(res);
} else if ('error' in res) {
if (res.error === 'User rejected') {
reset();
} else {
handleError(res);
}
} else if (res.tx?.signature?.value && res.txHash) {
setTransaction({
status: VegaTxStatus.Pending,
txHash: res.txHash,
signature: res.tx.signature.value,
});
return {
signature: res.tx.signature?.value,
};
}
return null;
},
[sendTx, handleError, setTransaction, reset]
);
const TransactionDialog = useMemo(() => {
return (props: DialogProps) => (
<VegaTransactionDialog
{...props}
isOpen={transaction.dialogOpen}
onChange={(isOpen) => {
if (!isOpen) reset();
setTransaction({ dialogOpen: isOpen });
}}
transaction={transaction}
/>
);
}, [transaction, setTransaction, reset]);
return {
send,
transaction,
reset,
setComplete,
TransactionDialog,
};
};