Fix/Default market and tabs navigation (#518)

* fix: dont use localstorage for navigation, remove query params for tabs

* chore: lint

* fix: revert to using url rather than data test id

* chore: lint

* chore: remove arrow down ref from markets page object
This commit is contained in:
Matthew Russell 2022-06-08 01:47:31 -07:00 committed by GitHub
parent ca3a2905dd
commit be3b416176
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 21 additions and 101 deletions

View File

@ -20,11 +20,10 @@ export default class BasePage {
.should('be.visible')
.click({ force: true });
cy.url().should('include', '/portfolio');
cy.getByTestId('portfolio');
}
navigateToMarkets() {
cy.getByTestId('markets-link').should('be.visible').click({ force: true });
cy.get(`a[href='${this.marketsUrl}']`).should('be.visible').click();
cy.url().should('include', '/markets');
}

View File

@ -8,7 +8,6 @@ export default class MarketPage extends BasePage {
marketRowPrices = 'flash-cell';
marketRowDescription = 'name';
marketStateColId = 'data';
openMarketMenu = 'arrow-down';
validateMarketsAreDisplayed() {
// We need this to ensure that ag-grid is fully rendered before asserting
@ -57,13 +56,5 @@ export default class MarketPage extends BasePage {
clickOnMarket(text: string) {
cy.get(`[col-id=${this.marketStateColId}]`).should('be.visible');
cy.get(`[col-id=${this.marketStateColId}]`).contains(text).click();
cy.url({ timeout: 8000 }).should(
'contain',
'portfolio=orders&trade=orderbook'
);
}
clickOpenMarketMenu() {
cy.getByTestId(this.openMarketMenu).click();
}
}

View File

@ -19,7 +19,6 @@ const mockMarkets = () => {
Then('I navigate to markets page', () => {
mockMarkets();
marketsPage.navigateToMarkets();
marketsPage.clickOpenMarketMenu();
cy.wait('@Markets');
});

View File

@ -1,38 +1,17 @@
import * as Tabs from '@radix-ui/react-tabs';
import classNames from 'classnames';
import { useRouter } from 'next/router';
import type { ReactElement, ReactNode } from 'react';
import { Children, isValidElement, useEffect, useState } from 'react';
import { Children, isValidElement, useState } from 'react';
interface GridTabsProps {
children: ReactElement<GridTabProps>[];
group: string;
}
export const GridTabs = ({ children, group }: GridTabsProps) => {
const { query, asPath, replace } = useRouter();
export const GridTabs = ({ children }: GridTabsProps) => {
const [activeTab, setActiveTab] = useState<string>(() => {
const tab = query[group];
if (typeof tab === 'string') {
return tab;
}
// Default to first tab
return children[0].props.id;
});
// Update the query string in the url when the active tab changes
// uses group property as the query string key
useEffect(() => {
const [url, queryString] = asPath.split('?');
const searchParams = new URLSearchParams(queryString);
searchParams.set(group, activeTab as string);
replace(`${url}?${searchParams.toString()}`);
// replace and using asPath causes a render loop
// eslint-disable-next-line
}, [activeTab, group]);
return (
<Tabs.Root
value={activeTab}

View File

@ -2,38 +2,9 @@ import { useRouter } from 'next/router';
import { Vega } from '../icons/vega';
import Link from 'next/link';
import { AnchorButton } from '@vegaprotocol/ui-toolkit';
import { LocalStorage, t } from '@vegaprotocol/react-helpers';
import { useEffect, useState } from 'react';
import { t } from '@vegaprotocol/react-helpers';
export const Navbar = () => {
const initNavItemsState = [
{
name: t('Portfolio'),
path: '/portfolio',
testId: 'portfolio-link',
slug: '',
},
];
const [navItems, setNavItems] = useState(initNavItemsState);
const marketId = LocalStorage.getItem('marketId') ?? '';
useEffect(() => {
setNavItems([
{
name: t('Trading'),
path: '/markets',
testId: 'markets-link',
slug: marketId,
},
{
name: t('Portfolio'),
path: '/portfolio',
testId: 'portfolio-link',
slug: '',
},
]);
}, [marketId]);
return (
<nav className="flex items-center">
<Link href="/" passHref={true}>
@ -41,7 +12,10 @@ export const Navbar = () => {
<Vega className="fill-black dark:fill-white" />
</a>
</Link>
{navItems.map((route) => (
{[
{ name: t('Trading'), path: '/markets' },
{ name: t('Portfolio'), path: '/portfolio' },
].map((route) => (
<NavLink key={route.path} {...route} />
))}
</nav>
@ -53,30 +27,18 @@ interface NavLinkProps {
path: string;
exact?: boolean;
testId?: string;
slug?: string;
}
const NavLink = ({
name,
path,
exact,
testId = name,
slug = '',
}: NavLinkProps) => {
const NavLink = ({ name, path, exact, testId = name }: NavLinkProps) => {
const router = useRouter();
const isActive =
router.asPath === path || (!exact && router.asPath.startsWith(path));
const href = slug !== '' ? `${path}/${slug}` : path;
return (
<AnchorButton
variant={isActive ? 'accent' : 'inline'}
className="px-16 py-6 h-[38px] uppercase border-0 self-end xs:text-ui sm:text-body-large md:text-h5 lg:text-h4"
data-testid={testId}
href={href}
onClick={(e) => {
e.preventDefault();
router.push(href);
}}
href={path}
>
{name}
</AnchorButton>

View File

@ -1,5 +1,4 @@
import { gql, useQuery } from '@apollo/client';
import { LocalStorage } from '@vegaprotocol/react-helpers';
import { MarketTradingMode } from '@vegaprotocol/types';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import sortBy from 'lodash/sortBy';
@ -36,13 +35,10 @@ export function Index() {
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
const { data, error, loading } = useQuery<MarketsLanding>(MARKETS_QUERY);
const setLandingDialog = useGlobalStore((state) => state.setLandingDialog);
const lastSelectedMarketId = LocalStorage.getItem('marketId');
useEffect(() => {
if (data) {
const marketId = lastSelectedMarketId
? lastSelectedMarketId
: marketList(data)[0]?.id;
const marketId = marketList(data)[0]?.id;
// If a default market is found, go to it with the landing dialog open
if (marketId) {
@ -54,7 +50,7 @@ export function Index() {
replace('/markets');
}
}
}, [data, lastSelectedMarketId, replace, setLandingDialog]);
}, [data, replace, setLandingDialog]);
return (
<AsyncRenderer data={data} loading={loading} error={error}>

View File

@ -5,7 +5,7 @@ import React, { useEffect, useState } from 'react';
import debounce from 'lodash/debounce';
import { PageQueryContainer } from '../../components/page-query-container';
import { TradeGrid, TradePanels } from './trade-grid';
import { LocalStorage, t } from '@vegaprotocol/react-helpers';
import { t } from '@vegaprotocol/react-helpers';
import { useGlobalStore } from '../../stores';
import { LandingDialog } from '@vegaprotocol/market-list';
import type { Market, MarketVariables } from './__generated__/Market';
@ -74,7 +74,6 @@ const MarketPage = ({ id }: { id?: string }) => {
);
}
LocalStorage.setItem('marketId', marketId);
return (
<PageQueryContainer<Market, MarketVariables>
query={MARKET_QUERY}

View File

@ -99,7 +99,7 @@ export const TradeGrid = ({ market }: TradeGridProps) => {
<TradeMarketHeader market={market} />
<div className={wrapperClasses}>
<TradeGridChild className="row-start-1 row-end-3">
<GridTabs group="chart">
<GridTabs>
<GridTab id="candles" name={t('Candles')}>
<TradingViews.Candles marketId={market.id} />
</GridTab>
@ -112,7 +112,7 @@ export const TradeGrid = ({ market }: TradeGridProps) => {
<TradingViews.Ticket marketId={market.id} />
</TradeGridChild>
<TradeGridChild className="row-start-1 row-end-3">
<GridTabs group="trade">
<GridTabs>
<GridTab id="trades" name={t('Trades')}>
<TradingViews.Trades marketId={market.id} />
</GridTab>
@ -122,7 +122,7 @@ export const TradeGrid = ({ market }: TradeGridProps) => {
</GridTabs>
</TradeGridChild>
<TradeGridChild className="col-span-3">
<GridTabs group="portfolio">
<GridTabs>
<GridTab id="orders" name={t('Orders')}>
<TradingViews.Orders />
</GridTab>

View File

@ -21,7 +21,7 @@ const Portfolio = () => {
</h2>
</aside>
<section>
<GridTabs group="portfolio">
<GridTabs>
<GridTab id="positions" name={t('Positions')}>
<div className={tabClassName}>
<h4 className="text-h4 text-black dark:text-white">
@ -56,7 +56,7 @@ const Portfolio = () => {
</section>
</main>
<section className="fixed bottom-0 left-0 w-full h-[200px]">
<GridTabs group="collaterals">
<GridTabs>
<GridTab id="collateral" name={t('Collateral')}>
<AccountsContainer />
</GridTab>

View File

@ -60,7 +60,7 @@ export const CandlesChartContainer = ({
return (
<div className="h-full flex flex-col">
<div className="px-8 flex flex-row flex-wrap gap-8">
<div className="p-8 flex flex-row flex-wrap gap-8">
<DropdownMenu>
<DropdownMenuTrigger asChild={true}>
<Button appendIconName="caret-down" variant="secondary">

View File

@ -50,10 +50,7 @@ export const SelectMarketList = ({
className={`hover:bg-black/20 dark:hover:bg-white/20 cursor-pointer relative`}
>
<td className={`${boldUnderlineClassNames} relative`}>
<Link
href={`/markets/${id}?portfolio=orders&trade=orderbook&chart=candles`}
passHref={true}
>
<Link href={`/markets/${id}`} passHref={true}>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
onClick={() => onSelect(id)}

View File

@ -56,9 +56,7 @@ export const MarketsContainer = () => {
<MarketListTable
ref={gridRef}
data={data}
onRowClicked={(id) =>
push(`/markets/${id}?portfolio=orders&trade=orderbook`)
}
onRowClicked={(id) => push(`/markets/${id}`)}
/>
</AsyncRenderer>
);