chore: console dapp routes for skeleton page (2361) (#2450)

* chore: console dapp routes for skeleton page (2361)

* chore: console dapp routes for skeleton page (2361)

* chore: console dapp routes for skeleton page (2361)
This commit is contained in:
Art 2022-12-22 15:24:20 +01:00 committed by GitHub
parent b3bbe260c6
commit 9c26f4d01b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 79 additions and 43 deletions

View File

@ -138,7 +138,7 @@ describe('Navbar', { tags: '@smoke' }, () => {
it('should be properly rendered', () => { it('should be properly rendered', () => {
const links = ['Markets', 'Trading', 'Portfolio']; const links = ['Markets', 'Trading', 'Portfolio'];
const hashes = ['#/markets', '#/markets/market-0', '#/portfolio']; const hashes = ['#/markets/all', '#/markets/market-0', '#/portfolio'];
let i = 0; let i = 0;
cy.getByTestId('navbar').within(() => { cy.getByTestId('navbar').within(() => {
cy.get('a[data-testid]', { log: true }) cy.get('a[data-testid]', { log: true })

View File

@ -158,7 +158,7 @@ describe('home', { tags: '@regression' }, () => {
cy.visit('/'); cy.visit('/');
cy.wait('@Markets'); cy.wait('@Markets');
cy.wait('@MarketsData'); cy.wait('@MarketsData');
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/empty`); cy.url().should('eq', Cypress.config().baseUrl + `/#/markets`);
cy.getByTestId('welcome-notice-title').should( cy.getByTestId('welcome-notice-title').should(
'contain.text', 'contain.text',
'Welcome to Console' 'Welcome to Console'

View File

@ -62,9 +62,9 @@ describe('markets table', { tags: '@smoke' }, () => {
'SOLUSD', 'SOLUSD',
]; ];
cy.getByTestId('view-market-list-link') cy.getByTestId('view-market-list-link')
.should('have.attr', 'href', '#/markets') .should('have.attr', 'href', '#/markets/all')
.click(); .click();
cy.url().should('eq', Cypress.config('baseUrl') + '/#/markets'); cy.url().should('eq', Cypress.config('baseUrl') + '/#/markets/all');
cy.contains('AAPL.MF21').should('be.visible'); cy.contains('AAPL.MF21').should('be.visible');
cy.get('.ag-header-cell-label').contains('Market').click(); // sort by market name cy.get('.ag-header-cell-label').contains('Market').click(); // sort by market name
for (let i = 0; i < ExpectedSortedMarkets.length; i++) { for (let i = 0; i < ExpectedSortedMarkets.length; i++) {
@ -76,7 +76,7 @@ describe('markets table', { tags: '@smoke' }, () => {
it('proposed markets tab should be rendered properly', () => { it('proposed markets tab should be rendered properly', () => {
cy.getByTestId('view-market-list-link') cy.getByTestId('view-market-list-link')
.should('have.attr', 'href', '#/markets') .should('have.attr', 'href', '#/markets/all')
.click(); .click();
cy.get('[data-testid="Active markets"]').should( cy.get('[data-testid="Active markets"]').should(
'have.attr', 'have.attr',

View File

@ -5,7 +5,7 @@ import {
useDataProvider, useDataProvider,
} from '@vegaprotocol/react-helpers'; } from '@vegaprotocol/react-helpers';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { EMPTY_MARKET_ID } from '../../components/constants'; import { Links, Routes } from '../../pages/client-router';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useGlobalStore, usePageTitleStore } from '../../stores'; import { useGlobalStore, usePageTitleStore } from '../../stores';
@ -39,13 +39,15 @@ export const Home = () => {
const newPageTitle = titlefy([marketName, marketPrice]); const newPageTitle = titlefy([marketName, marketPrice]);
if (marketId) { if (marketId) {
navigate(`/markets/${marketId}`, { replace: true }); navigate(Links[Routes.MARKET](marketId), {
replace: true,
});
update({ marketId }); update({ marketId });
if (pageTitle !== newPageTitle) { if (pageTitle !== newPageTitle) {
updateTitle(newPageTitle); updateTitle(newPageTitle);
} }
} else { } else {
navigate(`/markets/${EMPTY_MARKET_ID}`); navigate(Links[Routes.MARKET]());
} }
} }
}, [data, navigate, update, pageTitle, updateTitle]); }, [data, navigate, update, pageTitle, updateTitle]);

View File

@ -27,6 +27,7 @@ import { Header, HeaderStat } from '../../components/header';
import type { AgGridReact } from 'ag-grid-react'; import type { AgGridReact } from 'ag-grid-react';
import type { LiquidityProvisionData } from '@vegaprotocol/liquidity'; import type { LiquidityProvisionData } from '@vegaprotocol/liquidity';
import { Link, useParams } from 'react-router-dom'; import { Link, useParams } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
export const Liquidity = () => { export const Liquidity = () => {
const params = useParams(); const params = useParams();
@ -227,7 +228,7 @@ export const LiquidityViewContainer = ({
title={ title={
marketProvision?.market?.tradableInstrument.instrument.name && marketProvision?.market?.tradableInstrument.instrument.name &&
marketId && ( marketId && (
<Link to={`/markets/${marketId}`}> <Link to={Links[Routes.MARKET](marketId)}>
<UiToolkitLink className="sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300"> <UiToolkitLink className="sm:text-lg md:text-xl lg:text-2xl flex items-center gap-2 whitespace-nowrap hover:text-neutral-500 dark:hover:text-neutral-300">
{`${ {`${
marketProvision?.market?.tradableInstrument.instrument.name marketProvision?.market?.tradableInstrument.instrument.name

View File

@ -18,7 +18,7 @@ import { marketProvider, marketDataProvider } from '@vegaprotocol/market-list';
import { useGlobalStore, usePageTitleStore } from '../../stores'; import { useGlobalStore, usePageTitleStore } from '../../stores';
import { TradeGrid, TradePanels } from './trade-grid'; import { TradeGrid, TradePanels } from './trade-grid';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import { EMPTY_MARKET_ID } from '../../components/constants'; import { Links, Routes } from '../../pages/client-router';
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => { const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
return markPrice && decimalPlaces return markPrice && decimalPlaces
@ -31,17 +31,11 @@ export interface SingleMarketData extends SingleMarketFieldsFragment {
data: MarketData; data: MarketData;
} }
export const Market = ({ export const Market = () => {
id,
marketId: mid,
}: {
id?: string;
marketId?: string;
}) => {
const params = useParams(); const params = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const isEmpty = params.marketId === EMPTY_MARKET_ID;
const marketId = isEmpty ? undefined : params.marketId; const marketId = params.marketId;
const { w } = useWindowSize(); const { w } = useWindowSize();
const { update } = useGlobalStore((store) => ({ const { update } = useGlobalStore((store) => ({
@ -57,7 +51,7 @@ export const Market = ({
(id: string) => { (id: string) => {
if (id && id !== marketId) { if (id && id !== marketId) {
update({ marketId: id }); update({ marketId: id });
navigate(`/markets/${id}`); navigate(Links[Routes.MARKET](id));
} }
}, },
[marketId, update, navigate] [marketId, update, navigate]
@ -111,7 +105,7 @@ export const Market = ({
return <TradePanels market={data} onSelect={onSelect} />; return <TradePanels market={data} onSelect={onSelect} />;
}, [w, data, onSelect]); }, [w, data, onSelect]);
if (!marketId && !isEmpty) { if (!data && marketId) {
return ( return (
<Splash> <Splash>
<p>{t('Not found')}</p> <p>{t('Not found')}</p>
@ -126,7 +120,7 @@ export const Market = ({
data={data || undefined} data={data || undefined}
noDataCondition={(data) => false} noDataCondition={(data) => false}
render={(data) => { render={(data) => {
if (!data && !isEmpty) { if (!data && marketId) {
return <Splash>{t('Market not found')}</Splash>; return <Splash>{t('Market not found')}</Splash>;
} }
return <>{tradeView}</>; return <>{tradeView}</>;

View File

@ -2,6 +2,7 @@ import { useCallback } from 'react';
import { MarketsContainer } from '@vegaprotocol/market-list'; import { MarketsContainer } from '@vegaprotocol/market-list';
import { useGlobalStore } from '../../stores'; import { useGlobalStore } from '../../stores';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
export const Markets = () => { export const Markets = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -9,7 +10,7 @@ export const Markets = () => {
const handleOnSelect = useCallback( const handleOnSelect = useCallback(
(marketId: string) => { (marketId: string) => {
update({ marketId }); update({ marketId });
navigate(`/markets/${marketId}`); navigate(Links[Routes.MARKET](marketId));
}, },
[update, navigate] [update, navigate]
); );

View File

@ -1,6 +1,5 @@
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
export const DEBOUNCE_UPDATE_TIME = 500; export const DEBOUNCE_UPDATE_TIME = 500;
export const EMPTY_MARKET_ID = 'empty';
export const RISK_ACCEPTED_KEY = 'vega-risk-accepted'; export const RISK_ACCEPTED_KEY = 'vega-risk-accepted';
export const MAINNET_WELCOME_HEADER = t( export const MAINNET_WELCOME_HEADER = t(
'Trade cash settled futures on the fully decentralised Vega network.' 'Trade cash settled futures on the fully decentralised Vega network.'

View File

@ -1,13 +1,18 @@
import classNames from 'classnames'; import classNames from 'classnames';
import { NavLink, Link } from 'react-router-dom'; import { NavLink, Link } from 'react-router-dom';
import { NetworkSwitcher, useEnvironment } from '@vegaprotocol/environment'; import {
DApp,
NetworkSwitcher,
TOKEN_GOVERNANCE,
useLinks,
} from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { useGlobalStore } from '../../stores/global'; import { useGlobalStore } from '../../stores/global';
import { VegaWalletConnectButton } from '../vega-wallet-connect-button'; import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
import { NewTab, ThemeSwitcher } from '@vegaprotocol/ui-toolkit'; import { NewTab, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
import { Vega } from '../icons/vega'; import { Vega } from '../icons/vega';
import type { HTMLAttributeAnchorTarget } from 'react'; import type { HTMLAttributeAnchorTarget } from 'react';
import { Routes } from '../../pages/client-router'; import { Links, Routes } from '../../pages/client-router';
import { import {
getNavLinkClassNames, getNavLinkClassNames,
getActiveNavLinkClassNames, getActiveNavLinkClassNames,
@ -20,11 +25,13 @@ interface NavbarProps {
} }
export const Navbar = ({ navbarTheme = 'inherit' }: NavbarProps) => { export const Navbar = ({ navbarTheme = 'inherit' }: NavbarProps) => {
const { VEGA_TOKEN_URL } = useEnvironment(); const tokenLink = useLinks(DApp.Token);
const { marketId } = useGlobalStore((store) => ({ const { marketId } = useGlobalStore((store) => ({
marketId: store.marketId, marketId: store.marketId,
})); }));
const tradingPath = marketId ? `/markets/${marketId}` : '/markets'; const tradingPath = marketId
? Links[Routes.MARKET](marketId)
: Links[Routes.MARKET]();
return ( return (
<Nav <Nav
navbarTheme={navbarTheme} navbarTheme={navbarTheme}
@ -38,7 +45,7 @@ export const Navbar = ({ navbarTheme = 'inherit' }: NavbarProps) => {
> >
<AppNavLink <AppNavLink
name={t('Markets')} name={t('Markets')}
path={Routes.MARKETS} path={Links[Routes.MARKETS]()}
navbarTheme={navbarTheme} navbarTheme={navbarTheme}
end end
/> />
@ -46,14 +53,15 @@ export const Navbar = ({ navbarTheme = 'inherit' }: NavbarProps) => {
name={t('Trading')} name={t('Trading')}
path={tradingPath} path={tradingPath}
navbarTheme={navbarTheme} navbarTheme={navbarTheme}
end
/> />
<AppNavLink <AppNavLink
name={t('Portfolio')} name={t('Portfolio')}
path={Routes.PORTFOLIO} path={Links[Routes.PORTFOLIO]()}
navbarTheme={navbarTheme} navbarTheme={navbarTheme}
/> />
<a <a
href={`${VEGA_TOKEN_URL}/governance`} href={tokenLink(TOKEN_GOVERNANCE)}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className={getActiveNavLinkClassNames(false, navbarTheme)} className={getActiveNavLinkClassNames(false, navbarTheme)}

View File

@ -22,6 +22,7 @@ import { MarketMarkPrice } from '../market-mark-price';
import { Last24hPriceChange } from '../last-24h-price-change'; import { Last24hPriceChange } from '../last-24h-price-change';
import { MarketTradingMode } from '../market-trading-mode'; import { MarketTradingMode } from '../market-trading-mode';
import { Last24hVolume } from '../last-24h-volume'; import { Last24hVolume } from '../last-24h-volume';
import { Links, Routes } from '../../pages/client-router';
type Market = MarketWithData & MarketWithCandles; type Market = MarketWithData & MarketWithCandles;
@ -194,7 +195,7 @@ export const columns = (
kind: ColumnKind.Market, kind: ColumnKind.Market,
value: ( value: (
<Link <Link
to={`/markets/${market.id}`} to={Links[Routes.MARKET](market.id)}
data-testid={`market-link-${market.id}`} data-testid={`market-link-${market.id}`}
onKeyPress={(event) => handleKeyPress(event, market.id)} onKeyPress={(event) => handleKeyPress(event, market.id)}
onClick={(e) => { onClick={(e) => {
@ -382,7 +383,7 @@ export const columnsPositionMarkets = (
kind: ColumnKind.Market, kind: ColumnKind.Market,
value: ( value: (
<Link <Link
to={`/markets/${market.id}`} to={Links[Routes.MARKET](market.id)}
data-testid={`market-link-${market.id}`} data-testid={`market-link-${market.id}`}
onKeyPress={(event) => handleKeyPress(event, market.id)} onKeyPress={(event) => handleKeyPress(event, market.id)}
onClick={(e) => { onClick={(e) => {

View File

@ -12,9 +12,9 @@ import {
} from '../select-market'; } from '../select-market';
import { WelcomeDialogHeader } from './welcome-dialog-header'; import { WelcomeDialogHeader } from './welcome-dialog-header';
import { Link, useNavigate, useParams } from 'react-router-dom'; import { Link, useNavigate, useParams } from 'react-router-dom';
import { EMPTY_MARKET_ID } from '../constants';
import { useGlobalStore } from '../../stores'; import { useGlobalStore } from '../../stores';
import { ProposedMarkets } from './proposed-markets'; import { ProposedMarkets } from './proposed-markets';
import { Links, Routes } from '../../pages/client-router';
export const SelectMarketLandingTable = ({ export const SelectMarketLandingTable = ({
markets, markets,
@ -25,8 +25,7 @@ export const SelectMarketLandingTable = ({
}) => { }) => {
const params = useParams(); const params = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const isEmpty = params.marketId === EMPTY_MARKET_ID; const marketId = params.marketId;
const marketId = isEmpty ? undefined : params.marketId;
const { update } = useGlobalStore((store) => ({ const { update } = useGlobalStore((store) => ({
update: store.update, update: store.update,
@ -36,7 +35,7 @@ export const SelectMarketLandingTable = ({
(id: string) => { (id: string) => {
if (id && id !== marketId) { if (id && id !== marketId) {
update({ marketId: id }); update({ marketId: id });
navigate(`/markets/${id}`); navigate(Links[Routes.MARKET](id));
} }
}, },
[marketId, update, navigate] [marketId, update, navigate]
@ -87,7 +86,7 @@ export const SelectMarketLandingTable = ({
</div> </div>
<div className="mt-4 text-md"> <div className="mt-4 text-md">
<Link <Link
to="/markets" to={Links[Routes.MARKETS]()}
data-testid="view-market-list-link" data-testid="view-market-list-link"
onClick={() => onClose()} onClick={() => onClose()}
> >

View File

@ -1,8 +1,10 @@
import { Suspense } from 'react'; import { Suspense } from 'react';
import type { RouteObject } from 'react-router-dom';
import { useRoutes } from 'react-router-dom'; import { useRoutes } from 'react-router-dom';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { Splash } from '@vegaprotocol/ui-toolkit'; import { Splash } from '@vegaprotocol/ui-toolkit';
import trimEnd from 'lodash/trimEnd';
const LazyHome = dynamic(() => import('../client-pages/home'), { const LazyHome = dynamic(() => import('../client-pages/home'), {
ssr: false, ssr: false,
@ -26,11 +28,24 @@ const LazyPortfolio = dynamic(() => import('../client-pages/portfolio'), {
export enum Routes { export enum Routes {
HOME = '/', HOME = '/',
MARKETS = '/markets', MARKET = '/markets',
MARKETS = '/markets/all',
PORTFOLIO = '/portfolio', PORTFOLIO = '/portfolio',
LIQUIDITY = 'liquidity/:marketId',
} }
const routerConfig = [ type ConsoleLinks = { [r in Routes]: (...args: string[]) => string };
export const Links: ConsoleLinks = {
[Routes.HOME]: () => Routes.HOME,
[Routes.MARKET]: (marketId: string | null | undefined) =>
marketId ? trimEnd(`${Routes.MARKET}/${marketId}`, '/') : Routes.MARKET,
[Routes.MARKETS]: () => Routes.MARKETS,
[Routes.PORTFOLIO]: () => Routes.PORTFOLIO,
[Routes.LIQUIDITY]: (marketId: string) =>
Routes.LIQUIDITY.replace(':marketId', marketId),
};
const routerConfig: RouteObject[] = [
{ {
index: true, index: true,
element: <LazyHome />, element: <LazyHome />,
@ -40,11 +55,20 @@ const routerConfig = [
element: <LazyMarkets />, element: <LazyMarkets />,
}, },
{ {
path: 'markets/:marketId', path: Routes.MARKET,
element: <LazyMarket />, children: [
{
index: true,
element: <LazyMarket />,
},
{
path: ':marketId',
element: <LazyMarket />,
},
],
}, },
{ {
path: 'liquidity/:marketId', path: Routes.LIQUIDITY,
element: <LazyLiquidity />, element: <LazyLiquidity />,
}, },
{ {

View File

@ -91,6 +91,7 @@ export const BLOG = 'https://blog.vega.xyz/';
export const TOKEN_NEW_MARKET_PROPOSAL = '/governance/propose/new-market'; export const TOKEN_NEW_MARKET_PROPOSAL = '/governance/propose/new-market';
export const TOKEN_NEW_NETWORK_PARAM_PROPOSAL = export const TOKEN_NEW_NETWORK_PARAM_PROPOSAL =
'/governance/propose/network-parameter'; '/governance/propose/network-parameter';
export const TOKEN_GOVERNANCE = '/governance';
export const TOKEN_PROPOSALS = '/governance'; export const TOKEN_PROPOSALS = '/governance';
export const TOKEN_PROPOSAL = '/governance/:id'; export const TOKEN_PROPOSAL = '/governance/:id';
@ -99,3 +100,9 @@ export const EXPLORER_TX = '/txs/:hash';
// Etherscan pages // Etherscan pages
export const ETHERSCAN_TX = '/tx/:hash'; export const ETHERSCAN_TX = '/tx/:hash';
// Console pages
export const CONSOLE_MARKET = '/markets/:marketId';
export const CONSOLE_MARKETS = '/markets/all';
export const CONSOLE_PORTFOLIO = '/portfolio';
export const CONSOLE_LIQUIDITY = 'liquidity/:marketId';