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:
parent
ca3a2905dd
commit
be3b416176
@ -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');
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ const mockMarkets = () => {
|
||||
Then('I navigate to markets page', () => {
|
||||
mockMarkets();
|
||||
marketsPage.navigateToMarkets();
|
||||
marketsPage.clickOpenMarketMenu();
|
||||
cy.wait('@Markets');
|
||||
});
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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}>
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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)}
|
||||
|
@ -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>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user