fix: trades grid colors (#2766)
This commit is contained in:
parent
b1280c8285
commit
4b3b5c322a
@ -3,6 +3,7 @@ fragment TradeFields on Trade {
|
|||||||
price
|
price
|
||||||
size
|
size
|
||||||
createdAt
|
createdAt
|
||||||
|
aggressor
|
||||||
market {
|
market {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@ -35,5 +36,6 @@ subscription TradesUpdate($marketId: ID!) {
|
|||||||
size
|
size
|
||||||
createdAt
|
createdAt
|
||||||
marketId
|
marketId
|
||||||
|
aggressor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
libs/trades/src/lib/__generated__/Trades.ts
generated
8
libs/trades/src/lib/__generated__/Trades.ts
generated
@ -3,7 +3,7 @@ import * as Types from '@vegaprotocol/types';
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import * as Apollo from '@apollo/client';
|
import * as Apollo from '@apollo/client';
|
||||||
const defaultOptions = {} as const;
|
const defaultOptions = {} as const;
|
||||||
export type TradeFieldsFragment = { __typename?: 'Trade', id: string, price: string, size: string, createdAt: any, market: { __typename?: 'Market', id: string } };
|
export type TradeFieldsFragment = { __typename?: 'Trade', id: string, price: string, size: string, createdAt: any, aggressor: Types.Side, market: { __typename?: 'Market', id: string } };
|
||||||
|
|
||||||
export type TradesQueryVariables = Types.Exact<{
|
export type TradesQueryVariables = Types.Exact<{
|
||||||
marketId: Types.Scalars['ID'];
|
marketId: Types.Scalars['ID'];
|
||||||
@ -11,14 +11,14 @@ export type TradesQueryVariables = Types.Exact<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type TradesQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, tradesConnection?: { __typename?: 'TradeConnection', edges: Array<{ __typename?: 'TradeEdge', cursor: string, node: { __typename?: 'Trade', id: string, price: string, size: string, createdAt: any, market: { __typename?: 'Market', id: string } } }>, pageInfo: { __typename?: 'PageInfo', startCursor: string, endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean } } | null } | null };
|
export type TradesQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, tradesConnection?: { __typename?: 'TradeConnection', edges: Array<{ __typename?: 'TradeEdge', cursor: string, node: { __typename?: 'Trade', id: string, price: string, size: string, createdAt: any, aggressor: Types.Side, market: { __typename?: 'Market', id: string } } }>, pageInfo: { __typename?: 'PageInfo', startCursor: string, endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean } } | null } | null };
|
||||||
|
|
||||||
export type TradesUpdateSubscriptionVariables = Types.Exact<{
|
export type TradesUpdateSubscriptionVariables = Types.Exact<{
|
||||||
marketId: Types.Scalars['ID'];
|
marketId: Types.Scalars['ID'];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type TradesUpdateSubscription = { __typename?: 'Subscription', trades?: Array<{ __typename?: 'TradeUpdate', id: string, price: string, size: string, createdAt: any, marketId: string }> | null };
|
export type TradesUpdateSubscription = { __typename?: 'Subscription', trades?: Array<{ __typename?: 'TradeUpdate', id: string, price: string, size: string, createdAt: any, marketId: string, aggressor: Types.Side }> | null };
|
||||||
|
|
||||||
export const TradeFieldsFragmentDoc = gql`
|
export const TradeFieldsFragmentDoc = gql`
|
||||||
fragment TradeFields on Trade {
|
fragment TradeFields on Trade {
|
||||||
@ -26,6 +26,7 @@ export const TradeFieldsFragmentDoc = gql`
|
|||||||
price
|
price
|
||||||
size
|
size
|
||||||
createdAt
|
createdAt
|
||||||
|
aggressor
|
||||||
market {
|
market {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@ -89,6 +90,7 @@ export const TradesUpdateDocument = gql`
|
|||||||
size
|
size
|
||||||
createdAt
|
createdAt
|
||||||
marketId
|
marketId
|
||||||
|
aggressor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { act, render, screen } from '@testing-library/react';
|
import { act, render, screen } from '@testing-library/react';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
||||||
import { DOWN_CLASS, TradesTable, UP_CLASS } from './trades-table';
|
import { SELL_CLASS, TradesTable, BUY_CLASS } from './trades-table';
|
||||||
import type { Trade } from './trades-data-provider';
|
import type { Trade } from './trades-data-provider';
|
||||||
|
import { Side } from '@vegaprotocol/types';
|
||||||
|
|
||||||
const trade: Trade = {
|
const trade: Trade = {
|
||||||
__typename: 'Trade',
|
__typename: 'Trade',
|
||||||
id: 'trade-id',
|
id: 'trade-id',
|
||||||
price: '111122200',
|
price: '111122200',
|
||||||
size: '2000',
|
size: '2000',
|
||||||
|
aggressor: Side.SIDE_BUY,
|
||||||
createdAt: new Date('2022-04-06T19:00:00').toISOString(),
|
createdAt: new Date('2022-04-06T19:00:00').toISOString(),
|
||||||
market: {
|
market: {
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
@ -17,59 +19,58 @@ const trade: Trade = {
|
|||||||
} as Trade['market'],
|
} as Trade['market'],
|
||||||
};
|
};
|
||||||
|
|
||||||
it('Correct columns are rendered', async () => {
|
describe('TradesTable', () => {
|
||||||
await act(async () => {
|
it('should render correct columns', async () => {
|
||||||
render(<TradesTable rowData={[trade]} />);
|
await act(async () => {
|
||||||
});
|
render(<TradesTable rowData={[trade]} />);
|
||||||
const expectedHeaders = ['Price', 'Size', 'Created at'];
|
});
|
||||||
const headers = screen.getAllByRole('columnheader');
|
const expectedHeaders = ['Price', 'Size', 'Created at'];
|
||||||
expect(headers).toHaveLength(expectedHeaders.length);
|
const headers = screen.getAllByRole('columnheader');
|
||||||
expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders);
|
expect(headers).toHaveLength(expectedHeaders.length);
|
||||||
});
|
expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders);
|
||||||
|
|
||||||
it('Number and data columns are formatted', async () => {
|
|
||||||
await act(async () => {
|
|
||||||
render(<TradesTable rowData={[trade]} />);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const cells = screen.getAllByRole('gridcell');
|
it('should format number and data columns', async () => {
|
||||||
const expectedValues = [
|
await act(async () => {
|
||||||
'1,111,222.00',
|
render(<TradesTable rowData={[trade]} />);
|
||||||
'20.00',
|
});
|
||||||
getDateTimeFormat().format(new Date(trade.createdAt)),
|
|
||||||
];
|
const cells = screen.getAllByRole('gridcell');
|
||||||
cells.forEach((cell, i) => {
|
const expectedValues = [
|
||||||
expect(cell).toHaveTextContent(expectedValues[i]);
|
'1,111,222.00',
|
||||||
|
'20.00',
|
||||||
|
getDateTimeFormat().format(new Date(trade.createdAt)),
|
||||||
|
];
|
||||||
|
cells.forEach((cell, i) => {
|
||||||
|
expect(cell).toHaveTextContent(expectedValues[i]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should format price and size columns', async () => {
|
||||||
|
const trade2 = {
|
||||||
|
...trade,
|
||||||
|
id: 'trade-id-2',
|
||||||
|
price: (Number(trade.price) + 10).toString(),
|
||||||
|
size: (Number(trade.size) - 10).toString(),
|
||||||
|
};
|
||||||
|
await act(async () => {
|
||||||
|
render(<TradesTable rowData={[trade2, trade]} />);
|
||||||
|
});
|
||||||
|
|
||||||
|
const cells = screen.getAllByRole('gridcell');
|
||||||
|
|
||||||
|
const priceCells = cells.filter(
|
||||||
|
(cell) => cell.getAttribute('col-id') === 'price'
|
||||||
|
);
|
||||||
|
const sizeCells = cells.filter(
|
||||||
|
(cell) => cell.getAttribute('col-id') === 'size'
|
||||||
|
);
|
||||||
|
|
||||||
|
// For first trade price should have green class
|
||||||
|
// row 1
|
||||||
|
expect(priceCells[0]).toHaveClass(BUY_CLASS);
|
||||||
|
expect(priceCells[1]).not.toHaveClass(SELL_CLASS);
|
||||||
|
expect(sizeCells[1]).not.toHaveClass(SELL_CLASS);
|
||||||
|
expect(sizeCells[1]).not.toHaveClass(BUY_CLASS);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Price and size columns are formatted', async () => {
|
|
||||||
const trade2 = {
|
|
||||||
...trade,
|
|
||||||
id: 'trade-id-2',
|
|
||||||
price: (Number(trade.price) + 10).toString(),
|
|
||||||
size: (Number(trade.size) - 10).toString(),
|
|
||||||
};
|
|
||||||
await act(async () => {
|
|
||||||
render(<TradesTable rowData={[trade2, trade]} />);
|
|
||||||
});
|
|
||||||
|
|
||||||
const cells = screen.getAllByRole('gridcell');
|
|
||||||
|
|
||||||
const priceCells = cells.filter(
|
|
||||||
(cell) => cell.getAttribute('col-id') === 'price'
|
|
||||||
);
|
|
||||||
const sizeCells = cells.filter(
|
|
||||||
(cell) => cell.getAttribute('col-id') === 'size'
|
|
||||||
);
|
|
||||||
|
|
||||||
// For first trade price should have green class and size should have red class
|
|
||||||
// row 1
|
|
||||||
expect(priceCells[0]).toHaveClass(UP_CLASS);
|
|
||||||
expect(priceCells[1]).not.toHaveClass(DOWN_CLASS);
|
|
||||||
expect(priceCells[1]).not.toHaveClass(UP_CLASS);
|
|
||||||
|
|
||||||
expect(sizeCells[0]).toHaveClass(DOWN_CLASS);
|
|
||||||
expect(sizeCells[1]).not.toHaveClass(DOWN_CLASS);
|
|
||||||
expect(sizeCells[1]).not.toHaveClass(UP_CLASS);
|
|
||||||
});
|
|
||||||
|
@ -13,31 +13,22 @@ import type { IDatasource, IGetRowsParams } from 'ag-grid-community';
|
|||||||
import type { CellClassParams, ValueFormatterParams } from 'ag-grid-community';
|
import type { CellClassParams, ValueFormatterParams } from 'ag-grid-community';
|
||||||
import type { AgGridReactProps } from 'ag-grid-react';
|
import type { AgGridReactProps } from 'ag-grid-react';
|
||||||
import type { Trade } from './trades-data-provider';
|
import type { Trade } from './trades-data-provider';
|
||||||
import BigNumber from 'bignumber.js';
|
import { Side } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export const UP_CLASS = 'text-vega-green dark:text-vega-green';
|
export const BUY_CLASS = 'text-vega-green dark:text-vega-green';
|
||||||
export const DOWN_CLASS = 'text-vega-pink dark:text-vega-pink';
|
export const SELL_CLASS = 'text-vega-pink dark:text-vega-pink';
|
||||||
|
|
||||||
const changeCellClass =
|
const changeCellClass = ({ node }: CellClassParams) => {
|
||||||
(dataKey: string) =>
|
let colorClass = '';
|
||||||
({ api, value, node }: CellClassParams) => {
|
|
||||||
const rowIndex = node?.rowIndex;
|
|
||||||
let colorClass = '';
|
|
||||||
|
|
||||||
if (typeof rowIndex === 'number') {
|
if (node.data?.aggressor === Side.SIDE_BUY) {
|
||||||
const prevRowNode = api.getModel().getRow(rowIndex + 1);
|
colorClass = BUY_CLASS;
|
||||||
const prevValue = prevRowNode?.data && prevRowNode.data[dataKey];
|
} else if (node.data?.aggressor === Side.SIDE_SELL) {
|
||||||
const valueNum = new BigNumber(value);
|
colorClass = SELL_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueNum.isGreaterThan(prevValue)) {
|
return ['font-mono text-right', colorClass].join(' ');
|
||||||
colorClass = UP_CLASS;
|
};
|
||||||
} else if (valueNum.isLessThan(prevValue)) {
|
|
||||||
colorClass = DOWN_CLASS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ['font-mono text-right', colorClass].join(' ');
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
|
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
|
||||||
successCallback(rowsThisBlock: (Trade | null)[], lastRow?: number): void;
|
successCallback(rowsThisBlock: (Trade | null)[], lastRow?: number): void;
|
||||||
@ -77,7 +68,7 @@ export const TradesTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
field="price"
|
field="price"
|
||||||
type="rightAligned"
|
type="rightAligned"
|
||||||
width={130}
|
width={130}
|
||||||
cellClass={changeCellClass('price')}
|
cellClass={changeCellClass}
|
||||||
valueFormatter={({
|
valueFormatter={({
|
||||||
value,
|
value,
|
||||||
data,
|
data,
|
||||||
@ -127,7 +118,6 @@ export const TradesTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
}
|
}
|
||||||
return addDecimal(value, data.market.positionDecimalPlaces);
|
return addDecimal(value, data.market.positionDecimalPlaces);
|
||||||
}}
|
}}
|
||||||
cellClass={changeCellClass('size')}
|
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
headerName={t('Created at')}
|
headerName={t('Created at')}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Side } from '@vegaprotocol/types';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import type {
|
import type {
|
||||||
@ -47,6 +48,7 @@ export const tradesUpdateSubscription = (
|
|||||||
size: '24',
|
size: '24',
|
||||||
createdAt: '2022-04-06T16:19:42.692598951Z',
|
createdAt: '2022-04-06T16:19:42.692598951Z',
|
||||||
marketId: 'market-0',
|
marketId: 'market-0',
|
||||||
|
aggressor: Side.SIDE_BUY,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -59,6 +61,7 @@ const trades: TradeFieldsFragment[] = [
|
|||||||
price: '17116898',
|
price: '17116898',
|
||||||
size: '24',
|
size: '24',
|
||||||
createdAt: '2022-04-06T16:19:42.692598951Z',
|
createdAt: '2022-04-06T16:19:42.692598951Z',
|
||||||
|
aggressor: Side.SIDE_BUY,
|
||||||
market: {
|
market: {
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
@ -70,6 +73,7 @@ const trades: TradeFieldsFragment[] = [
|
|||||||
price: '17209102',
|
price: '17209102',
|
||||||
size: '7',
|
size: '7',
|
||||||
createdAt: '2022-04-07T06:59:44.835686754Z',
|
createdAt: '2022-04-07T06:59:44.835686754Z',
|
||||||
|
aggressor: Side.SIDE_SELL,
|
||||||
market: {
|
market: {
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
@ -81,6 +85,7 @@ const trades: TradeFieldsFragment[] = [
|
|||||||
price: '17106734',
|
price: '17106734',
|
||||||
size: '18',
|
size: '18',
|
||||||
createdAt: '2022-04-07T17:56:47.997938583Z',
|
createdAt: '2022-04-07T17:56:47.997938583Z',
|
||||||
|
aggressor: Side.SIDE_BUY,
|
||||||
market: {
|
market: {
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
|
Loading…
Reference in New Issue
Block a user