market page: break down components to smaller chunks for better performance (#1726)
* chore: break down components to smaller chunks for better performance * chore: break down components to smaller chunks for better performance * chore: break down components to smaller chunks for better performance - fix failing tests * chore: break down components to smaller chunks for better performance - adjust token app cases * chore: break down components to smaller chunks for better performance - small fixes * chore: break down components to smaller chunks for better performance - small fixes * chore: break down components to smaller chunks for better performance - small fixes * chore: break down components to smaller chunks for better performance - small fixes * chore: break down components to smaller chunks for better performance - add nwe store for pageTitle * chore: break down components to smaller chunks for better performance - sm fix * chore: break down components to smaller chunks for better performance - sm fix * chore: break down components to smaller chunks for better performance - sm imprv * chore: break down components to smaller chunks for better performance - change prop names * chore: break down components to smaller chunks for better performance - fix some test * chore: break down components to smaller chunks for better performance - change cypress url * chore: break down components to smaller chunks for better perf - set back redundant changes * chore: resolve conflicts Co-authored-by: maciek <maciek@vegaprotocol.io>
This commit is contained in:
parent
ecb19f226b
commit
37a6217169
@ -40,11 +40,7 @@ function App() {
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWalletDialog.connect}
|
||||
setDialogOpen={vegaWalletDialog.setConnect}
|
||||
/>
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
|
@ -1,12 +1,16 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import Logo from './logo';
|
||||
import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
|
||||
import LocalContext from '../../context/local-context';
|
||||
|
||||
const Header = () => {
|
||||
const { updateVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
updateVegaWalletDialog: store.updateVegaWalletDialog,
|
||||
}));
|
||||
const {
|
||||
vegaWalletDialog: { setConnect, setManage },
|
||||
vegaWalletDialog: { setManage },
|
||||
theme,
|
||||
toggleTheme,
|
||||
} = useContext(LocalContext);
|
||||
@ -18,7 +22,7 @@ const Header = () => {
|
||||
<Logo />
|
||||
<div className="flex items-center gap-2 ml-auto relative z-10">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={setConnect}
|
||||
setConnectDialog={updateVegaWalletDialog}
|
||||
setManageDialog={setManage}
|
||||
/>
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import * as React from 'react';
|
||||
import { useContext } from 'react';
|
||||
import LocalContext from '../../context/local-context';
|
||||
|
||||
const ConnectWallet = () => {
|
||||
const {
|
||||
vegaWalletDialog: { setConnect },
|
||||
} = useContext(LocalContext);
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
return (
|
||||
<section
|
||||
className="p-8 bg-white-normal dark:bg-offBlack"
|
||||
@ -17,7 +16,7 @@ const ConnectWallet = () => {
|
||||
{t('Please connect your Vega wallet to make a trade')}
|
||||
</h3>
|
||||
<div className="mb-4">
|
||||
<Button variant="primary" onClick={() => setConnect(true)} size="lg">
|
||||
<Button variant="primary" onClick={openVegaWalletDialog} size="lg">
|
||||
{t('Connect Vega wallet')}
|
||||
</Button>
|
||||
</div>
|
||||
|
@ -1,9 +1,7 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
export interface VegaWalletDialogState {
|
||||
connect: boolean;
|
||||
manage: boolean;
|
||||
setConnect: (isOpen: boolean) => void;
|
||||
setManage: (isOpen: boolean) => void;
|
||||
}
|
||||
|
||||
|
@ -7,12 +7,9 @@ describe('local values hook', () => {
|
||||
const { result } = renderHook(() => useLocalValues('light', setTheme));
|
||||
expect(result.current.vegaWalletDialog).toBeDefined();
|
||||
expect(result.current.vegaWalletDialog.manage).toBe(false);
|
||||
expect(result.current.vegaWalletDialog.connect).toBe(false);
|
||||
act(() => {
|
||||
result.current.vegaWalletDialog.setConnect(true);
|
||||
result.current.vegaWalletDialog.setManage(true);
|
||||
});
|
||||
expect(result.current.vegaWalletDialog.manage).toBe(true);
|
||||
expect(result.current.vegaWalletDialog.connect).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -2,17 +2,16 @@ import { useMemo, useState } from 'react';
|
||||
import type { LocalValues } from '../context/local-context';
|
||||
|
||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
const [connect, setConnect] = useState<boolean>(false);
|
||||
const [manage, setManage] = useState<boolean>(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
return useMemo<LocalValues>(
|
||||
() => ({
|
||||
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
||||
vegaWalletDialog: { manage, setManage },
|
||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||
theme,
|
||||
toggleTheme,
|
||||
}),
|
||||
[connect, manage, theme, toggleTheme, menuOpen]
|
||||
[manage, theme, toggleTheme, menuOpen]
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
@ -10,14 +10,18 @@ import {
|
||||
export const ConnectToVega = () => {
|
||||
const { appDispatch } = useAppState();
|
||||
const { t } = useTranslation();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
return (
|
||||
<Button
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
data-testid="connect-to-vega-wallet-btn"
|
||||
>
|
||||
{t('connectVegaWallet')}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@ -16,18 +16,22 @@ export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { appDispatch } = useAppState();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
|
||||
if (!pubKey) {
|
||||
return (
|
||||
<p>
|
||||
<Button
|
||||
data-testid="connect-to-vega-wallet-btn"
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
>
|
||||
{t('connectVegaWallet')}
|
||||
</Button>
|
||||
|
@ -11,8 +11,7 @@ export const VegaWalletDialogs = () => {
|
||||
<>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={appState.vegaWalletOverlay}
|
||||
setDialogOpen={(open) =>
|
||||
onChangeOpen={(open) =>
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: open,
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
} from '../wallet-card';
|
||||
import { DownloadWalletPrompt } from './download-wallet-prompt';
|
||||
import { usePollForDelegations } from './hooks';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export const VegaWallet = () => {
|
||||
@ -69,16 +69,19 @@ export const VegaWallet = () => {
|
||||
const VegaWalletNotConnected = () => {
|
||||
const { t } = useTranslation();
|
||||
const { appDispatch } = useAppState();
|
||||
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
fill={true}
|
||||
data-testid="connect-vega"
|
||||
>
|
||||
|
@ -14,7 +14,7 @@ import type {
|
||||
VoteButtonsQueryVariables,
|
||||
} from './__generated__/VoteButtonsQuery';
|
||||
import { VoteState } from './use-user-vote';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
ProposalState,
|
||||
ProposalUserAction,
|
||||
@ -84,6 +84,9 @@ export const VoteButtons = ({
|
||||
const { t } = useTranslation();
|
||||
const { appDispatch } = useAppState();
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
const [changeVote, setChangeVote] = React.useState(false);
|
||||
|
||||
const cantVoteUI = React.useMemo(() => {
|
||||
@ -95,12 +98,13 @@ export const VoteButtons = ({
|
||||
return (
|
||||
<div data-testid="connect-wallet">
|
||||
<ButtonLink
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
>
|
||||
{t('connectVegaWallet')}
|
||||
</ButtonLink>{' '}
|
||||
@ -144,6 +148,7 @@ export const VoteButtons = ({
|
||||
appDispatch,
|
||||
minVoterBalance,
|
||||
spamProtectionMinTokens,
|
||||
openVegaWalletDialog,
|
||||
]);
|
||||
|
||||
function submitVote(vote: VoteValue) {
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
} from '../../../contexts/app-state/app-state-context';
|
||||
import type { Rewards } from './__generated__/Rewards';
|
||||
import { RewardInfo } from './reward-info';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { useNetworkParams, NetworkParams } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const REWARDS_QUERY = gql`
|
||||
@ -67,6 +67,9 @@ export const REWARDS_QUERY = gql`
|
||||
export const RewardsIndex = () => {
|
||||
const { t } = useTranslation();
|
||||
const { pubKey, pubKeys } = useVegaWallet();
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
const { appDispatch } = useAppState();
|
||||
const { data, loading, error } = useQuery<Rewards>(REWARDS_QUERY, {
|
||||
variables: { partyId: pubKey },
|
||||
@ -147,12 +150,13 @@ export const RewardsIndex = () => {
|
||||
<div>
|
||||
<Button
|
||||
data-testid="connect-to-vega-wallet-btn"
|
||||
onClick={() =>
|
||||
onClick={() => {
|
||||
appDispatch({
|
||||
type: AppStateActionType.SET_VEGA_WALLET_OVERLAY,
|
||||
isOpen: true,
|
||||
})
|
||||
}
|
||||
});
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
>
|
||||
{t('connectVegaWallet')}
|
||||
</Button>
|
||||
|
@ -1,2 +1,2 @@
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
CYPRESS_VEGA_URL=https://api.n06.testnet.vega.xyz/graphql
|
||||
CYPRESS_VEGA_URL=https://api.n06.testnet.vega.xyz/graphql
|
||||
|
@ -15,9 +15,8 @@ interface NavbarProps {
|
||||
}
|
||||
|
||||
export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
|
||||
const { marketId, update } = useGlobalStore((store) => ({
|
||||
const { marketId } = useGlobalStore((store) => ({
|
||||
marketId: store.marketId,
|
||||
update: store.update,
|
||||
}));
|
||||
const [tradingPath, setTradingPath] = useState('/markets');
|
||||
useEffect(() => {
|
||||
@ -42,9 +41,7 @@ export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
|
||||
</nav>
|
||||
<div className="flex items-center gap-2 ml-auto">
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) => update({ connectDialog: open })}
|
||||
/>
|
||||
<VegaWalletConnectButton />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,49 +1,49 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||
import type { VegaWalletConnectButtonProps } from './vega-wallet-connect-button';
|
||||
import { VegaWalletConnectButton } from './vega-wallet-connect-button';
|
||||
import { truncateByChars } from '@vegaprotocol/react-helpers';
|
||||
|
||||
let props: VegaWalletConnectButtonProps;
|
||||
const mockUpdateDialogOpen = jest.fn();
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
...jest.requireActual('@vegaprotocol/wallet'),
|
||||
useVegaWalletDialogStore: () => ({
|
||||
openVegaWalletDialog: mockUpdateDialogOpen,
|
||||
}),
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
setConnectDialog: jest.fn(),
|
||||
};
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const generateJsx = (
|
||||
context: VegaWalletContextShape,
|
||||
props: VegaWalletConnectButtonProps
|
||||
) => {
|
||||
const generateJsx = (context: VegaWalletContextShape) => {
|
||||
return (
|
||||
<VegaWalletContext.Provider value={context}>
|
||||
<VegaWalletConnectButton {...props} />
|
||||
<VegaWalletConnectButton />
|
||||
</VegaWalletContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
it('Not connected', () => {
|
||||
render(generateJsx({ pubKey: null } as VegaWalletContextShape, props));
|
||||
render(generateJsx({ pubKey: null } as VegaWalletContextShape));
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toHaveTextContent('Connect Vega wallet');
|
||||
fireEvent.click(button);
|
||||
expect(props.setConnectDialog).toHaveBeenCalledWith(true);
|
||||
expect(mockUpdateDialogOpen).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('Connected', () => {
|
||||
const pubKey = { publicKey: '123456__123456', name: 'test' };
|
||||
render(
|
||||
generateJsx(
|
||||
{ pubKey: pubKey.publicKey, pubKeys: [pubKey] } as VegaWalletContextShape,
|
||||
props
|
||||
)
|
||||
generateJsx({
|
||||
pubKey: pubKey.publicKey,
|
||||
pubKeys: [pubKey],
|
||||
} as VegaWalletContextShape)
|
||||
);
|
||||
|
||||
const button = screen.getByRole('button');
|
||||
expect(button).toHaveTextContent(truncateByChars(pubKey.publicKey));
|
||||
fireEvent.click(button);
|
||||
expect(props.setConnectDialog).not.toHaveBeenCalled();
|
||||
expect(mockUpdateDialogOpen).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -10,18 +10,15 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
Icon,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
|
||||
export interface VegaWalletConnectButtonProps {
|
||||
setConnectDialog: (isOpen: boolean) => void;
|
||||
}
|
||||
|
||||
export const VegaWalletConnectButton = ({
|
||||
setConnectDialog,
|
||||
}: VegaWalletConnectButtonProps) => {
|
||||
export const VegaWalletConnectButton = () => {
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
const { pubKey, pubKeys, selectPubKey, disconnect } = useVegaWallet();
|
||||
const isConnected = pubKey !== null;
|
||||
|
||||
@ -64,7 +61,7 @@ export const VegaWalletConnectButton = ({
|
||||
return (
|
||||
<Button
|
||||
data-testid="connect-vega-wallet"
|
||||
onClick={() => setConnectDialog(true)}
|
||||
onClick={openVegaWalletDialog}
|
||||
size="sm"
|
||||
>
|
||||
<span className="whitespace-nowrap">{t('Connect Vega wallet')}</span>
|
||||
|
@ -1,15 +1,16 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Button, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
import { useVegaWallet, useVegaWalletDialogStore } from '@vegaprotocol/wallet';
|
||||
|
||||
interface VegaWalletContainerProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
|
||||
const { update } = useGlobalStore((store) => ({ update: store.update }));
|
||||
const { openVegaWalletDialog } = useVegaWalletDialogStore((store) => ({
|
||||
openVegaWalletDialog: store.openVegaWalletDialog,
|
||||
}));
|
||||
const { pubKey } = useVegaWallet();
|
||||
|
||||
if (!pubKey) {
|
||||
@ -20,7 +21,7 @@ export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
|
||||
{t('Connect your Vega wallet')}
|
||||
</p>
|
||||
<Button
|
||||
onClick={() => update({ connectDialog: true })}
|
||||
onClick={openVegaWalletDialog}
|
||||
data-testid="vega-wallet-connect"
|
||||
>
|
||||
{t('Connect')}
|
||||
|
@ -2,35 +2,23 @@ import type { AppProps } from 'next/app';
|
||||
import Head from 'next/head';
|
||||
import { Navbar } from '../components/navbar';
|
||||
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { VegaConnectDialog, VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
EnvironmentProvider,
|
||||
envTriggerMapping,
|
||||
useEnvironment,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { AppLoader } from '../components/app-loader';
|
||||
import { RiskNoticeDialog } from '../components/risk-notice-dialog';
|
||||
import './styles.css';
|
||||
import { useGlobalStore } from '../stores';
|
||||
import {
|
||||
AssetDetailsDialog,
|
||||
useAssetDetailsDialogStore,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { usePageTitleStore } from '../stores';
|
||||
import { Footer } from '../components/footer';
|
||||
import { useMemo } from 'react';
|
||||
import DialogsContainer from './dialogs-container';
|
||||
|
||||
const DEFAULT_TITLE = t('Welcome to Vega trading!');
|
||||
|
||||
function AppBody({ Component, pageProps }: AppProps) {
|
||||
const { connectDialog, update } = useGlobalStore((store) => ({
|
||||
connectDialog: store.connectDialog,
|
||||
update: store.update,
|
||||
}));
|
||||
const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
|
||||
const { pageTitle } = useGlobalStore((store) => ({
|
||||
const Title = () => {
|
||||
const { pageTitle } = usePageTitleStore((store) => ({
|
||||
pageTitle: store.pageTitle,
|
||||
}));
|
||||
|
||||
@ -42,32 +30,26 @@ function AppBody({ Component, pageProps }: AppProps) {
|
||||
if (networkName) return `${pageTitle} [${networkName}]`;
|
||||
return pageTitle;
|
||||
}, [pageTitle, networkName]);
|
||||
return (
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
);
|
||||
};
|
||||
|
||||
function AppBody({ Component, pageProps }: AppProps) {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
<Title />
|
||||
<div className="h-full relative dark:bg-black dark:text-white z-0 grid grid-rows-[min-content,1fr,min-content]">
|
||||
<AppLoader>
|
||||
<Navbar theme={theme} toggleTheme={toggleTheme} />
|
||||
<main data-testid={pageProps.page}>
|
||||
{/* @ts-ignore conflict between @types/react and nextjs internal types */}
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
<Footer />
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={connectDialog}
|
||||
setDialogOpen={(open) => update({ connectDialog: open })}
|
||||
/>
|
||||
<AssetDetailsDialog
|
||||
assetSymbol={symbol}
|
||||
trigger={trigger || null}
|
||||
open={isOpen}
|
||||
onChange={setOpen}
|
||||
/>
|
||||
<RiskNoticeDialog />
|
||||
<DialogsContainer />
|
||||
</AppLoader>
|
||||
</div>
|
||||
</ThemeContext.Provider>
|
||||
|
25
apps/trading/pages/dialogs-container.tsx
Normal file
25
apps/trading/pages/dialogs-container.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import {
|
||||
AssetDetailsDialog,
|
||||
useAssetDetailsDialogStore,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { VegaConnectDialog } from '@vegaprotocol/wallet';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { RiskNoticeDialog } from '../components/risk-notice-dialog';
|
||||
|
||||
const DialogsContainer = () => {
|
||||
const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
return (
|
||||
<>
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<AssetDetailsDialog
|
||||
assetSymbol={symbol}
|
||||
trigger={trigger || null}
|
||||
open={isOpen}
|
||||
onChange={setOpen}
|
||||
/>
|
||||
<RiskNoticeDialog />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default DialogsContainer;
|
@ -7,7 +7,7 @@ import {
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect } from 'react';
|
||||
import { useGlobalStore } from '../stores';
|
||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
||||
|
||||
export function Index() {
|
||||
const { replace } = useRouter();
|
||||
@ -21,6 +21,11 @@ export function Index() {
|
||||
update: store.update,
|
||||
}));
|
||||
|
||||
const { pageTitle, updateTitle } = usePageTitleStore((store) => ({
|
||||
pageTitle: store.pageTitle,
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
update({ landingDialog: true });
|
||||
|
||||
@ -33,18 +38,21 @@ export function Index() {
|
||||
data[0]?.decimalPlaces
|
||||
)
|
||||
: null;
|
||||
const pageTitle = titlefy([marketName, marketPrice]);
|
||||
const newPageTitle = titlefy([marketName, marketPrice]);
|
||||
|
||||
if (marketId) {
|
||||
replace(`/markets/${marketId}`);
|
||||
update({ marketId, pageTitle });
|
||||
update({ marketId });
|
||||
if (pageTitle !== newPageTitle) {
|
||||
updateTitle(newPageTitle);
|
||||
}
|
||||
}
|
||||
// Fallback to the markets list page
|
||||
else {
|
||||
replace('/markets');
|
||||
}
|
||||
}
|
||||
}, [data, replace, riskNoticeDialog, update]);
|
||||
}, [data, replace, riskNoticeDialog, update, pageTitle, updateTitle]);
|
||||
|
||||
return (
|
||||
<AsyncRenderer data={data} loading={loading} error={error}>
|
||||
|
@ -16,7 +16,7 @@ import type {
|
||||
MarketDataUpdateFieldsFragment,
|
||||
} from '@vegaprotocol/market-list';
|
||||
import { marketProvider, marketDataProvider } from '@vegaprotocol/market-list';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
import { TradeGrid, TradePanels } from './trade-grid';
|
||||
import { ColumnKind, SelectMarketDialog } from '../../components/select-market';
|
||||
|
||||
@ -40,18 +40,17 @@ const MarketPage = ({
|
||||
}) => {
|
||||
const { query, push } = useRouter();
|
||||
const { w } = useWindowSize();
|
||||
const {
|
||||
landingDialog,
|
||||
riskNoticeDialog,
|
||||
update,
|
||||
updateTitle,
|
||||
updateMarketId,
|
||||
} = useGlobalStore((store) => ({
|
||||
landingDialog: store.landingDialog,
|
||||
riskNoticeDialog: store.riskNoticeDialog,
|
||||
update: store.update,
|
||||
const { landingDialog, riskNoticeDialog, update } = useGlobalStore(
|
||||
(store) => ({
|
||||
landingDialog: store.landingDialog,
|
||||
riskNoticeDialog: store.riskNoticeDialog,
|
||||
update: store.update,
|
||||
})
|
||||
);
|
||||
|
||||
const { pageTitle, updateTitle } = usePageTitleStore((store) => ({
|
||||
pageTitle: store.pageTitle,
|
||||
updateTitle: store.updateTitle,
|
||||
updateMarketId: store.updateMarketId,
|
||||
}));
|
||||
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
@ -63,11 +62,11 @@ const MarketPage = ({
|
||||
const onSelect = useCallback(
|
||||
(id: string) => {
|
||||
if (id && id !== marketId) {
|
||||
updateMarketId(id);
|
||||
update({ marketId: id });
|
||||
push(`/markets/${id}`);
|
||||
}
|
||||
},
|
||||
[marketId, updateMarketId, push]
|
||||
[marketId, update, push]
|
||||
);
|
||||
|
||||
const variables = useMemo(
|
||||
@ -86,20 +85,22 @@ const MarketPage = ({
|
||||
skip: !marketId,
|
||||
});
|
||||
|
||||
const marketName = data?.tradableInstrument.instrument.name;
|
||||
const updateProvider = useCallback(
|
||||
({ data: marketData }: { data: MarketData }) => {
|
||||
const marketName = data?.tradableInstrument.instrument.name;
|
||||
const marketPrice = calculatePrice(
|
||||
marketData.markPrice,
|
||||
data?.decimalPlaces
|
||||
);
|
||||
if (marketName) {
|
||||
const pageTitle = titlefy([marketName, marketPrice]);
|
||||
updateTitle(pageTitle);
|
||||
const newPageTitle = titlefy([marketName, marketPrice]);
|
||||
if (pageTitle !== newPageTitle) {
|
||||
updateTitle(newPageTitle);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[updateTitle, data?.tradableInstrument.instrument.name, data?.decimalPlaces]
|
||||
[updateTitle, pageTitle, marketName, data?.decimalPlaces]
|
||||
);
|
||||
|
||||
useDataProvider<MarketData, MarketDataUpdateFieldsFragment>({
|
||||
@ -110,6 +111,16 @@ const MarketPage = ({
|
||||
updateOnInit: true,
|
||||
});
|
||||
|
||||
const tradeView = useMemo(() => {
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
if (w > 960) {
|
||||
return <TradeGrid market={data} onSelect={onSelect} />;
|
||||
}
|
||||
return <TradePanels market={data} onSelect={onSelect} />;
|
||||
}, [w, data, onSelect]);
|
||||
|
||||
if (!marketId) {
|
||||
return (
|
||||
<Splash>
|
||||
@ -129,11 +140,7 @@ const MarketPage = ({
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{w > 960 ? (
|
||||
<TradeGrid market={data} onSelect={onSelect} />
|
||||
) : (
|
||||
<TradePanels market={data} onSelect={onSelect} />
|
||||
)}
|
||||
{tradeView}
|
||||
<SelectMarketDialog
|
||||
dialogOpen={landingDialog && !riskNoticeDialog}
|
||||
setDialogOpen={(isOpen: boolean) =>
|
||||
|
@ -1,16 +1,19 @@
|
||||
import { useRouter } from 'next/router';
|
||||
import { MarketsContainer } from '@vegaprotocol/market-list';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||
import { useEffect } from 'react';
|
||||
import { titlefy } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const Markets = () => {
|
||||
const { update } = useGlobalStore((store) => ({ update: store.update }));
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
useEffect(() => {
|
||||
update({ pageTitle: titlefy(['Markets']) });
|
||||
}, [update]);
|
||||
|
||||
updateTitle(titlefy(['Markets']));
|
||||
}, [updateTitle]);
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<MarketsContainer
|
||||
onSelect={(marketId) => {
|
||||
|
@ -1,16 +1,17 @@
|
||||
import { t, titlefy } from '@vegaprotocol/react-helpers';
|
||||
import { Web3Container } from '@vegaprotocol/web3';
|
||||
import { useEffect } from 'react';
|
||||
import { useGlobalStore } from '../../../stores';
|
||||
import { usePageTitleStore } from '../../../stores';
|
||||
import { DepositContainer } from './deposit-container';
|
||||
|
||||
const Deposit = () => {
|
||||
const { update } = useGlobalStore((store) => ({
|
||||
update: store.update,
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
update({ pageTitle: titlefy([t('Deposits')]) });
|
||||
}, [update]);
|
||||
updateTitle(titlefy([t('Deposits')]));
|
||||
}, [updateTitle]);
|
||||
|
||||
return (
|
||||
<Web3Container>
|
||||
|
@ -10,16 +10,16 @@ import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
||||
import { DepositsContainer } from './deposits-container';
|
||||
import { ResizableGrid } from '@vegaprotocol/ui-toolkit';
|
||||
import { LayoutPriority } from 'allotment';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
import { usePageTitleStore } from '../../stores';
|
||||
import { AccountsContainer } from './accounts-container';
|
||||
|
||||
const Portfolio = () => {
|
||||
const { update } = useGlobalStore((store) => ({
|
||||
update: store.update,
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
}));
|
||||
useEffect(() => {
|
||||
update({ pageTitle: titlefy([t('Portfolio')]) });
|
||||
}, [update]);
|
||||
updateTitle(titlefy([t('Portfolio')]));
|
||||
}, [updateTitle]);
|
||||
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
||||
const tabContentClassName = 'h-full grid grid-rows-[min-content_1fr]';
|
||||
return (
|
||||
|
@ -2,33 +2,32 @@ import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import create from 'zustand';
|
||||
|
||||
interface GlobalStore {
|
||||
connectDialog: boolean;
|
||||
networkSwitcherDialog: boolean;
|
||||
landingDialog: boolean;
|
||||
riskNoticeDialog: boolean;
|
||||
marketId: string | null;
|
||||
pageTitle: string | null;
|
||||
update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
|
||||
}
|
||||
|
||||
interface PageTitleStore {
|
||||
pageTitle: string | null;
|
||||
updateTitle: (title: string) => void;
|
||||
updateMarketId: (marketId: string) => void;
|
||||
}
|
||||
|
||||
export const useGlobalStore = create<GlobalStore>((set) => ({
|
||||
connectDialog: false,
|
||||
networkSwitcherDialog: false,
|
||||
landingDialog: false,
|
||||
riskNoticeDialog: false,
|
||||
marketId: LocalStorage.getItem('marketId') || null,
|
||||
pageTitle: null,
|
||||
update: (state) => {
|
||||
set(state);
|
||||
if (state.marketId) {
|
||||
LocalStorage.setItem('marketId', state.marketId);
|
||||
}
|
||||
},
|
||||
updateTitle: (title: string) => set({ pageTitle: title }),
|
||||
updateMarketId: (marketId: string) => {
|
||||
set({ marketId });
|
||||
LocalStorage.setItem('marketId', marketId);
|
||||
},
|
||||
}));
|
||||
|
||||
export const usePageTitleStore = create<PageTitleStore>((set) => ({
|
||||
pageTitle: null,
|
||||
updateTitle: (title: string) => set({ pageTitle: title }),
|
||||
}));
|
||||
|
@ -20,6 +20,14 @@ import { EnvironmentProvider } from '@vegaprotocol/environment';
|
||||
import type { ChainIdQuery } from '@vegaprotocol/react-helpers';
|
||||
import { ChainIdDocument } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const mockUpdateDialogOpen = jest.fn();
|
||||
const mockCloseVegaDialog = jest.fn();
|
||||
jest.mock('zustand', () => () => () => ({
|
||||
updateVegaWalletDialog: mockUpdateDialogOpen,
|
||||
closeVegaWalletDialog: mockCloseVegaDialog,
|
||||
vegaWalletDialogOpen: true,
|
||||
}));
|
||||
|
||||
let defaultProps: VegaConnectDialogProps;
|
||||
|
||||
const rest = new RestConnector();
|
||||
@ -29,10 +37,9 @@ const connectors = {
|
||||
jsonRpc,
|
||||
};
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
defaultProps = {
|
||||
connectors,
|
||||
dialogOpen: true,
|
||||
setDialogOpen: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
@ -122,7 +129,7 @@ describe('VegaConnectDialog', () => {
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(fields);
|
||||
|
||||
expect(defaultProps.setDialogOpen).toHaveBeenCalledWith(false);
|
||||
expect(mockCloseVegaDialog).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles failed connection', async () => {
|
||||
@ -149,7 +156,7 @@ describe('VegaConnectDialog', () => {
|
||||
expect(spy).toHaveBeenCalledWith(fields);
|
||||
|
||||
expect(screen.getByTestId('form-error')).toHaveTextContent(errMessage);
|
||||
expect(defaultProps.setDialogOpen).not.toHaveBeenCalled();
|
||||
expect(mockUpdateDialogOpen).not.toHaveBeenCalled();
|
||||
|
||||
// Fetch failed due to wallet not running
|
||||
spy = jest
|
||||
@ -249,9 +256,7 @@ describe('VegaConnectDialog', () => {
|
||||
});
|
||||
|
||||
it('connects with permission update', async () => {
|
||||
const mockSetDialog = jest.fn();
|
||||
|
||||
render(generateJSX({ setDialogOpen: mockSetDialog }));
|
||||
render(generateJSX());
|
||||
await selectJsonRpc();
|
||||
|
||||
// Wallet version check
|
||||
@ -299,7 +304,7 @@ describe('VegaConnectDialog', () => {
|
||||
await act(async () => {
|
||||
jest.advanceTimersByTime(CLOSE_DELAY);
|
||||
});
|
||||
expect(mockSetDialog).toHaveBeenCalledWith(false);
|
||||
expect(mockCloseVegaDialog).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('handles incompatible wallet', async () => {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import create from 'zustand';
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
@ -28,15 +29,50 @@ type WalletType = 'gui' | 'cli' | 'hosted';
|
||||
|
||||
export interface VegaConnectDialogProps {
|
||||
connectors: Connectors;
|
||||
dialogOpen: boolean;
|
||||
setDialogOpen: (isOpen: boolean) => void;
|
||||
onChangeOpen?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export const useVegaWalletDialogStore = create<VegaWalletDialogStore>(
|
||||
(set) => ({
|
||||
vegaWalletDialogOpen: false,
|
||||
updateVegaWalletDialog: (open: boolean) =>
|
||||
set({ vegaWalletDialogOpen: open }),
|
||||
openVegaWalletDialog: () => set({ vegaWalletDialogOpen: true }),
|
||||
closeVegaWalletDialog: () => set({ vegaWalletDialogOpen: false }),
|
||||
})
|
||||
);
|
||||
|
||||
interface VegaWalletDialogStore {
|
||||
vegaWalletDialogOpen: boolean;
|
||||
updateVegaWalletDialog: (open: boolean) => void;
|
||||
openVegaWalletDialog: () => void;
|
||||
closeVegaWalletDialog: () => void;
|
||||
}
|
||||
|
||||
export const VegaConnectDialog = ({
|
||||
connectors,
|
||||
dialogOpen,
|
||||
setDialogOpen,
|
||||
onChangeOpen,
|
||||
}: VegaConnectDialogProps) => {
|
||||
const {
|
||||
vegaWalletDialogOpen,
|
||||
closeVegaWalletDialog,
|
||||
updateVegaWalletDialog,
|
||||
} = useVegaWalletDialogStore((store) => ({
|
||||
vegaWalletDialogOpen: store.vegaWalletDialogOpen,
|
||||
updateVegaWalletDialog: onChangeOpen
|
||||
? (open: boolean) => {
|
||||
store.updateVegaWalletDialog(open);
|
||||
onChangeOpen(open);
|
||||
}
|
||||
: store.updateVegaWalletDialog,
|
||||
closeVegaWalletDialog: onChangeOpen
|
||||
? () => {
|
||||
store.closeVegaWalletDialog();
|
||||
onChangeOpen(false);
|
||||
}
|
||||
: store.closeVegaWalletDialog,
|
||||
}));
|
||||
|
||||
const { data, error, loading } = useChainIdQuery();
|
||||
|
||||
const renderContent = () => {
|
||||
@ -66,14 +102,18 @@ export const VegaConnectDialog = ({
|
||||
return (
|
||||
<ConnectDialogContainer
|
||||
connectors={connectors}
|
||||
closeDialog={() => setDialogOpen(false)}
|
||||
closeDialog={closeVegaWalletDialog}
|
||||
appChainId={data.statistics.chainId}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={dialogOpen} size="small" onChange={setDialogOpen}>
|
||||
<Dialog
|
||||
open={vegaWalletDialogOpen}
|
||||
size="small"
|
||||
onChange={updateVegaWalletDialog}
|
||||
>
|
||||
{renderContent()}
|
||||
</Dialog>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user