chore(1987): persist ui behind dialog when staking (#1997)

* Chore/1987: Persist UI behind dialog when staking

* feat(1987): Placed staking form tx status notifications in separate component
This commit is contained in:
Sam Keen 2022-11-10 11:31:11 +00:00 committed by GitHub
parent 4fedd94243
commit 7f8185372d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 147 additions and 46 deletions

View File

@ -206,7 +206,7 @@
"noGovernanceTokens": "You need some VEGA tokens to participate in governance",
"youVoted": "You voted",
"changeVote": "Change vote",
"voteRequested": "Please confirm transaction in wallet",
"txRequested": "Confirm transaction in wallet",
"votePending": "Casting vote",
"voteError": "Something went wrong, and your vote was not seen by the network",
"back": "back",

View File

@ -10,7 +10,7 @@ interface VoteTransactionDialogProps {
const dialogTitle = (voteState: VoteState): string | undefined => {
switch (voteState) {
case VoteState.Requested:
return t('voteRequested');
return t('txRequested');
case VoteState.Pending:
return t('votePending');
default:

View File

@ -3,15 +3,22 @@ import { useTranslation } from 'react-i18next';
interface StakeFailureProps {
nodeName: string;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeFailure = ({ nodeName }: StakeFailureProps) => {
export const StakeFailure = ({
nodeName,
isDialogVisible,
toggleDialog,
}: StakeFailureProps) => {
const { t } = useTranslation();
return (
<Dialog
intent={Intent.Danger}
title={t('Something went wrong')}
open={true}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>
{t('stakeFailed', {

View File

@ -7,12 +7,16 @@ interface StakePendingProps {
action: StakeAction;
amount: string;
nodeName: string;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakePending = ({
action,
amount,
nodeName,
isDialogVisible,
toggleDialog,
}: StakePendingProps) => {
const { t } = useTranslation();
const titleArgs = { amount, node: nodeName };
@ -22,7 +26,12 @@ export const StakePending = ({
: t('stakeRemovePendingTitle', titleArgs);
return (
<Dialog icon={<Loader size="small" />} title={title} open={true}>
<Dialog
icon={<Loader size="small" />}
title={title}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>{t('timeForConfirmation')}</p>
</Dialog>
);

View File

@ -0,0 +1,25 @@
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import React from 'react';
interface StakeRequestedProps {
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeRequested = ({
isDialogVisible,
toggleDialog,
}: StakeRequestedProps) => {
const { t } = useTranslation();
return (
<Dialog
title={t('txRequested')}
intent={Intent.Warning}
open={isDialogVisible}
onChange={toggleDialog}
>
<p>{t('stakingConfirm')}</p>
</Dialog>
);
};

View File

@ -10,6 +10,8 @@ interface StakeSuccessProps {
amount: string;
nodeName: string;
removeType: RemoveType;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakeSuccess = ({
@ -17,6 +19,8 @@ export const StakeSuccess = ({
amount,
nodeName,
removeType,
isDialogVisible,
toggleDialog,
}: StakeSuccessProps) => {
const { t } = useTranslation();
const isAdd = action === Actions.Add;
@ -34,7 +38,8 @@ export const StakeSuccess = ({
icon={<Icon name="tick" />}
intent={Intent.Success}
title={title}
open={true}
open={isDialogVisible}
onChange={toggleDialog}
>
<div>
<p>{message}</p>

View File

@ -0,0 +1,67 @@
import { StakeFailure } from './stake-failure';
import { StakeRequested } from './stake-requested';
import { StakePending } from './stake-pending';
import { StakeSuccess } from './stake-success';
import { FormState } from './staking-form';
import type { RemoveType, StakeAction } from './staking-form';
interface StakeFormTxStatusesProps {
formState: FormState;
nodeName: string;
amount: string;
action: StakeAction;
removeType: RemoveType;
isDialogVisible: boolean;
toggleDialog: () => void;
}
export const StakingFormTxStatuses = ({
formState,
nodeName,
amount,
action,
removeType,
isDialogVisible,
toggleDialog,
}: StakeFormTxStatusesProps) => {
switch (formState) {
case FormState.Requested:
return (
<StakeRequested
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
case FormState.Pending:
return (
<StakePending
action={action}
amount={amount}
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
case FormState.Success:
return (
<StakeSuccess
action={action}
amount={amount}
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
removeType={removeType}
/>
);
case FormState.Failure:
return (
<StakeFailure
nodeName={nodeName}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
);
default:
return null;
}
};

View File

@ -1,6 +1,6 @@
import { gql, useApolloClient } from '@apollo/client';
import * as Sentry from '@sentry/react';
import React from 'react';
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
@ -12,14 +12,10 @@ import type {
PartyDelegations,
PartyDelegationsVariables,
} from './__generated__/PartyDelegations';
import { StakeFailure } from './stake-failure';
import { StakePending } from './stake-pending';
import { StakeSuccess } from './stake-success';
import { StakingFormTxStatuses } from './staking-form-tx-statuses';
import {
ButtonLink,
Dialog,
FormGroup,
Intent,
Radio,
RadioGroup,
} from '@vegaprotocol/ui-toolkit';
@ -54,7 +50,7 @@ export const PARTY_DELEGATIONS_QUERY = gql`
}
`;
enum FormState {
export enum FormState {
Default,
Requested,
Pending,
@ -93,6 +89,7 @@ export const StakingForm = ({
const { appState } = useAppState();
const { sendTx } = useVegaWallet();
const [formState, setFormState] = React.useState(FormState.Default);
const [isDialogVisible, setIsDialogVisible] = useState(false);
const { t } = useTranslation();
const [action, setAction] = React.useState<StakeAction>(
params.action as StakeAction
@ -129,6 +126,7 @@ export const StakingForm = ({
async function onSubmit() {
setFormState(FormState.Requested);
setIsDialogVisible(true);
const delegateInput: DelegateSubmissionBody = {
delegateSubmission: {
nodeId,
@ -196,43 +194,24 @@ export const StakingForm = ({
return () => clearInterval(interval);
}, [formState, client, pubKey, nodeId]);
if (formState === FormState.Failure) {
return <StakeFailure nodeName={nodeName} />;
} else if (formState === FormState.Requested) {
return (
<Dialog
title="Confirm transaction in wallet"
intent={Intent.Warning}
open={true}
>
<p>{t('stakingConfirm')}</p>
</Dialog>
);
} else if (formState === FormState.Pending) {
return <StakePending action={action} amount={amount} nodeName={nodeName} />;
} else if (formState === FormState.Success) {
return (
<StakeSuccess
action={action}
amount={amount}
nodeName={nodeName}
removeType={removeType}
/>
);
} else if (
availableStakeToAdd.isEqualTo(0) &&
availableStakeToRemove.isEqualTo(0)
) {
if (appState.lien.isGreaterThan(0)) {
return <span className="text-red">{t('stakeNodeWrongVegaKey')}</span>;
} else {
return <span className="text-red">{t('stakeNodeNone')}</span>;
}
}
const toggleDialog = useCallback(() => {
setIsDialogVisible(!isDialogVisible);
}, [isDialogVisible]);
return (
<>
<h2>{t('Manage your stake')}</h2>
{formState === FormState.Default &&
availableStakeToAdd.isEqualTo(0) &&
availableStakeToRemove.isEqualTo(0) && (
<div>
{appState.lien.isGreaterThan(0) ? (
<span className="text-red">{t('stakeNodeWrongVegaKey')}</span>
) : (
<span className="text-red">{t('stakeNodeNone')}</span>
)}
</div>
)}
<FormGroup
label={t('Select if you want to add or remove stake')}
labelFor="radio-stake-options"
@ -331,6 +310,15 @@ export const StakingForm = ({
)}
</>
)}
<StakingFormTxStatuses
formState={formState}
nodeName={nodeName}
amount={amount}
action={action}
removeType={removeType}
isDialogVisible={isDialogVisible}
toggleDialog={toggleDialog}
/>
</>
);
};