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:
parent
4fedd94243
commit
7f8185372d
@ -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",
|
||||
|
@ -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:
|
||||
|
@ -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', {
|
||||
|
@ -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>
|
||||
);
|
||||
|
25
apps/token/src/routes/staking/node/stake-requested.tsx
Normal file
25
apps/token/src/routes/staking/node/stake-requested.tsx
Normal 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>
|
||||
);
|
||||
};
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
@ -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}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user