diff --git a/apps/simple-trading-app-e2e/src/integration/market-list.test.ts b/apps/simple-trading-app-e2e/src/integration/market-list.test.ts
index 4aa744942..0c965291c 100644
--- a/apps/simple-trading-app-e2e/src/integration/market-list.test.ts
+++ b/apps/simple-trading-app-e2e/src/integration/market-list.test.ts
@@ -1,11 +1,14 @@
describe('market list', () => {
describe('simple url', () => {
- beforeEach(() => cy.visit('/markets'));
+ beforeEach(() => {
+ cy.visit('/markets');
+ });
it('selects menus', () => {
cy.get('.MuiDrawer-root [aria-current]').should('have.text', 'Markets');
- cy.get('select[name="states"]').should('have.value', 'Active');
- cy.get('[data-testid="market-assets-menu"] button.font-bold').should(
+ cy.getByTestId('state-trigger').should('have.text', 'Active');
+ cy.get('[aria-label="Future"]').click();
+ cy.get('[data-testid="market-assets-menu"] a.active').should(
'have.text',
'All'
);
@@ -14,9 +17,12 @@ describe('market list', () => {
it('navigation should make possibly shortest url', () => {
cy.location('pathname').should('equal', '/markets');
- cy.get('select[name="states"]').select('All');
+ cy.getByTestId('state-trigger').click();
+ cy.get('[role=menuitemcheckbox]').contains('All').click();
cy.location('pathname').should('equal', '/markets/all');
+ cy.get('[aria-label="Future"]').click();
+ cy.location('pathname').should('eq', '/markets/all/Future');
let asset = '';
cy.getByTestId('market-assets-menu')
.children()
@@ -25,25 +31,18 @@ describe('market list', () => {
asset = children[1].innerText;
if (asset) {
cy.wrap(children[1]).click();
- cy.location('pathname').should('equal', `/markets/all/${asset}`);
+ cy.location('pathname').should(
+ 'match',
+ new RegExp(`/markets/all/Future/${asset}`, 'i')
+ );
+ cy.get('a').contains('All Markets').click();
+ cy.location('pathname').should('eq', '/markets/all');
}
}
});
- if (asset) {
- cy.get('button').contains('Future').click();
- cy.location('pathname').should('equal', `/markets/all/${asset}/Future`);
- cy.get('button').contains('All Markets').click();
- cy.location('pathname').should('equal', `/markets/all/${asset}`);
- }
- cy.getByTestId('market-assets-menu')
- .children()
- .find('button')
- .contains('All')
- .click();
- cy.location('pathname').should('equal', '/markets/all');
-
- cy.get('select[name="states"]').select('Active');
+ cy.getByTestId('state-trigger').click();
+ cy.get('[role=menuitemcheckbox]').contains('Active').click();
cy.location('pathname').should('equal', '/markets');
});
});
@@ -51,20 +50,29 @@ describe('market list', () => {
describe('url params should select filters', () => {
it('suspended status', () => {
cy.visit('/markets/Suspended');
- cy.get('select[name="states"]').should('have.value', 'Suspended');
+ cy.getByTestId('state-trigger').should('have.text', 'Suspended');
});
- it('tBTC asset', () => {
- cy.visit('/markets/Suspended/tBTC');
- cy.getByTestId('market-assets-menu')
- .find('button.font-bold')
- .should('have.text', 'tBTC');
+ it('last asset (if exists)', () => {
+ cy.intercept('POST', '/query').as('Filters');
+ cy.visit('/markets');
+ cy.wait('@Filters').then((filters) => {
+ if (filters?.response?.body.data.markets.length) {
+ const asset =
+ filters.response.body.data.markets[0].tradableInstrument.instrument
+ .product.settlementAsset.symbol;
+ cy.visit(`/markets/Suspended/Future/${asset}`);
+ cy.getByTestId('market-assets-menu')
+ .find('a.active')
+ .should('have.text', asset);
+ }
+ });
});
it('Future product', () => {
- cy.visit('/markets/Suspended/tBTC/Future');
+ cy.visit('/markets/Suspended/Future');
cy.getByTestId('market-products-menu')
- .find('button.active')
+ .find('a.active')
.should('have.text', 'Future');
});
});
diff --git a/apps/simple-trading-app/src/app/components/drawer/drawer.tsx b/apps/simple-trading-app/src/app/components/drawer/drawer.tsx
index fcf2d9e5d..552098b4b 100644
--- a/apps/simple-trading-app/src/app/components/drawer/drawer.tsx
+++ b/apps/simple-trading-app/src/app/components/drawer/drawer.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { theme } from '@vegaprotocol/tailwindcss-config';
+import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import type { ReactElement } from 'react';
import { useEffect } from 'react';
import Drawer from '@mui/material/Drawer';
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.spec.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.spec.tsx
index 03ad76d3b..3268c1f96 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.spec.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.spec.tsx
@@ -3,6 +3,7 @@ import { act } from 'react-dom/test-utils';
import { render, screen, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing';
+import { BrowserRouter } from 'react-router-dom';
import { MarketState } from '@vegaprotocol/types';
import SimpleMarketList from './simple-market-list';
import { FILTERS_QUERY, MARKETS_QUERY } from './data-provider';
@@ -54,7 +55,8 @@ describe('SimpleMarketList', () => {
render(
-
+ ,
+ { wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
@@ -122,7 +124,8 @@ describe('SimpleMarketList', () => {
render(
-
+ ,
+ { wrapper: BrowserRouter }
);
await new Promise((resolve) => setTimeout(resolve, 0));
});
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx
index 48f81c801..831470e8d 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx
@@ -68,7 +68,7 @@ const SimpleMarketList = () => {
>
{localData?.map((market) => (
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx
index 64db3a61a..0e6d4e733 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
-import { theme } from '@vegaprotocol/tailwindcss-config';
+import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import { MockedProvider } from '@apollo/react-testing';
import SimpleMarketPercentChange from './simple-market-percent-change';
import type { SimpleMarkets_markets_candles } from './__generated__/SimpleMarkets';
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx
index ac8efb5f5..e4c094736 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx
@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { InView } from 'react-intersection-observer';
import { useSubscription } from '@apollo/client';
-import { theme } from '@vegaprotocol/tailwindcss-config';
+import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import type { SimpleMarkets_markets_candles } from './__generated__/SimpleMarkets';
import type {
CandleLive,
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.spec.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.spec.tsx
index 7bcb70b80..bfd803bdb 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.spec.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.spec.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { act } from 'react-dom/test-utils';
+import { useLocation, useRoutes, BrowserRouter } from 'react-router-dom';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/react-testing';
import SimpleMarketToolbar from './simple-market-toolbar';
@@ -8,14 +8,6 @@ import type { MarketFilters } from './__generated__/MarketFilters';
import { FILTERS_QUERY } from './data-provider';
import filterData from './mocks/market-filters.json';
-const mockedNavigate = jest.fn();
-
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useNavigate: () => mockedNavigate,
- useParams: () => ({}),
-}));
-
describe('SimpleMarketToolbar', () => {
const filterMock: MockedResponse
= {
request: {
@@ -26,58 +18,105 @@ describe('SimpleMarketToolbar', () => {
},
};
+ const WrappedCompForTest = () => {
+ const routes = useRoutes([
+ {
+ path: '/',
+ element: ,
+ },
+ {
+ path: 'markets',
+ children: [
+ {
+ path: `:state`,
+ element: ,
+ children: [
+ {
+ path: `:product`,
+ element: ,
+ children: [
+ { path: `:asset`, element: },
+ ],
+ },
+ ],
+ },
+ ],
+ element: ,
+ },
+ ]);
+ const location = useLocation();
+ return (
+ <>
+ {routes}
+ {location.pathname}
+ >
+ );
+ };
+
afterEach(() => {
jest.resetAllMocks();
});
it('should be properly rendered', async () => {
- await act(async () => {
- render(
-
-
-
- );
- await new Promise((resolve) => setTimeout(resolve, 0));
- });
+ render(
+
+
+ ,
+ { wrapper: BrowserRouter }
+ );
await waitFor(() => {
- expect(screen.getByTestId('market-assets-menu')).toBeInTheDocument();
+ expect(screen.getByText('Future')).toBeInTheDocument();
+ });
+ fireEvent.click(screen.getByText('Future'));
+ await waitFor(() => {
+ expect(screen.getByTestId('market-products-menu').children).toHaveLength(
+ 3
+ );
+ expect(screen.getByTestId('market-assets-menu').children).toHaveLength(6);
+ });
+ fireEvent.click(screen.getByTestId('state-trigger'));
+ waitFor(() => {
+ expect(screen.getByRole('menu')).toBeInTheDocument();
+ expect(screen.getByRole('menu').children).toHaveLength(10);
});
- expect(screen.getByTestId('market-products-menu').children).toHaveLength(3);
- expect(screen.getByTestId('market-assets-menu').children).toHaveLength(6);
- expect(screen.getByRole('combobox').children).toHaveLength(10);
});
it('navigation should work well', async () => {
- await act(async () => {
- render(
-
-
-
- );
- await new Promise((resolve) => setTimeout(resolve, 0));
- });
- await waitFor(() => {
- expect(screen.getByTestId('market-assets-menu')).toBeInTheDocument();
- });
- fireEvent.click(
- screen
- .getByTestId('market-products-menu')
- .children[1].querySelector('button') as HTMLButtonElement
+ render(
+
+
+ ,
+ { wrapper: BrowserRouter }
);
- expect(mockedNavigate).toHaveBeenCalledWith('/markets/Active/all/Future');
+
+ await waitFor(() => {
+ expect(screen.getByText('Future')).toBeInTheDocument();
+ });
+ fireEvent.click(screen.getByText('Future'));
+ await waitFor(() => {
+ expect(screen.getByTestId('location-display')).toHaveTextContent(
+ '/markets/Active/Future'
+ );
+ });
fireEvent.click(
screen
.getByTestId('market-assets-menu')
- .children[5].querySelector('button') as HTMLButtonElement
+ .children[5].querySelector('a') as HTMLAnchorElement
);
- expect(mockedNavigate).toHaveBeenCalledWith('/markets/Active/tEURO/Future');
-
- fireEvent.change(screen.getByRole('combobox'), {
- target: { value: 'Pending' },
+ await waitFor(() => {
+ expect(screen.getByTestId('location-display')).toHaveTextContent(
+ '/markets/Active/Future/tEURO'
+ );
+ });
+
+ fireEvent.click(screen.getByTestId('state-trigger'));
+ waitFor(() => {
+ expect(screen.getByRole('menu')).toBeInTheDocument();
+ fireEvent.click(screen.getByText('Pending'));
+ expect(screen.getByTestId('location-display')).toHaveTextContent(
+ '/markets/Pending/Future/tEURO'
+ );
});
- expect(mockedNavigate).toHaveBeenCalledWith(
- '/markets/Pending/tEURO/Future'
- );
});
});
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx
index 5831f73f3..c250871aa 100644
--- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx
+++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx
@@ -1,38 +1,41 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
+import { useNavigate, useParams, Link } from 'react-router-dom';
+import {
+ DropdownMenu,
+ DropdownMenuTrigger,
+} from '@radix-ui/react-dropdown-menu';
+import { IconNames } from '@blueprintjs/icons';
import { t } from '@vegaprotocol/react-helpers';
-import { theme } from '@vegaprotocol/tailwindcss-config';
-import { useNavigate, useParams } from 'react-router-dom';
-import { Button, Select } from '@vegaprotocol/ui-toolkit';
+import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
+import {
+ DropdownMenuCheckboxItem,
+ DropdownMenuContent,
+ DropdownMenuItemIndicator,
+ Icon,
+} from '@vegaprotocol/ui-toolkit';
import useMarketFiltersData from '../../hooks/use-markets-filter';
import { STATES_FILTER } from './constants';
const SimpleMarketToolbar = () => {
const navigate = useNavigate();
const params = useParams();
- const { assets, products, assetsPerProduct } = useMarketFiltersData();
+ const { products, assetsPerProduct } = useMarketFiltersData();
+ const [isOpen, setOpen] = useState(false);
const [activeNumber, setActiveNumber] = useState(
products?.length ? products.indexOf(params.product || '') + 1 : -1
);
- const [activeAsset, setActiveAsset] = useState(params.asset || 'all');
- const [activeState, setActiveState] = useState(params.state || 'Active');
+
const [sliderStyles, setSliderStyles] = useState>({});
const slideContRef = useRef(null);
- const onStateChange = useCallback(
- (e: React.ChangeEvent) => {
- setActiveState(e.target.value);
- },
- [setActiveState]
- );
-
useEffect(() => {
- // handle corner case when there is product
- // param, but no products yet
- if (activeNumber < 0 && products?.length) {
- setActiveNumber(products.indexOf(params.product || '') + 1 || 0);
+ if (products.length) {
+ setActiveNumber(products.indexOf(params.product || '') + 1);
+ } else {
+ setActiveNumber(-1);
}
- }, [activeNumber, setActiveNumber, products, params]);
+ }, [params, products, setActiveNumber]);
useEffect(() => {
const contStyles = (
@@ -43,7 +46,7 @@ const SimpleMarketToolbar = () => {
]?.getBoundingClientRect();
const styles: Record = selectedStyles
? {
- backgroundColor: activeNumber ? '' : theme.colors.coral,
+ backgroundColor: activeNumber ? '' : theme.colors.pink,
width: `${selectedStyles.width}px`,
left: `${selectedStyles.left - contStyles.left}px`,
}
@@ -51,42 +54,55 @@ const SimpleMarketToolbar = () => {
setSliderStyles(styles);
}, [activeNumber, slideContRef]);
- useEffect(() => {
- if (activeNumber < 0) {
- return;
- }
- const product = activeNumber ? `/${products[activeNumber - 1]}` : '';
- const asset = activeAsset !== 'all' || product ? `/${activeAsset}` : '';
- const state = activeState !== 'Active' || asset ? `/${activeState}` : '';
- navigate(`/markets${state}${asset}${product}`);
- }, [activeNumber, activeAsset, activeState, products, navigate]);
+ const onStateChange = useCallback(
+ (activeState: string) => {
+ const asset =
+ params.asset && params.asset !== 'all' ? `/${params.asset}` : '';
+ const product = params.product ? `/${params.product}` : '';
+ const state =
+ activeState !== 'Active' || product ? `/${activeState}` : '';
+ navigate(`/markets${state}${product}${asset}`);
+ },
+ [params, navigate]
+ );
return (
-
+
- -
-
+
{products.map((product, i) => (
-
-
+
))}
- {
/>
-
-
-
-
|
-
- -
-
+ {t('All')}
+
- ))}
-
+ {assetsPerProduct[products[activeNumber - 1]]?.map((asset) => (
+
+
+ {asset}
+
+
+ ))}
+
+ )}
);
diff --git a/apps/simple-trading-app/src/app/hooks/use-markets-filter.ts b/apps/simple-trading-app/src/app/hooks/use-markets-filter.ts
index 2b1bd687b..7b636e1bb 100644
--- a/apps/simple-trading-app/src/app/hooks/use-markets-filter.ts
+++ b/apps/simple-trading-app/src/app/hooks/use-markets-filter.ts
@@ -4,7 +4,6 @@ import { FILTERS_QUERY } from '../components/simple-market-list/data-provider';
import type { MarketFilters } from '../components/simple-market-list/__generated__/MarketFilters';
const useMarketFilters = () => {
- const [assets, setAssets] = useState
([]);
const [products, setProducts] = useState([]);
const [assetsPerProduct, setAssetsPerProduct] = useState<
Record
@@ -14,7 +13,6 @@ const useMarketFilters = () => {
});
useEffect(() => {
const localProducts = new Set();
- const localAssets = new Set();
const localAssetPerProduct: Record> = {};
data?.markets?.forEach((item) => {
const product = item.tradableInstrument.instrument.product.__typename;
@@ -25,9 +23,7 @@ const useMarketFilters = () => {
}
localAssetPerProduct[product].add(asset);
localProducts.add(product);
- localAssets.add(asset);
});
- setAssets([...localAssets]);
setProducts([...localProducts]);
setAssetsPerProduct(
Object.entries(localAssetPerProduct).reduce(
@@ -39,7 +35,7 @@ const useMarketFilters = () => {
)
);
}, [data]);
- return { assets, products, assetsPerProduct };
+ return { products, assetsPerProduct };
};
export default useMarketFilters;
diff --git a/apps/simple-trading-app/src/app/routes/router-config.tsx b/apps/simple-trading-app/src/app/routes/router-config.tsx
index 59b66b55f..3458cea79 100644
--- a/apps/simple-trading-app/src/app/routes/router-config.tsx
+++ b/apps/simple-trading-app/src/app/routes/router-config.tsx
@@ -26,9 +26,9 @@ export const routerConfig = [
element: ,
children: [
{
- path: `:asset`,
+ path: `:product`,
element: ,
- children: [{ path: `:product`, element: }],
+ children: [{ path: `:asset`, element: }],
},
],
},
diff --git a/apps/simple-trading-app/tailwind.config.js b/apps/simple-trading-app/tailwind.config.js
index 51ca67ff2..d2fb3eb3d 100644
--- a/apps/simple-trading-app/tailwind.config.js
+++ b/apps/simple-trading-app/tailwind.config.js
@@ -1,6 +1,6 @@
const { join } = require('path');
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
-const theme = require('../../libs/tailwindcss-config/src/theme');
+const theme = require('../../libs/tailwindcss-config/src/theme-lite');
const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes');
module.exports = {
diff --git a/apps/token/src/routes/governance/components/vote-details/vote-buttons.tsx b/apps/token/src/routes/governance/components/vote-details/vote-buttons.tsx
index 7e9f54682..e8d70992a 100644
--- a/apps/token/src/routes/governance/components/vote-details/vote-buttons.tsx
+++ b/apps/token/src/routes/governance/components/vote-details/vote-buttons.tsx
@@ -145,7 +145,6 @@ export const VoteButtons = ({
{proposalState === ProposalState.Open ? (
{
setChangeVote(true);
}}
diff --git a/libs/tailwindcss-config/src/index.js b/libs/tailwindcss-config/src/index.js
index c7c7a09b6..aea0e9677 100644
--- a/libs/tailwindcss-config/src/index.js
+++ b/libs/tailwindcss-config/src/index.js
@@ -1,7 +1,9 @@
const theme = require('./theme');
+const themelite = require('./theme-lite');
const vegaCustomClasses = require('./vega-custom-classes');
module.exports = {
theme,
+ themelite,
plugins: [vegaCustomClasses],
};
diff --git a/libs/tailwindcss-config/src/theme-lite.js b/libs/tailwindcss-config/src/theme-lite.js
new file mode 100644
index 000000000..a18b56303
--- /dev/null
+++ b/libs/tailwindcss-config/src/theme-lite.js
@@ -0,0 +1,19 @@
+const theme = require('./theme');
+
+module.exports = {
+ ...theme,
+ colors: {
+ ...theme.colors,
+ offBlack: '#252525',
+ midGrey: '#828282',
+ borderGrey: '#4f4f4f',
+ lightGrey: '#F2F2F2',
+ yellow: '#DFFF0B',
+ mint: '#00F780',
+ pink: '#FF077F',
+ },
+ fontSize: {
+ ...theme.fontSize,
+ capMenu: ['15px', { lineHeight: '24px', letterSpacing: '-0.01em' }],
+ },
+};