* chore: make liquidity page client side only * chore: switch to hash based router * chore: add index files for each page * chore: tidy up _app * chore: convert to use useRoutes * fix: active state with react-router NavLink * feat: add routes enum * chore: restrict link and router imports from next * chore: update testing navigation to use hash routes * fix: typoe in eslint rule message * chore: remove unnecessary getInitialProps function definition * chore: wrap tests with memory router * chore: delete unused index.page file * chore: update suspense fallback state * chore: add comment for link component span usage, update link to use toolkit styles * chore: fix lint issues * chore: delete client deposit page * chore: revert title in _app so title gets set correctly without rerender * revert: removal of deposit page so deposit e2e tests still pass * chore: move client router to index page so valid status codes are still sent * fix: wrong route path for markets page, cypress tests
This commit is contained in:
parent
8542f6c5d8
commit
c576037b58
@ -9,7 +9,7 @@ describe('deposit form validation', { tags: '@smoke' }, () => {
|
|||||||
cy.mockWeb3Provider();
|
cy.mockWeb3Provider();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/portfolio/deposit');
|
cy.visit('/#/portfolio/deposit');
|
||||||
|
|
||||||
// Deposit page requires connection Ethereum wallet first
|
// Deposit page requires connection Ethereum wallet first
|
||||||
cy.getByTestId(connectEthWalletBtn).click();
|
cy.getByTestId(connectEthWalletBtn).click();
|
||||||
|
@ -11,10 +11,10 @@ describe('vega wallet', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Using portfolio page as it requires vega wallet connection
|
// Using portfolio page as it requires vega wallet connection
|
||||||
cy.visit('/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.get('main[data-testid="portfolio"]').should('exist');
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can connect', () => {
|
it('can connect', () => {
|
||||||
@ -79,12 +79,12 @@ describe('ethereum wallet', { tags: '@smoke' }, () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockWeb3Provider();
|
cy.mockWeb3Provider();
|
||||||
// Using portfolio withdrawals tab is it requires Ethereum wallet connection
|
// Using portfolio withdrawals tab is it requires Ethereum wallet connection
|
||||||
cy.visit('/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasQuery(req, 'NetworkParams', generateNetworkParameters());
|
aliasQuery(req, 'NetworkParams', generateNetworkParameters());
|
||||||
});
|
});
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.get('main[data-testid="portfolio"]').should('exist');
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
cy.getByTestId('Withdrawals').click();
|
cy.getByTestId('Withdrawals').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,7 +14,9 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
|
|
||||||
cy.get('main[data-testid="market"]', { timeout: 20000 }).should('exist'); // Wait for page to be rendered to before checking url
|
cy.get('main', { timeout: 20000 }).then((el) => {
|
||||||
|
expect(el.attr('data-testid')?.startsWith('/market')).to.equal(true);
|
||||||
|
}); // Wait for page to be rendered to before checking url
|
||||||
|
|
||||||
// Overlay should be shown
|
// Overlay should be shown
|
||||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||||
@ -45,7 +47,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
// the choose market overlay is no longer showing
|
// the choose market overlay is no longer showing
|
||||||
cy.contains('Select a market to get started').should('not.exist');
|
cy.contains('Select a market to get started').should('not.exist');
|
||||||
cy.contains('Loading...').should('not.exist');
|
cy.contains('Loading...').should('not.exist');
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/markets/market-0');
|
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-0');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,7 +67,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');
|
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,9 @@ describe('Console - market list - live env', { tags: '@live' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('shows the market list page', () => {
|
it('shows the market list page', () => {
|
||||||
cy.get('main[data-testid="market"]', { timeout: 20000 }).should('exist'); // Wait for page to be rendered to before checking url
|
cy.get('main', { timeout: 20000 }).then((el) => {
|
||||||
|
expect(el.attr('data-testid')?.startsWith('/market')).to.equal(true);
|
||||||
|
}); // Wait for page to be rendered to before checking url
|
||||||
|
|
||||||
// Overlay should be shown
|
// Overlay should be shown
|
||||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||||
|
@ -10,7 +10,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
cy.getByTestId(marketInfoBtn).click();
|
cy.getByTestId(marketInfoBtn).click();
|
||||||
cy.wait('@MarketInfo');
|
cy.wait('@MarketInfo');
|
||||||
@ -222,7 +222,7 @@ describe('market states', { tags: '@smoke' }, function () {
|
|||||||
before(function () {
|
before(function () {
|
||||||
cy.mockTradingPage(marketState);
|
cy.mockTradingPage(marketState);
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ describe('Market trading page', () => {
|
|||||||
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
||||||
);
|
);
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@MarketData');
|
cy.wait('@MarketData');
|
||||||
cy.getByTestId(marketSummaryBlock).should('be.visible');
|
cy.getByTestId(marketSummaryBlock).should('be.visible');
|
||||||
});
|
});
|
||||||
|
@ -53,9 +53,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')
|
||||||
.click();
|
.click();
|
||||||
cy.url().should('eq', Cypress.config('baseUrl') + '/markets');
|
cy.url().should('eq', Cypress.config('baseUrl') + '/#/markets');
|
||||||
cy.contains('AAPL.MF21').should('be.visible');
|
cy.contains('AAPL.MF21').should('be.visible');
|
||||||
cy.contains('Market').click(); // sort by market name
|
cy.contains('Market').click(); // sort by market name
|
||||||
for (let i = 0; i < ExpectedSortedMarkets.length; i++) {
|
for (let i = 0; i < ExpectedSortedMarkets.length; i++) {
|
||||||
|
@ -5,7 +5,7 @@ beforeEach(() => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockWeb3Provider();
|
cy.mockWeb3Provider();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('accounts', { tags: '@smoke' }, () => {
|
describe('accounts', { tags: '@smoke' }, () => {
|
||||||
|
@ -126,7 +126,7 @@ describe('must submit order', { tags: '@smoke' }, () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
});
|
});
|
||||||
@ -205,7 +205,7 @@ describe('must submit order', { tags: '@smoke' }, () => {
|
|||||||
describe('deal ticket validation', { tags: '@smoke' }, () => {
|
describe('deal ticket validation', { tags: '@smoke' }, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ describe('deal ticket validation', { tags: '@smoke' }, () => {
|
|||||||
describe('deal ticket size validation', { tags: '@smoke' }, function () {
|
describe('deal ticket size validation', { tags: '@smoke' }, function () {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
});
|
});
|
||||||
@ -284,7 +284,7 @@ describe('deal ticket size validation', { tags: '@smoke' }, function () {
|
|||||||
describe('limit order validations', { tags: '@smoke' }, () => {
|
describe('limit order validations', { tags: '@smoke' }, () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
cy.getByTestId(toggleLimit).click();
|
cy.getByTestId(toggleLimit).click();
|
||||||
});
|
});
|
||||||
@ -358,7 +358,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
|
|||||||
describe('market order validations', { tags: '@smoke' }, () => {
|
describe('market order validations', { tags: '@smoke' }, () => {
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
cy.getByTestId(toggleMarket).click();
|
cy.getByTestId(toggleMarket).click();
|
||||||
});
|
});
|
||||||
@ -413,7 +413,7 @@ describe('suspended market validation', { tags: '@regression' }, () => {
|
|||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||||
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
||||||
);
|
);
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
});
|
});
|
||||||
@ -464,7 +464,7 @@ describe('margin required validation', { tags: '@regression' }, () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
});
|
});
|
||||||
|
@ -12,8 +12,8 @@ describe('fills', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders fills on portfolio page', () => {
|
it('renders fills on portfolio page', () => {
|
||||||
cy.visit('/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
cy.get('main[data-testid="portfolio"]').should('exist');
|
cy.get('main[data-testid="/portfolio"]').should('exist');
|
||||||
cy.getByTestId('Fills').click();
|
cy.getByTestId('Fills').click();
|
||||||
cy.getByTestId('tab-fills').contains('Connect your Vega wallet');
|
cy.getByTestId('tab-fills').contains('Connect your Vega wallet');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
@ -22,7 +22,7 @@ describe('fills', { tags: '@regression' }, () => {
|
|||||||
|
|
||||||
it('renders fills on trading tab', () => {
|
it('renders fills on trading tab', () => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.getByTestId('Fills').click();
|
cy.getByTestId('Fills').click();
|
||||||
cy.getByTestId('tab-fills').contains('Please connect Vega wallet');
|
cy.getByTestId('tab-fills').contains('Please connect Vega wallet');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
|
@ -23,7 +23,7 @@ describe('orders list', { tags: '@smoke' }, () => {
|
|||||||
cy.spy(subscriptionMocks, 'OrdersUpdate');
|
cy.spy(subscriptionMocks, 'OrdersUpdate');
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription(subscriptionMocks);
|
cy.mockGQLSubscription(subscriptionMocks);
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.getByTestId('Orders').click();
|
cy.getByTestId('Orders').click();
|
||||||
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
@ -127,7 +127,7 @@ describe('subscribe orders', { tags: '@smoke' }, () => {
|
|||||||
cy.spy(subscriptionMocks, 'OrdersUpdate');
|
cy.spy(subscriptionMocks, 'OrdersUpdate');
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription(subscriptionMocks);
|
cy.mockGQLSubscription(subscriptionMocks);
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.getByTestId('Orders').click();
|
cy.getByTestId('Orders').click();
|
||||||
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
|
@ -8,7 +8,7 @@ beforeEach(() => {
|
|||||||
|
|
||||||
describe('positions', { tags: '@smoke' }, () => {
|
describe('positions', { tags: '@smoke' }, () => {
|
||||||
it('renders positions on trading page', () => {
|
it('renders positions on trading page', () => {
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.getByTestId('Positions').click();
|
cy.getByTestId('Positions').click();
|
||||||
cy.getByTestId('tab-positions').contains('Please connect Vega wallet');
|
cy.getByTestId('tab-positions').contains('Please connect Vega wallet');
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ describe('positions', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders positions on portfolio page', () => {
|
it('renders positions on portfolio page', () => {
|
||||||
cy.visit('/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
connectVegaWallet();
|
connectVegaWallet();
|
||||||
validatePositionsDisplayed();
|
validatePositionsDisplayed();
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('trades', { tags: '@smoke' }, () => {
|
describe('trades', { tags: '@smoke' }, () => {
|
||||||
|
@ -17,7 +17,7 @@ describe('withdraw', { tags: '@smoke' }, () => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockGQLSubscription();
|
cy.mockGQLSubscription();
|
||||||
|
|
||||||
cy.visit('/portfolio');
|
cy.visit('/#/portfolio');
|
||||||
cy.getByTestId('Withdrawals').click();
|
cy.getByTestId('Withdrawals').click();
|
||||||
|
|
||||||
// Withdraw page requires vega wallet connection
|
// Withdraw page requires vega wallet connection
|
||||||
|
@ -10,7 +10,18 @@
|
|||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"@next/next/no-html-link-for-pages": ["error", "apps/trading/pages"]
|
"@next/next/no-html-link-for-pages": ["error", "apps/trading/pages"],
|
||||||
|
"no-restricted-imports": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"name": "next/link",
|
||||||
|
"message": "Please Link from react-router-dom instead"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "next/router",
|
||||||
|
"message": "Please use routing hooks from react-router-dom instead"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
38
apps/trading/client-pages/deposit/deposit-container.tsx
Normal file
38
apps/trading/client-pages/deposit/deposit-container.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { DepositManager } from '@vegaprotocol/deposits';
|
||||||
|
import { useDataProvider, t } from '@vegaprotocol/react-helpers';
|
||||||
|
import { enabledAssetsProvider } from '@vegaprotocol/assets';
|
||||||
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
|
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches data required for the Deposit page
|
||||||
|
*/
|
||||||
|
export const DepositContainer = () => {
|
||||||
|
const { VEGA_ENV } = useEnvironment();
|
||||||
|
const { data, error, loading } = useDataProvider({
|
||||||
|
dataProvider: enabledAssetsProvider,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<AsyncRenderer
|
||||||
|
data={data}
|
||||||
|
error={error}
|
||||||
|
loading={loading}
|
||||||
|
render={(assets) => {
|
||||||
|
if (!assets || !assets.length) {
|
||||||
|
return (
|
||||||
|
<Splash>
|
||||||
|
<p>{t('No assets on this network')}</p>
|
||||||
|
</Splash>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DepositManager
|
||||||
|
assets={assets}
|
||||||
|
isFaucetable={VEGA_ENV !== 'MAINNET'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
@ -5,9 +5,9 @@ import { t, titlefy, useDataProvider } from '@vegaprotocol/react-helpers';
|
|||||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Web3Container } from '@vegaprotocol/web3';
|
import { Web3Container } from '@vegaprotocol/web3';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { usePageTitleStore } from '../../../stores';
|
import { usePageTitleStore } from '../../stores';
|
||||||
|
|
||||||
const Deposit = () => {
|
export const Deposit = () => {
|
||||||
const { updateTitle } = usePageTitleStore((store) => ({
|
const { updateTitle } = usePageTitleStore((store) => ({
|
||||||
updateTitle: store.updateTitle,
|
updateTitle: store.updateTitle,
|
||||||
}));
|
}));
|
||||||
@ -50,9 +50,3 @@ const Deposit = () => {
|
|||||||
</Web3Container>
|
</Web3Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Deposit.getInitialProps = () => ({
|
|
||||||
page: 'deposit',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Deposit;
|
|
3
apps/trading/client-pages/deposit/index.ts
Normal file
3
apps/trading/client-pages/deposit/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Deposit } from './deposit';
|
||||||
|
|
||||||
|
export default Deposit;
|
63
apps/trading/client-pages/home/home.tsx
Normal file
63
apps/trading/client-pages/home/home.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
||||||
|
import {
|
||||||
|
addDecimalsFormatNumber,
|
||||||
|
titlefy,
|
||||||
|
useDataProvider,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||||
|
|
||||||
|
export const Home = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
// The default market selected in the platform behind the overlay
|
||||||
|
// should be the oldest market that is currently trading in us mode(i.e. not in auction).
|
||||||
|
const { data, error, loading } = useDataProvider({
|
||||||
|
dataProvider: marketsWithDataProvider,
|
||||||
|
});
|
||||||
|
const { riskNoticeDialog, update } = useGlobalStore((store) => ({
|
||||||
|
riskNoticeDialog: store.riskNoticeDialog,
|
||||||
|
update: store.update,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const { pageTitle, updateTitle } = usePageTitleStore((store) => ({
|
||||||
|
pageTitle: store.pageTitle,
|
||||||
|
updateTitle: store.updateTitle,
|
||||||
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
update({ landingDialog: true });
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
const marketId = data[0]?.id;
|
||||||
|
const marketName = data[0]?.tradableInstrument.instrument.name;
|
||||||
|
const marketPrice = data[0]?.data?.markPrice
|
||||||
|
? addDecimalsFormatNumber(
|
||||||
|
data[0]?.data?.markPrice,
|
||||||
|
data[0]?.decimalPlaces
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
const newPageTitle = titlefy([marketName, marketPrice]);
|
||||||
|
|
||||||
|
if (marketId) {
|
||||||
|
navigate(`/markets/${marketId}`, { replace: true });
|
||||||
|
update({ marketId });
|
||||||
|
if (pageTitle !== newPageTitle) {
|
||||||
|
updateTitle(newPageTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback to the markets list page
|
||||||
|
else {
|
||||||
|
navigate('/markets');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [data, navigate, riskNoticeDialog, update, pageTitle, updateTitle]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AsyncRenderer data={data} loading={loading} error={error}>
|
||||||
|
{/* Render a loading and error state but we will redirect if markets are found */}
|
||||||
|
{null}
|
||||||
|
</AsyncRenderer>
|
||||||
|
);
|
||||||
|
};
|
3
apps/trading/client-pages/home/index.ts
Normal file
3
apps/trading/client-pages/home/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Home } from './home';
|
||||||
|
|
||||||
|
export default Home;
|
3
apps/trading/client-pages/liquidity/index.ts
Normal file
3
apps/trading/client-pages/liquidity/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Liquidity } from './liquidity';
|
||||||
|
|
||||||
|
export default Liquidity;
|
@ -15,28 +15,25 @@ import {
|
|||||||
import { Schema } from '@vegaprotocol/types';
|
import { Schema } from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
AsyncRenderer,
|
AsyncRenderer,
|
||||||
Link as UiToolkitLink,
|
|
||||||
Tab,
|
Tab,
|
||||||
Tabs,
|
Tabs,
|
||||||
|
Link as UiToolkitLink,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import Link from 'next/link';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import { Header, HeaderStat } from '../../components/header';
|
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';
|
||||||
|
|
||||||
const LiquidityPage = ({ id }: { id?: string }) => {
|
export const Liquidity = () => {
|
||||||
const { query } = useRouter();
|
const params = useParams();
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
|
|
||||||
// Default to first marketId query item if found
|
const marketId = params.marketId;
|
||||||
const marketId =
|
|
||||||
id || (Array.isArray(query.marketId) ? query.marketId[0] : query.marketId);
|
|
||||||
|
|
||||||
const { data: marketProvision } = useDataProvider({
|
const { data: marketProvision } = useDataProvider({
|
||||||
dataProvider: marketLiquidityDataProvider,
|
dataProvider: marketLiquidityDataProvider,
|
||||||
@ -139,7 +136,7 @@ const LiquidityPage = ({ id }: { id?: string }) => {
|
|||||||
<div className="h-full grid grid-rows-[min-content_1fr]">
|
<div className="h-full grid grid-rows-[min-content_1fr]">
|
||||||
<Header
|
<Header
|
||||||
title={
|
title={
|
||||||
<Link href={`/markets/${marketId}`} passHref={true}>
|
<Link to={`/markets/${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
|
||||||
@ -223,8 +220,3 @@ const LiquidityPage = ({ id }: { id?: string }) => {
|
|||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
LiquidityPage.getInitialProps = () => ({
|
|
||||||
page: 'liquidity',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default LiquidityPage;
|
|
3
apps/trading/client-pages/market/index.ts
Normal file
3
apps/trading/client-pages/market/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Market } from './market';
|
||||||
|
|
||||||
|
export default Market;
|
@ -8,7 +8,6 @@ import {
|
|||||||
useDataProvider,
|
useDataProvider,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import type {
|
import type {
|
||||||
SingleMarketFieldsFragment,
|
SingleMarketFieldsFragment,
|
||||||
MarketData,
|
MarketData,
|
||||||
@ -19,6 +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 { ColumnKind, SelectMarketDialog } from '../../components/select-market';
|
import { ColumnKind, SelectMarketDialog } from '../../components/select-market';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
||||||
return markPrice && decimalPlaces
|
return markPrice && decimalPlaces
|
||||||
@ -31,14 +31,16 @@ export interface SingleMarketData extends SingleMarketFieldsFragment {
|
|||||||
data: MarketData;
|
data: MarketData;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MarketPage = ({
|
export const Market = ({
|
||||||
id,
|
id,
|
||||||
marketId: mid,
|
marketId: mid,
|
||||||
}: {
|
}: {
|
||||||
id?: string;
|
id?: string;
|
||||||
marketId?: string;
|
marketId?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { query, push } = useRouter();
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const marketId = params.marketId;
|
||||||
const { w } = useWindowSize();
|
const { w } = useWindowSize();
|
||||||
const { landingDialog, riskNoticeDialog, update } = useGlobalStore(
|
const { landingDialog, riskNoticeDialog, update } = useGlobalStore(
|
||||||
(store) => ({
|
(store) => ({
|
||||||
@ -55,18 +57,14 @@ const MarketPage = ({
|
|||||||
|
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||||
|
|
||||||
// Default to first marketId query item if found
|
|
||||||
const marketId =
|
|
||||||
id || (Array.isArray(query.marketId) ? query.marketId[0] : query.marketId);
|
|
||||||
|
|
||||||
const onSelect = useCallback(
|
const onSelect = useCallback(
|
||||||
(id: string) => {
|
(id: string) => {
|
||||||
if (id && id !== marketId) {
|
if (id && id !== marketId) {
|
||||||
update({ marketId: id });
|
update({ marketId: id });
|
||||||
push(`/markets/${id}`);
|
navigate(`/markets/${id}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[marketId, update, push]
|
[marketId, update, navigate]
|
||||||
);
|
);
|
||||||
|
|
||||||
const variables = useMemo(
|
const variables = useMemo(
|
||||||
@ -160,12 +158,6 @@ const MarketPage = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
MarketPage.getInitialProps = () => ({
|
|
||||||
page: 'market',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default MarketPage;
|
|
||||||
|
|
||||||
const useWindowSize = () => {
|
const useWindowSize = () => {
|
||||||
const [windowSize, setWindowSize] = useState(() => {
|
const [windowSize, setWindowSize] = useState(() => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
@ -24,7 +24,7 @@ import { t } from '@vegaprotocol/react-helpers';
|
|||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
import { useEnvironment } from '@vegaprotocol/environment';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { Header, HeaderStat } from '../../components/header';
|
import { Header, HeaderStat } from '../../components/header';
|
||||||
import { AccountsContainer } from '../portfolio/accounts-container';
|
import { AccountsContainer } from '../../components/accounts-container';
|
||||||
import {
|
import {
|
||||||
ColumnKind,
|
ColumnKind,
|
||||||
SelectMarketPopover,
|
SelectMarketPopover,
|
3
apps/trading/client-pages/markets/index.ts
Normal file
3
apps/trading/client-pages/markets/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Markets } from './markets';
|
||||||
|
|
||||||
|
export default Markets;
|
@ -1,10 +1,11 @@
|
|||||||
import { useRouter } from 'next/router';
|
|
||||||
import { MarketsContainer } from '@vegaprotocol/market-list';
|
import { MarketsContainer } from '@vegaprotocol/market-list';
|
||||||
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
import { useGlobalStore, usePageTitleStore } from '../../stores';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { titlefy } from '@vegaprotocol/react-helpers';
|
import { titlefy } from '@vegaprotocol/react-helpers';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
const Markets = () => {
|
export const Markets = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const { update } = useGlobalStore((store) => ({ update: store.update }));
|
const { update } = useGlobalStore((store) => ({ update: store.update }));
|
||||||
const { updateTitle } = usePageTitleStore((store) => ({
|
const { updateTitle } = usePageTitleStore((store) => ({
|
||||||
updateTitle: store.updateTitle,
|
updateTitle: store.updateTitle,
|
||||||
@ -12,20 +13,13 @@ const Markets = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateTitle(titlefy(['Markets']));
|
updateTitle(titlefy(['Markets']));
|
||||||
}, [updateTitle]);
|
}, [updateTitle]);
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MarketsContainer
|
<MarketsContainer
|
||||||
onSelect={(marketId) => {
|
onSelect={(marketId) => {
|
||||||
update({ marketId });
|
update({ marketId });
|
||||||
router.push(`/markets/${marketId}`);
|
navigate(`/markets/${marketId}`);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Markets.getInitialProps = () => ({
|
|
||||||
page: 'markets',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Markets;
|
|
3
apps/trading/client-pages/portfolio/index.ts
Normal file
3
apps/trading/client-pages/portfolio/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { Portfolio } from './portfolio';
|
||||||
|
|
||||||
|
export default Portfolio;
|
@ -11,16 +11,18 @@ import { DepositsContainer } from './deposits-container';
|
|||||||
import { ResizableGrid } from '@vegaprotocol/ui-toolkit';
|
import { ResizableGrid } from '@vegaprotocol/ui-toolkit';
|
||||||
import { LayoutPriority } from 'allotment';
|
import { LayoutPriority } from 'allotment';
|
||||||
import { usePageTitleStore } from '../../stores';
|
import { usePageTitleStore } from '../../stores';
|
||||||
import { AccountsContainer } from './accounts-container';
|
|
||||||
import { LedgerContainer } from '@vegaprotocol/ledger';
|
import { LedgerContainer } from '@vegaprotocol/ledger';
|
||||||
|
import { AccountsContainer } from '../../components/accounts-container';
|
||||||
|
|
||||||
const Portfolio = () => {
|
export const Portfolio = () => {
|
||||||
const { updateTitle } = usePageTitleStore((store) => ({
|
const { updateTitle } = usePageTitleStore((store) => ({
|
||||||
updateTitle: store.updateTitle,
|
updateTitle: store.updateTitle,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateTitle(titlefy([t('Portfolio')]));
|
updateTitle(titlefy([t('Portfolio')]));
|
||||||
}, [updateTitle]);
|
}, [updateTitle]);
|
||||||
|
|
||||||
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
||||||
return (
|
return (
|
||||||
<div className={wrapperClasses}>
|
<div className={wrapperClasses}>
|
||||||
@ -79,12 +81,6 @@ const Portfolio = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Portfolio.getInitialProps = () => ({
|
|
||||||
page: 'portfolio',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Portfolio;
|
|
||||||
|
|
||||||
interface PortfolioGridChildProps {
|
interface PortfolioGridChildProps {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
1
apps/trading/components/accounts-container/index.ts
Normal file
1
apps/trading/components/accounts-container/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './accounts-container';
|
@ -1,6 +1,5 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useRouter } from 'next/router';
|
import { NavLink, Link } from 'react-router-dom';
|
||||||
import Link from 'next/link';
|
|
||||||
import { NetworkSwitcher, useEnvironment } from '@vegaprotocol/environment';
|
import { NetworkSwitcher, useEnvironment } 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';
|
||||||
@ -8,8 +7,8 @@ import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
|
|||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { 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 { useEffect, useState } from 'react';
|
|
||||||
import testnetBg from '../../assets/green-cloud.png';
|
import testnetBg from '../../assets/green-cloud.png';
|
||||||
|
import { Routes } from '../../pages/client-router';
|
||||||
|
|
||||||
type NavbarTheme = 'inherit' | 'dark' | 'yellow';
|
type NavbarTheme = 'inherit' | 'dark' | 'yellow';
|
||||||
interface NavbarProps {
|
interface NavbarProps {
|
||||||
@ -27,13 +26,7 @@ export const Navbar = ({
|
|||||||
const { marketId } = useGlobalStore((store) => ({
|
const { marketId } = useGlobalStore((store) => ({
|
||||||
marketId: store.marketId,
|
marketId: store.marketId,
|
||||||
}));
|
}));
|
||||||
const [tradingPath, setTradingPath] = useState('/markets');
|
const tradingPath = marketId ? `/markets/${marketId}` : '/markets';
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (marketId) {
|
|
||||||
setTradingPath(`/markets/${marketId}`);
|
|
||||||
}
|
|
||||||
}, [marketId]);
|
|
||||||
|
|
||||||
const themeWrapperClasses = classNames({
|
const themeWrapperClasses = classNames({
|
||||||
dark: navbarTheme === 'dark',
|
dark: navbarTheme === 'dark',
|
||||||
@ -58,26 +51,23 @@ export const Navbar = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex gap-4 items-center">
|
<div className="flex gap-4 items-center">
|
||||||
<Link href="/" passHref={true}>
|
<Link to="/">
|
||||||
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
<Vega className="w-13" />
|
||||||
<a>
|
|
||||||
<Vega className="w-13" />
|
|
||||||
</a>
|
|
||||||
</Link>
|
</Link>
|
||||||
<NetworkSwitcher />
|
<NetworkSwitcher />
|
||||||
</div>
|
</div>
|
||||||
<nav className="flex items-center flex-1 px-2">
|
<nav className="flex items-center flex-1 px-2">
|
||||||
<NavLink
|
<AppNavLink
|
||||||
name={t('Trading')}
|
name={t('Trading')}
|
||||||
path={tradingPath}
|
path={tradingPath}
|
||||||
navbarTheme={navbarTheme}
|
navbarTheme={navbarTheme}
|
||||||
/>
|
/>
|
||||||
<NavLink
|
<AppNavLink
|
||||||
name={t('Portfolio')}
|
name={t('Portfolio')}
|
||||||
path="/portfolio"
|
path={Routes.PORTFOLIO}
|
||||||
navbarTheme={navbarTheme}
|
navbarTheme={navbarTheme}
|
||||||
/>
|
/>
|
||||||
<NavLink
|
<AppNavLink
|
||||||
name={t('Governance')}
|
name={t('Governance')}
|
||||||
path={`${VEGA_TOKEN_URL}/governance`}
|
path={`${VEGA_TOKEN_URL}/governance`}
|
||||||
alignRight={true}
|
alignRight={true}
|
||||||
@ -94,7 +84,7 @@ export const Navbar = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
interface NavLinkProps {
|
interface AppNavLinkProps {
|
||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
navbarTheme: NavbarTheme;
|
navbarTheme: NavbarTheme;
|
||||||
@ -103,36 +93,44 @@ interface NavLinkProps {
|
|||||||
target?: HTMLAttributeAnchorTarget;
|
target?: HTMLAttributeAnchorTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NavLink = ({
|
const AppNavLink = ({
|
||||||
name,
|
name,
|
||||||
path,
|
path,
|
||||||
navbarTheme,
|
navbarTheme,
|
||||||
alignRight,
|
alignRight,
|
||||||
target,
|
target,
|
||||||
testId = name,
|
testId = name,
|
||||||
}: NavLinkProps) => {
|
}: AppNavLinkProps) => {
|
||||||
const router = useRouter();
|
|
||||||
const isActive = router.asPath?.includes(path);
|
|
||||||
const linkClasses = classNames('mx-2 py-3 self-end relative', {
|
|
||||||
'cursor-default': isActive,
|
|
||||||
'text-black dark:text-white': isActive && navbarTheme !== 'yellow',
|
|
||||||
'text-neutral-500 dark:text-neutral-400 hover:text-black dark:hover:text-neutral-300':
|
|
||||||
!isActive && navbarTheme !== 'yellow',
|
|
||||||
'ml-auto': alignRight,
|
|
||||||
'text-black': isActive && navbarTheme === 'yellow',
|
|
||||||
'text-black/60 hover:text-black': !isActive && navbarTheme === 'yellow',
|
|
||||||
});
|
|
||||||
const borderClasses = classNames('absolute h-1 w-full bottom-[-1px] left-0', {
|
const borderClasses = classNames('absolute h-1 w-full bottom-[-1px] left-0', {
|
||||||
'bg-black dark:bg-vega-yellow': navbarTheme !== 'yellow',
|
'bg-black dark:bg-vega-yellow': navbarTheme !== 'yellow',
|
||||||
'bg-black': navbarTheme === 'yellow',
|
'bg-black': navbarTheme === 'yellow',
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<Link data-testid={testId} href={path} passHref={true}>
|
<NavLink
|
||||||
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
data-testid={testId}
|
||||||
<a className={linkClasses} target={target}>
|
to={path}
|
||||||
{name}
|
className={({ isActive }) => {
|
||||||
{isActive && <span className={borderClasses} />}
|
return classNames('mx-2 py-3 self-end relative', {
|
||||||
</a>
|
'cursor-default': isActive,
|
||||||
</Link>
|
'text-black dark:text-white': isActive && navbarTheme !== 'yellow',
|
||||||
|
'text-neutral-500 dark:text-neutral-400 hover:text-black dark:hover:text-neutral-300':
|
||||||
|
!isActive && navbarTheme !== 'yellow',
|
||||||
|
'ml-auto': alignRight,
|
||||||
|
'text-black': isActive && navbarTheme === 'yellow',
|
||||||
|
'text-black/60 hover:text-black':
|
||||||
|
!isActive && navbarTheme === 'yellow',
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
target={target}
|
||||||
|
>
|
||||||
|
{({ isActive }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{name}
|
||||||
|
{isActive && <span className={borderClasses} />}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</NavLink>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ import {
|
|||||||
MarketTradingModeMapping,
|
MarketTradingModeMapping,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
Link,
|
Link as UILink,
|
||||||
PriceCellChange,
|
PriceCellChange,
|
||||||
Sparkline,
|
Sparkline,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
@ -31,6 +31,8 @@ import type {
|
|||||||
MarketWithData,
|
MarketWithData,
|
||||||
MarketWithCandles,
|
MarketWithCandles,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
type Market = MarketWithData & MarketWithCandles;
|
type Market = MarketWithData & MarketWithCandles;
|
||||||
|
|
||||||
export const cellClassNames = 'py-1 first:text-left text-right';
|
export const cellClassNames = 'py-1 first:text-left text-right';
|
||||||
@ -224,7 +226,7 @@ export const columns = (
|
|||||||
kind: ColumnKind.Market,
|
kind: ColumnKind.Market,
|
||||||
value: (
|
value: (
|
||||||
<Link
|
<Link
|
||||||
href={`/markets/${market.id}`}
|
to={`/markets/${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) => {
|
||||||
@ -232,7 +234,7 @@ export const columns = (
|
|||||||
onSelect(market.id);
|
onSelect(market.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{market.tradableInstrument.instrument.code}
|
<UILink>{market.tradableInstrument.instrument.code}</UILink>
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
className: cellClassNames,
|
className: cellClassNames,
|
||||||
@ -392,7 +394,7 @@ export const columnsPositionMarkets = (
|
|||||||
const candleLow = market.candles && calcCandleLow(market.candles);
|
const candleLow = market.candles && calcCandleLow(market.candles);
|
||||||
const candleHigh = market.candles && calcCandleHigh(market.candles);
|
const candleHigh = market.candles && calcCandleHigh(market.candles);
|
||||||
const handleKeyPress = (
|
const handleKeyPress = (
|
||||||
event: React.KeyboardEvent<HTMLAnchorElement>,
|
event: React.KeyboardEvent<HTMLSpanElement>,
|
||||||
id: string
|
id: string
|
||||||
) => {
|
) => {
|
||||||
if (event.key === 'Enter' && onSelect) {
|
if (event.key === 'Enter' && onSelect) {
|
||||||
@ -405,7 +407,7 @@ export const columnsPositionMarkets = (
|
|||||||
kind: ColumnKind.Market,
|
kind: ColumnKind.Market,
|
||||||
value: (
|
value: (
|
||||||
<Link
|
<Link
|
||||||
href={`/markets/${market.id}`}
|
to={`/markets/${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) => {
|
||||||
@ -413,7 +415,7 @@ export const columnsPositionMarkets = (
|
|||||||
onSelect(market.id);
|
onSelect(market.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{market.tradableInstrument.instrument.code}
|
<UILink>{market.tradableInstrument.instrument.code}</UILink>
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
className: cellClassNames,
|
className: cellClassNames,
|
||||||
|
@ -6,21 +6,14 @@ import {
|
|||||||
SelectMarketLandingTable,
|
SelectMarketLandingTable,
|
||||||
} from './select-market';
|
} from './select-market';
|
||||||
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import type {
|
import type {
|
||||||
MarketWithCandles,
|
MarketWithCandles,
|
||||||
MarketWithData,
|
MarketWithData,
|
||||||
MarketData,
|
MarketData,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketWithCandles & MarketWithData;
|
||||||
|
|
||||||
jest.mock(
|
|
||||||
'next/link',
|
|
||||||
() =>
|
|
||||||
({ children }: { children: ReactNode }) =>
|
|
||||||
children
|
|
||||||
);
|
|
||||||
|
|
||||||
type PartialMarket = Partial<
|
type PartialMarket = Partial<
|
||||||
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
||||||
>;
|
>;
|
||||||
@ -157,11 +150,13 @@ describe('SelectMarket', () => {
|
|||||||
const onSelect = jest.fn();
|
const onSelect = jest.fn();
|
||||||
const onCellClick = jest.fn();
|
const onCellClick = jest.fn();
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<SelectAllMarketsTableBody
|
<MemoryRouter>
|
||||||
markets={[MARKET_A as Market, MARKET_B as Market]}
|
<SelectAllMarketsTableBody
|
||||||
onCellClick={onCellClick}
|
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||||
onSelect={onSelect}
|
onCellClick={onCellClick}
|
||||||
/>
|
onSelect={onSelect}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
|
expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
|
||||||
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
||||||
@ -175,11 +170,13 @@ describe('SelectMarket', () => {
|
|||||||
const onCellClick = jest.fn();
|
const onCellClick = jest.fn();
|
||||||
|
|
||||||
render(
|
render(
|
||||||
<SelectMarketLandingTable
|
<MemoryRouter>
|
||||||
markets={[MARKET_A as Market, MARKET_B as Market]}
|
<SelectMarketLandingTable
|
||||||
onCellClick={onCellClick}
|
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||||
onSelect={onSelect}
|
onCellClick={onCellClick}
|
||||||
/>
|
onSelect={onSelect}
|
||||||
|
/>
|
||||||
|
</MemoryRouter>
|
||||||
);
|
);
|
||||||
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||||
expect(onSelect).toHaveBeenCalledWith('1');
|
expect(onSelect).toHaveBeenCalledWith('1');
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
Dialog,
|
Dialog,
|
||||||
Icon,
|
Icon,
|
||||||
Intent,
|
Intent,
|
||||||
Link,
|
Link as UILink,
|
||||||
Loader,
|
Loader,
|
||||||
Popover,
|
Popover,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
@ -30,6 +30,7 @@ import type {
|
|||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
||||||
import type { Column, OnCellClickHandler } from './select-market-columns';
|
import type { Column, OnCellClickHandler } from './select-market-columns';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketWithCandles & MarketWithData;
|
||||||
|
|
||||||
export const SelectMarketLandingTable = ({
|
export const SelectMarketLandingTable = ({
|
||||||
@ -65,8 +66,8 @@ export const SelectMarketLandingTable = ({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 text-md">
|
<div className="mt-4 text-md">
|
||||||
<Link href="/markets" data-testid="view-market-list-link">
|
<Link to="/markets" data-testid="view-market-list-link">
|
||||||
{'Or view full market list'}
|
<UILink>{'Or view full market list'} </UILink>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { AppProps } from 'next/app';
|
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
|
import type { AppProps } from 'next/app';
|
||||||
import { Navbar } from '../components/navbar';
|
import { Navbar } from '../components/navbar';
|
||||||
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||||
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
import { VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||||
@ -13,8 +13,9 @@ import { AppLoader } from '../components/app-loader';
|
|||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { usePageTitleStore } from '../stores';
|
import { usePageTitleStore } from '../stores';
|
||||||
import { Footer } from '../components/footer';
|
import { Footer } from '../components/footer';
|
||||||
import { useMemo } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import DialogsContainer from './dialogs-container';
|
import DialogsContainer from './dialogs-container';
|
||||||
|
import { HashRouter, useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
const DEFAULT_TITLE = t('Welcome to Vega trading!');
|
const DEFAULT_TITLE = t('Welcome to Vega trading!');
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ const Title = () => {
|
|||||||
if (networkName) return `${pageTitle} [${networkName}]`;
|
if (networkName) return `${pageTitle} [${networkName}]`;
|
||||||
return pageTitle;
|
return pageTitle;
|
||||||
}, [pageTitle, networkName]);
|
}, [pageTitle, networkName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Head>
|
<Head>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
@ -38,9 +40,11 @@ const Title = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function AppBody({ Component, pageProps }: AppProps) {
|
function AppBody({ Component }: AppProps) {
|
||||||
|
const location = useLocation();
|
||||||
const { VEGA_ENV } = useEnvironment();
|
const { VEGA_ENV } = useEnvironment();
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
const [theme, toggleTheme] = useThemeSwitcher();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
<ThemeContext.Provider value={theme}>
|
||||||
<Head>
|
<Head>
|
||||||
@ -54,8 +58,8 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
toggleTheme={toggleTheme}
|
toggleTheme={toggleTheme}
|
||||||
navbarTheme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'}
|
navbarTheme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'dark'}
|
||||||
/>
|
/>
|
||||||
<main data-testid={pageProps.page}>
|
<main data-testid={location.pathname}>
|
||||||
<Component {...pageProps} />
|
<Component />
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
<DialogsContainer />
|
<DialogsContainer />
|
||||||
@ -66,12 +70,25 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function VegaTradingApp(props: AppProps) {
|
function VegaTradingApp(props: AppProps) {
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
|
// Hash router requires access to the document object. At compile time that doesn't exist
|
||||||
|
// so we need to ensure client side rendering only from this point onwards in
|
||||||
|
// the component tree
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!mounted) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<HashRouter>
|
||||||
<VegaWalletProvider>
|
<EnvironmentProvider>
|
||||||
<AppBody {...props} />
|
<VegaWalletProvider>
|
||||||
</VegaWalletProvider>
|
<AppBody {...props} />
|
||||||
</EnvironmentProvider>
|
</VegaWalletProvider>
|
||||||
|
</EnvironmentProvider>
|
||||||
|
</HashRouter>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ export default function Document() {
|
|||||||
return (
|
return (
|
||||||
<Html>
|
<Html>
|
||||||
<Head>
|
<Head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link
|
<link
|
||||||
rel="preload"
|
rel="preload"
|
||||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||||
|
77
apps/trading/pages/client-router.tsx
Normal file
77
apps/trading/pages/client-router.tsx
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { Suspense } from 'react';
|
||||||
|
import { useRoutes } from 'react-router-dom';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
|
const LazyHome = dynamic(() => import('../client-pages/home'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LazyLiquidity = dynamic(() => import('../client-pages/liquidity'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LazyMarkets = dynamic(() => import('../client-pages/markets'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LazyMarket = dynamic(() => import('../client-pages/market'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LazyPortfolio = dynamic(() => import('../client-pages/portfolio'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LazyDeposit = dynamic(() => import('../client-pages/deposit'), {
|
||||||
|
ssr: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
export enum Routes {
|
||||||
|
HOME = '/',
|
||||||
|
MARKETS = '/markets',
|
||||||
|
PORTFOLIO = '/portfolio',
|
||||||
|
PORTFOLIO_DEPOSIT = '/portfolio/deposit',
|
||||||
|
}
|
||||||
|
|
||||||
|
const routerConfig = [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <LazyHome />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: Routes.MARKETS,
|
||||||
|
element: <LazyMarkets />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'markets/:marketId',
|
||||||
|
element: <LazyMarket />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'liquidity/:marketId',
|
||||||
|
element: <LazyLiquidity />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: Routes.PORTFOLIO,
|
||||||
|
element: <LazyPortfolio />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: Routes.PORTFOLIO_DEPOSIT,
|
||||||
|
element: <LazyDeposit />,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const ClientRouter = () => {
|
||||||
|
const routes = useRoutes(routerConfig);
|
||||||
|
return (
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div className="w-full h-full flex justify-center items-center">
|
||||||
|
{t('Loading...')}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{routes}
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
};
|
@ -1,69 +1,10 @@
|
|||||||
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
import { ClientRouter } from './client-router';
|
||||||
import {
|
|
||||||
addDecimalsFormatNumber,
|
|
||||||
titlefy,
|
|
||||||
useDataProvider,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useGlobalStore, usePageTitleStore } from '../stores';
|
|
||||||
|
|
||||||
export function Index() {
|
/**
|
||||||
const { replace } = useRouter();
|
* Next only handles this single index page, react-router takes over after the page
|
||||||
// The default market selected in the platform behind the overlay
|
* is served to the browser. This is because we can't run next server via ipfs and
|
||||||
// should be the oldest market that is currently trading in us mode(i.e. not in auction).
|
* have to serve a static site via next export
|
||||||
const { data, error, loading } = useDataProvider({
|
*/
|
||||||
dataProvider: marketsWithDataProvider,
|
export default function Index() {
|
||||||
});
|
return <ClientRouter />;
|
||||||
const { riskNoticeDialog, update } = useGlobalStore((store) => ({
|
|
||||||
riskNoticeDialog: store.riskNoticeDialog,
|
|
||||||
update: store.update,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { pageTitle, updateTitle } = usePageTitleStore((store) => ({
|
|
||||||
pageTitle: store.pageTitle,
|
|
||||||
updateTitle: store.updateTitle,
|
|
||||||
}));
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
update({ landingDialog: true });
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
const marketId = data[0]?.id;
|
|
||||||
const marketName = data[0]?.tradableInstrument.instrument.name;
|
|
||||||
const marketPrice = data[0]?.data?.markPrice
|
|
||||||
? addDecimalsFormatNumber(
|
|
||||||
data[0]?.data?.markPrice,
|
|
||||||
data[0]?.decimalPlaces
|
|
||||||
)
|
|
||||||
: null;
|
|
||||||
const newPageTitle = titlefy([marketName, marketPrice]);
|
|
||||||
|
|
||||||
if (marketId) {
|
|
||||||
replace(`/markets/${marketId}`);
|
|
||||||
update({ marketId });
|
|
||||||
if (pageTitle !== newPageTitle) {
|
|
||||||
updateTitle(newPageTitle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Fallback to the markets list page
|
|
||||||
else {
|
|
||||||
replace('/markets');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [data, replace, riskNoticeDialog, update, pageTitle, updateTitle]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AsyncRenderer data={data} loading={loading} error={error}>
|
|
||||||
{/* Render a loading and error state but we will redirect if markets are found */}
|
|
||||||
{null}
|
|
||||||
</AsyncRenderer>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Index.getInitialProps = () => ({
|
|
||||||
page: 'home',
|
|
||||||
});
|
|
||||||
|
|
||||||
export default Index;
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './[marketId].page';
|
|
@ -1,36 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { act, render } from '@testing-library/react';
|
|
||||||
import Index from '../pages/index.page';
|
|
||||||
import { MockedProvider } from '@apollo/react-testing';
|
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/ui-toolkit', () => {
|
|
||||||
const original = jest.requireActual('@vegaprotocol/ui-toolkit');
|
|
||||||
return {
|
|
||||||
...original,
|
|
||||||
AgGridDynamic: () => <div>AgGrid</div>,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('next/router', () => ({
|
|
||||||
useRouter() {
|
|
||||||
return {
|
|
||||||
route: '/',
|
|
||||||
pathname: '',
|
|
||||||
query: '',
|
|
||||||
asPath: '',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('Index', () => {
|
|
||||||
it('should render successfully', async () => {
|
|
||||||
act(() => {
|
|
||||||
const { baseElement } = render(
|
|
||||||
<MockedProvider>
|
|
||||||
<Index />
|
|
||||||
</MockedProvider>
|
|
||||||
);
|
|
||||||
expect(baseElement).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -6,6 +6,7 @@ const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
join(__dirname, 'pages/**/*.{js,ts,jsx,tsx}'),
|
join(__dirname, 'pages/**/*.{js,ts,jsx,tsx}'),
|
||||||
|
join(__dirname, 'client-pages/**/*.{js,ts,jsx,tsx}'),
|
||||||
join(__dirname, 'components/**/*.{js,ts,jsx,tsx}'),
|
join(__dirname, 'components/**/*.{js,ts,jsx,tsx}'),
|
||||||
'libs/ui-toolkit/src/utils/shared.ts',
|
'libs/ui-toolkit/src/utils/shared.ts',
|
||||||
...createGlobPatternsForDependencies(__dirname),
|
...createGlobPatternsForDependencies(__dirname),
|
||||||
|
@ -3,12 +3,12 @@ import {
|
|||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { Link as UiToolkitLink } from '@vegaprotocol/ui-toolkit';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { MarketTradingMode, AuctionTrigger } from '@vegaprotocol/types';
|
import { MarketTradingMode, AuctionTrigger } from '@vegaprotocol/types';
|
||||||
|
import { Link as UILink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { MarketDataGridProps } from './market-data-grid';
|
import type { MarketDataGridProps } from './market-data-grid';
|
||||||
import type { DealTicketMarketFragment } from '../deal-ticket/__generated___/DealTicket';
|
import type { DealTicketMarketFragment } from '../deal-ticket/__generated___/DealTicket';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
export const compileGridData = (
|
export const compileGridData = (
|
||||||
market: Omit<DealTicketMarketFragment, 'depth'>,
|
market: Omit<DealTicketMarketFragment, 'depth'>,
|
||||||
@ -60,10 +60,11 @@ export const compileGridData = (
|
|||||||
if (isLiquidityMonitoringAuction && market.data?.suppliedStake) {
|
if (isLiquidityMonitoringAuction && market.data?.suppliedStake) {
|
||||||
grid.push({
|
grid.push({
|
||||||
label: (
|
label: (
|
||||||
<Link href={`/liquidity/${market.id}`} passHref={true}>
|
<Link
|
||||||
<UiToolkitLink onClick={() => onSelect && onSelect(market.id)}>
|
to={`/liquidity/${market.id}`}
|
||||||
{t('Current liquidity')}
|
onClick={() => onSelect && onSelect(market.id)}
|
||||||
</UiToolkitLink>
|
>
|
||||||
|
<UILink>{t('Current liquidity')}</UILink>
|
||||||
</Link>
|
</Link>
|
||||||
),
|
),
|
||||||
value: formatStake(market.data.suppliedStake),
|
value: formatStake(market.data.suppliedStake),
|
||||||
|
@ -17,14 +17,13 @@ import {
|
|||||||
Accordion,
|
Accordion,
|
||||||
AsyncRenderer,
|
AsyncRenderer,
|
||||||
ExternalLink,
|
ExternalLink,
|
||||||
Link as UiToolkitLink,
|
Link as UILink,
|
||||||
Splash,
|
Splash,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
import Link from 'next/link';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { generatePath } from 'react-router-dom';
|
import { generatePath, Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { getMarketExpiryDateFormatted } from '../market-expires';
|
import { getMarketExpiryDateFormatted } from '../market-expires';
|
||||||
import { MarketInfoTable } from './info-key-value-table';
|
import { MarketInfoTable } from './info-key-value-table';
|
||||||
@ -319,13 +318,12 @@ export const Info = ({ market, onSelect }: InfoProps) => {
|
|||||||
}
|
}
|
||||||
assetSymbol={assetSymbol}
|
assetSymbol={assetSymbol}
|
||||||
>
|
>
|
||||||
<Link passHref={true} href={`/liquidity/${market.id}`}>
|
<Link
|
||||||
<UiToolkitLink
|
to={`/liquidity/${market.id}`}
|
||||||
onClick={() => onSelect(market.id)}
|
onClick={() => onSelect(market.id)}
|
||||||
data-testid="view-liquidity-link"
|
data-testid="view-liquidity-link"
|
||||||
>
|
>
|
||||||
{t('View liquidity provision table')}
|
<UILink>{t('View liquidity provision table')}</UILink>
|
||||||
</UiToolkitLink>
|
|
||||||
</Link>
|
</Link>
|
||||||
</MarketInfoTable>
|
</MarketInfoTable>
|
||||||
),
|
),
|
||||||
|
@ -16,15 +16,25 @@ export const Link = ({ className, children, ...props }: LinkProps) => {
|
|||||||
'cursor-pointer': props['aria-disabled'] !== true,
|
'cursor-pointer': props['aria-disabled'] !== true,
|
||||||
'opacity-50 pointer-events-none': props['aria-disabled'] === true,
|
'opacity-50 pointer-events-none': props['aria-disabled'] === true,
|
||||||
});
|
});
|
||||||
|
const shared = {
|
||||||
|
role: 'link',
|
||||||
|
'data-testid': 'link',
|
||||||
|
referrerPolicy: 'strict-origin' as const,
|
||||||
|
className: anchorClassName,
|
||||||
|
};
|
||||||
|
|
||||||
|
// if no href is passed just render a span, this is so that we can wrap an
|
||||||
|
// element with our links styles with a react router link compoment
|
||||||
|
if (!props.href) {
|
||||||
|
return (
|
||||||
|
<span {...shared} {...props}>
|
||||||
|
{children}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a {...shared} {...props}>
|
||||||
role="link"
|
|
||||||
data-testid="link"
|
|
||||||
referrerPolicy="strict-origin"
|
|
||||||
className={anchorClassName}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
{children}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user