Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8461a0a0d5 | ||
|
|
80514a4adc | ||
|
|
1d39f81dfc | ||
|
|
e4f0cbc822 | ||
|
|
a9fd184647 | ||
|
|
e06ec8bb24 |
@@ -34,10 +34,6 @@ export const TOP_LEVEL_ROUTES = [
|
||||
name: 'Rewards',
|
||||
path: Routes.REWARDS,
|
||||
},
|
||||
{
|
||||
name: 'Restricted',
|
||||
path: Routes.RESTRICTED,
|
||||
},
|
||||
];
|
||||
|
||||
export const TOKEN_DROPDOWN_ROUTES = [
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
AssetDetailsDialog,
|
||||
useAssetDetailsDialogStore,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { useUpdateProposal } from '@vegaprotocol/proposals';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
export const LocalAssetDetailsDialog = () => {
|
||||
const { isOpen, id, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
const { data: proposal } = useUpdateProposal({
|
||||
id,
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_ASSET,
|
||||
});
|
||||
return (
|
||||
<AssetDetailsDialog
|
||||
assetId={id}
|
||||
trigger={trigger || null}
|
||||
open={isOpen}
|
||||
onChange={setOpen}
|
||||
proposalId={proposal?.id ?? undefined}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './asset-details-dialog';
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
AssetDetailsDialog,
|
||||
useAssetDetailsDialogStore,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { VegaConnectDialog, ViewAsDialog } from '@vegaprotocol/wallet';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import {
|
||||
@@ -10,9 +6,9 @@ import {
|
||||
} from '@vegaprotocol/web3';
|
||||
import { WelcomeDialog } from '../components/welcome-dialog';
|
||||
import { RiskMessage } from '../components/welcome-dialog';
|
||||
import { LocalAssetDetailsDialog as AssetDetailsDialog } from '../components/asset-details-dialog';
|
||||
|
||||
const DialogsContainer = () => {
|
||||
const { isOpen, id, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
return (
|
||||
<>
|
||||
<VegaConnectDialog
|
||||
@@ -20,12 +16,7 @@ const DialogsContainer = () => {
|
||||
riskMessage={<RiskMessage />}
|
||||
/>
|
||||
<ViewAsDialog connector={Connectors.view} />
|
||||
<AssetDetailsDialog
|
||||
assetId={id}
|
||||
trigger={trigger || null}
|
||||
open={isOpen}
|
||||
onChange={setOpen}
|
||||
/>
|
||||
<AssetDetailsDialog />
|
||||
<WelcomeDialog />
|
||||
<Web3ConnectUncontrolledDialog />
|
||||
<WithdrawalApprovalDialogContainer />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ToastsContainer, useToasts } from '@vegaprotocol/ui-toolkit';
|
||||
import { useUpdateNetworkParametersToasts } from '@vegaprotocol/proposals';
|
||||
import { useProposalNotificationToasts } from '@vegaprotocol/proposals';
|
||||
import { useVegaTransactionToasts } from '@vegaprotocol/web3';
|
||||
import { useEthereumTransactionToasts } from '@vegaprotocol/web3';
|
||||
import { useEthereumWithdrawApprovalsToasts } from '@vegaprotocol/web3';
|
||||
@@ -7,7 +7,7 @@ import { useReadyToWithdrawalToasts } from '@vegaprotocol/withdraws';
|
||||
import { Links } from '../lib/links';
|
||||
|
||||
export const ToastsManager = () => {
|
||||
useUpdateNetworkParametersToasts();
|
||||
useProposalNotificationToasts();
|
||||
useVegaTransactionToasts();
|
||||
useEthereumTransactionToasts();
|
||||
useEthereumWithdrawApprovalsToasts();
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { create } from 'zustand';
|
||||
import { AssetDetailsTable } from './asset-details-table';
|
||||
import { AssetProposalNotification } from '@vegaprotocol/proposals';
|
||||
import { AssetProposalNotification } from './asset-proposal-notification';
|
||||
import { useAssetDataProvider } from './asset-data-provider';
|
||||
|
||||
export type AssetDetailsDialogStore = {
|
||||
@@ -47,6 +47,7 @@ export interface AssetDetailsDialogProps {
|
||||
open: boolean;
|
||||
onChange: (open: boolean) => void;
|
||||
asJson?: boolean;
|
||||
proposalId?: string;
|
||||
}
|
||||
|
||||
export const AssetDetailsDialog = ({
|
||||
@@ -55,6 +56,7 @@ export const AssetDetailsDialog = ({
|
||||
open,
|
||||
onChange,
|
||||
asJson = false,
|
||||
proposalId,
|
||||
}: AssetDetailsDialogProps) => {
|
||||
const { data: asset } = useAssetDataProvider(assetId);
|
||||
|
||||
@@ -62,7 +64,7 @@ export const AssetDetailsDialog = ({
|
||||
|
||||
const content = asset ? (
|
||||
<div className="my-2">
|
||||
<AssetProposalNotification assetId={asset.id} />
|
||||
<AssetProposalNotification proposalId={proposalId} />
|
||||
{asJson ? (
|
||||
<div className="pr-8">
|
||||
<SyntaxHighlighter size="smaller" data={asset} />
|
||||
|
||||
+4
-10
@@ -1,24 +1,18 @@
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { ExternalLink, Intent, Notification } from '@vegaprotocol/ui-toolkit';
|
||||
import { useUpdateProposal } from '../lib';
|
||||
|
||||
type AssetProposalNotificationProps = {
|
||||
assetId?: string;
|
||||
proposalId?: string;
|
||||
};
|
||||
export const AssetProposalNotification = ({
|
||||
assetId,
|
||||
proposalId,
|
||||
}: AssetProposalNotificationProps) => {
|
||||
const tokenLink = useLinks(DApp.Governance);
|
||||
const { data: proposal } = useUpdateProposal({
|
||||
id: assetId,
|
||||
proposalType: Schema.ProposalType.TYPE_UPDATE_ASSET,
|
||||
});
|
||||
|
||||
if (proposal) {
|
||||
if (proposalId) {
|
||||
const proposalLink = tokenLink(
|
||||
TOKEN_PROPOSAL.replace(':id', proposal.id || '')
|
||||
TOKEN_PROPOSAL.replace(':id', proposalId || '')
|
||||
);
|
||||
const message = (
|
||||
<>
|
||||
@@ -1,4 +1,3 @@
|
||||
export * from './asset-proposal-notification';
|
||||
export * from './market-proposal-notification';
|
||||
export * from './proposals-list';
|
||||
export * from './protocol-upgrade-countdown';
|
||||
|
||||
@@ -319,6 +319,7 @@ fragment NewAssetFields on NewAsset {
|
||||
decimals
|
||||
quantum
|
||||
source {
|
||||
__typename
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
@@ -488,3 +489,39 @@ subscription MarketViewLiveProposals {
|
||||
...MarketViewProposalFields
|
||||
}
|
||||
}
|
||||
|
||||
fragment NotificationProposalsFields on Proposal {
|
||||
id
|
||||
state
|
||||
terms {
|
||||
closingDatetime
|
||||
enactmentDatetime
|
||||
change {
|
||||
__typename
|
||||
... on UpdateMarketState {
|
||||
...UpdateMarketStateFields
|
||||
}
|
||||
... on NewMarket {
|
||||
...NewMarketSuccessorFields
|
||||
}
|
||||
... on UpdateMarket {
|
||||
...UpdateMarketFields
|
||||
}
|
||||
... on NewAsset {
|
||||
...NewAssetFields
|
||||
}
|
||||
... on UpdateAsset {
|
||||
...UpdateAssetFields
|
||||
}
|
||||
... on UpdateNetworkParameter {
|
||||
...UpdateNetworkParameterFields
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subscription NotificationProposals {
|
||||
proposals {
|
||||
...NotificationProposalsFields
|
||||
}
|
||||
}
|
||||
|
||||
+77
-4
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ export * from './use-proposal-event';
|
||||
export * from './use-vega-transaction';
|
||||
export * from './use-proposal-submit';
|
||||
export * from './use-update-proposal';
|
||||
export * from './use-update-network-paramaters-toasts';
|
||||
export * from './use-proposal-notification-toasts';
|
||||
export * from './use-successor-market-proposal-details';
|
||||
export * from './use-new-transfer-proposal-details';
|
||||
export * from './use-cancel-transfer-proposal-details';
|
||||
|
||||
+10
-10
@@ -5,21 +5,21 @@ import { ProposalState } from '@vegaprotocol/types';
|
||||
import type { ReactNode } from 'react';
|
||||
import {
|
||||
PROPOSAL_STATES_TO_TOAST,
|
||||
useUpdateNetworkParametersToasts,
|
||||
} from './use-update-network-paramaters-toasts';
|
||||
useProposalNotificationToasts,
|
||||
} from './use-proposal-notification-toasts';
|
||||
import type {
|
||||
UpdateNetworkParameterProposalFragment,
|
||||
OnUpdateNetworkParametersSubscription,
|
||||
} from './__generated__/Proposal';
|
||||
import { OnUpdateNetworkParametersDocument } from './__generated__/Proposal';
|
||||
import { useToasts } from '@vegaprotocol/ui-toolkit';
|
||||
import { waitFor, renderHook } from '@testing-library/react';
|
||||
import { NotificationProposalsDocument } from '../proposals-data-provider/__generated__/Proposals';
|
||||
|
||||
const render = (mocks?: MockedResponse[]) => {
|
||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
||||
<MockedProvider mocks={mocks}>{children}</MockedProvider>
|
||||
);
|
||||
return renderHook(() => useUpdateNetworkParametersToasts(), { wrapper });
|
||||
return renderHook(() => useProposalNotificationToasts(), { wrapper });
|
||||
};
|
||||
|
||||
const generateUpdateNetworkParametersProposal = (
|
||||
@@ -51,7 +51,7 @@ const clear = () => {
|
||||
useToasts.setState(INITIAL);
|
||||
};
|
||||
|
||||
describe('useUpdateNetworkParametersToasts', () => {
|
||||
describe('useProposalNotificationToasts', () => {
|
||||
beforeEach(clear);
|
||||
afterAll(clear);
|
||||
|
||||
@@ -61,7 +61,7 @@ describe('useUpdateNetworkParametersToasts', () => {
|
||||
const mockOpenProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
|
||||
{
|
||||
request: {
|
||||
query: OnUpdateNetworkParametersDocument,
|
||||
query: NotificationProposalsDocument,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
@@ -89,7 +89,7 @@ describe('useUpdateNetworkParametersToasts', () => {
|
||||
const mockFailedProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
|
||||
{
|
||||
request: {
|
||||
query: OnUpdateNetworkParametersDocument,
|
||||
query: NotificationProposalsDocument,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
@@ -117,7 +117,7 @@ describe('useUpdateNetworkParametersToasts', () => {
|
||||
const mockEmptyProposal: MockedResponse<OnUpdateNetworkParametersSubscription> =
|
||||
{
|
||||
request: {
|
||||
query: OnUpdateNetworkParametersDocument,
|
||||
query: NotificationProposalsDocument,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
@@ -142,7 +142,7 @@ describe('useUpdateNetworkParametersToasts', () => {
|
||||
{
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewMarket',
|
||||
__typename: 'NewSpotMarket',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -150,7 +150,7 @@ describe('useUpdateNetworkParametersToasts', () => {
|
||||
const mockWrongProposalType: MockedResponse<OnUpdateNetworkParametersSubscription> =
|
||||
{
|
||||
request: {
|
||||
query: OnUpdateNetworkParametersDocument,
|
||||
query: NotificationProposalsDocument,
|
||||
},
|
||||
result: {
|
||||
data: {
|
||||
@@ -0,0 +1,200 @@
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { useAssetsDataProvider } from '@vegaprotocol/assets';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { ProposalStateMapping, MarketUpdateType } from '@vegaprotocol/types';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import type { Toast } from '@vegaprotocol/ui-toolkit';
|
||||
import { ToastHeading } from '@vegaprotocol/ui-toolkit';
|
||||
import { useToasts } from '@vegaprotocol/ui-toolkit';
|
||||
import { ExternalLink, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import type { NotificationProposalsFieldsFragment } from '../proposals-data-provider';
|
||||
import { useNotificationProposalsSubscription } from '../proposals-data-provider';
|
||||
|
||||
export const PROPOSAL_STATES_TO_TOAST = [
|
||||
ProposalState.STATE_DECLINED,
|
||||
ProposalState.STATE_ENACTED,
|
||||
ProposalState.STATE_OPEN,
|
||||
ProposalState.STATE_PASSED,
|
||||
];
|
||||
|
||||
const PROPOSAL_TYPES_TO_TOAST = [
|
||||
'UpdateNetworkParameter',
|
||||
'NewAsset',
|
||||
'NewMarket',
|
||||
'UpdateAsset',
|
||||
'UpdateMarket',
|
||||
'UpdateMarketState',
|
||||
];
|
||||
|
||||
type Proposal = NotificationProposalsFieldsFragment;
|
||||
|
||||
const NotificationProposalToastContent = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: Proposal;
|
||||
}) => {
|
||||
const { data: assets } = useAssetsDataProvider();
|
||||
const tokenLink = useLinks(DApp.Governance);
|
||||
const change = proposal.terms.change;
|
||||
let pretitle = 'New';
|
||||
let content: ReactNode = null;
|
||||
switch (change.__typename) {
|
||||
case 'UpdateNetworkParameter':
|
||||
pretitle = t('Network change');
|
||||
content = (
|
||||
<p className="italic">
|
||||
'{t('Update ')}
|
||||
<span className="break-all">{change.networkParameter.key}</span>
|
||||
{t(' to ')}
|
||||
<span>{change.networkParameter.value}</span>'
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
case 'NewMarket':
|
||||
pretitle = t('New market');
|
||||
content = (
|
||||
<p>
|
||||
{t('New market ')}
|
||||
<span className="break-all">{change.instrument.name}</span>
|
||||
{change.successorConfiguration?.parentMarketId && (
|
||||
<span>
|
||||
{' '}
|
||||
{t('successor of %', [
|
||||
change.successorConfiguration.parentMarketId,
|
||||
])}
|
||||
</span>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
case 'UpdateMarket':
|
||||
pretitle = t('Update market');
|
||||
content = (
|
||||
<p>
|
||||
{t('Market ')}
|
||||
<span className="break-all">
|
||||
{change.updateMarketConfiguration.instrument.code}
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
case 'UpdateMarketState':
|
||||
if (
|
||||
change.updateType ===
|
||||
MarketUpdateType.MARKET_STATE_UPDATE_TYPE_TERMINATE
|
||||
) {
|
||||
pretitle = t('Market termination');
|
||||
} else if (
|
||||
change.updateType === MarketUpdateType.MARKET_STATE_UPDATE_TYPE_SUSPEND
|
||||
) {
|
||||
pretitle = t('Market suspension');
|
||||
} else {
|
||||
pretitle = t('Market resume');
|
||||
}
|
||||
content = (
|
||||
<p>
|
||||
{t('Market ')}
|
||||
<span className="break-all">
|
||||
{change.market.tradableInstrument.instrument.name}
|
||||
</span>
|
||||
{change.price && (
|
||||
<span> {t('Final price will be %s', [change.price])}</span>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
case 'NewAsset':
|
||||
pretitle = t('New asset');
|
||||
content = (
|
||||
<p>
|
||||
<span className="break-all">
|
||||
{change.name} ({change.symbol})
|
||||
</span>
|
||||
{', '}
|
||||
{t('type %s', [
|
||||
change.source.__typename === 'ERC20' ? 'ERC20' : 'Builtin asset',
|
||||
])}
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
case 'UpdateAsset':
|
||||
pretitle = t('Update asset');
|
||||
content = (
|
||||
<p>
|
||||
<span className="break-all">
|
||||
{assets?.find((asset) => asset.id === change.assetId)?.name ??
|
||||
change.assetId}
|
||||
</span>
|
||||
</p>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
const title = t('%s proposal %s', [
|
||||
pretitle,
|
||||
ProposalStateMapping[proposal.state].toLowerCase(),
|
||||
]);
|
||||
const enactment = Date.parse(proposal.terms.enactmentDatetime);
|
||||
return (
|
||||
<div>
|
||||
<ToastHeading>{title}</ToastHeading>
|
||||
{content}
|
||||
{!isNaN(enactment) && (
|
||||
<p>
|
||||
{t('Enactment date:')} {getDateTimeFormat().format(enactment)}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<ExternalLink
|
||||
href={tokenLink(TOKEN_PROPOSAL).replace(':id', proposal?.id || '')}
|
||||
>
|
||||
{t('View proposal details')}
|
||||
</ExternalLink>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const useProposalNotificationToasts = () => {
|
||||
const setToast = useToasts((store) => store.setToast);
|
||||
const remove = useToasts((store) => store.remove);
|
||||
const hasToast = useToasts((store) => store.hasToast);
|
||||
const fromProposal = useCallback(
|
||||
(proposal: Proposal): Toast => {
|
||||
const id = `proposal-notification-${proposal.id}`;
|
||||
return {
|
||||
id,
|
||||
intent: Intent.Warning,
|
||||
content: <NotificationProposalToastContent proposal={proposal} />,
|
||||
onClose: () => {
|
||||
remove(id);
|
||||
},
|
||||
};
|
||||
},
|
||||
[remove]
|
||||
);
|
||||
|
||||
const displayToast = (toast: Toast) => {
|
||||
if (!hasToast(toast.id)) {
|
||||
setToast(toast);
|
||||
}
|
||||
};
|
||||
|
||||
return useNotificationProposalsSubscription({
|
||||
onData: ({ data }) => {
|
||||
// note proposals is poorly named, it is actually a single proposal
|
||||
const proposal = data.data?.proposals;
|
||||
if (!proposal) return;
|
||||
if (!PROPOSAL_TYPES_TO_TOAST.includes(proposal.terms.change.__typename)) {
|
||||
return;
|
||||
}
|
||||
// if one of the following states show a toast
|
||||
if (PROPOSAL_STATES_TO_TOAST.includes(proposal.state)) {
|
||||
displayToast(fromProposal(proposal));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -1,96 +0,0 @@
|
||||
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import type { UpdateNetworkParameter } from '@vegaprotocol/types';
|
||||
import { ProposalStateMapping } from '@vegaprotocol/types';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import type { Toast } from '@vegaprotocol/ui-toolkit';
|
||||
import { ToastHeading } from '@vegaprotocol/ui-toolkit';
|
||||
import { useToasts } from '@vegaprotocol/ui-toolkit';
|
||||
import { ExternalLink, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { useCallback } from 'react';
|
||||
import type { UpdateNetworkParameterProposalFragment } from './__generated__/Proposal';
|
||||
import { useOnUpdateNetworkParametersSubscription } from './__generated__/Proposal';
|
||||
|
||||
export const PROPOSAL_STATES_TO_TOAST = [
|
||||
ProposalState.STATE_DECLINED,
|
||||
ProposalState.STATE_ENACTED,
|
||||
ProposalState.STATE_OPEN,
|
||||
ProposalState.STATE_PASSED,
|
||||
];
|
||||
const CLOSE_AFTER = 0;
|
||||
type Proposal = UpdateNetworkParameterProposalFragment;
|
||||
|
||||
const UpdateNetworkParameterToastContent = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: Proposal;
|
||||
}) => {
|
||||
const tokenLink = useLinks(DApp.Governance);
|
||||
const change = proposal.terms.change as UpdateNetworkParameter;
|
||||
const title = t('Network change proposal %s').replace(
|
||||
'%s',
|
||||
ProposalStateMapping[proposal.state].toLowerCase()
|
||||
);
|
||||
const enactment = Date.parse(proposal.terms.enactmentDatetime);
|
||||
return (
|
||||
<div>
|
||||
<ToastHeading>{title}</ToastHeading>
|
||||
<p className="italic">
|
||||
'{t('Update ')}
|
||||
<span className="break-all">{change.networkParameter.key}</span>
|
||||
{t(' to ')}
|
||||
<span>{change.networkParameter.value}</span>'
|
||||
</p>
|
||||
{!isNaN(enactment) && (
|
||||
<p>
|
||||
{t('Enactment date:')} {getDateTimeFormat().format(enactment)}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<ExternalLink
|
||||
href={tokenLink(TOKEN_PROPOSAL).replace(':id', proposal?.id || '')}
|
||||
>
|
||||
{t('View proposal details')}
|
||||
</ExternalLink>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const useUpdateNetworkParametersToasts = () => {
|
||||
const { setToast, remove } = useToasts((store) => ({
|
||||
setToast: store.setToast,
|
||||
remove: store.remove,
|
||||
}));
|
||||
|
||||
const fromProposal = useCallback(
|
||||
(proposal: Proposal): Toast => {
|
||||
const id = `update-network-param-proposal-${proposal.id}`;
|
||||
return {
|
||||
id: `update-network-param-proposal-${proposal.id}`,
|
||||
intent: Intent.Warning,
|
||||
content: <UpdateNetworkParameterToastContent proposal={proposal} />,
|
||||
onClose: () => {
|
||||
remove(id);
|
||||
},
|
||||
closeAfter: CLOSE_AFTER,
|
||||
};
|
||||
},
|
||||
[remove]
|
||||
);
|
||||
|
||||
return useOnUpdateNetworkParametersSubscription({
|
||||
onData: ({ data }) => {
|
||||
// note proposals is poorly named, it is actually a single proposal
|
||||
const proposal = data.data?.proposals;
|
||||
if (!proposal) return;
|
||||
if (proposal.terms.change.__typename !== 'UpdateNetworkParameter') return;
|
||||
|
||||
// if one of the following states show a toast
|
||||
if (PROPOSAL_STATES_TO_TOAST.includes(proposal.state)) {
|
||||
setToast(fromProposal(proposal));
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user