feat(trading): market list snags and disable column removal (#5324)

Co-authored-by: bwallacee <ben@vega.xyz>
This commit is contained in:
m.ray 2023-11-22 15:51:39 +02:00 committed by GitHub
parent 1e9251c9c0
commit a5f2533a66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 97 additions and 26 deletions

View File

@ -1,7 +1,14 @@
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
import { AgGrid, PriceFlashCell } from '@vegaprotocol/datagrid';
import {
AgGrid,
PriceFlashCell,
useDataGridEvents,
} from '@vegaprotocol/datagrid';
import type { MarketMaybeWithData } from '@vegaprotocol/markets';
import { useColumnDefs } from './use-column-defs';
import type { DataGridStore } from '../../stores/datagrid-store-slice';
import { type StateCreator, create } from 'zustand';
import { persist } from 'zustand/middleware';
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
@ -18,8 +25,37 @@ const components = {
type Props = TypedDataAgGrid<MarketMaybeWithData>;
export type DataGridSlice = {
gridStore: DataGridStore;
updateGridStore: (gridStore: DataGridStore) => void;
};
export const createDataGridSlice: StateCreator<DataGridSlice> = (set) => ({
gridStore: {},
updateGridStore: (newStore) => {
set((curr) => ({
gridStore: {
...curr.gridStore,
...newStore,
},
}));
},
});
const useMarketsStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_market_list_store',
})
);
export const MarketListTable = (props: Props) => {
const columnDefs = useColumnDefs();
const gridStore = useMarketsStore((store) => store.gridStore);
const updateGridStore = useMarketsStore((store) => store.updateGridStore);
const gridStoreCallbacks = useDataGridEvents(gridStore, (colState) => {
updateGridStore(colState);
});
return (
<AgGrid
@ -28,6 +64,7 @@ export const MarketListTable = (props: Props) => {
columnDefs={columnDefs}
components={components}
rowHeight={45}
{...gridStoreCallbacks}
{...props}
/>
);

View File

@ -51,6 +51,29 @@ export const useColumnDefs = () => {
headerName: t('Description'),
field: 'tradableInstrument.instrument.name',
},
{
headerName: t('Settlement asset'),
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
cellRenderer: ({
data,
}: VegaICellRendererParams<
MarketMaybeWithData,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value = data && getAsset(data);
return value ? (
<ButtonLink
onClick={(e) => {
openAssetDetailsDialog(value.id, e.target as HTMLElement);
}}
>
{value.symbol}
</ButtonLink>
) : (
''
);
},
},
{
headerName: t('Trading mode'),
field: 'tradingMode',
@ -142,27 +165,21 @@ export const useColumnDefs = () => {
},
},
{
headerName: t('Settlement asset'),
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
cellRenderer: ({
headerName: t('Open Interest'),
field: 'data.openInterest',
type: 'rightAligned',
valueFormatter: ({
data,
}: VegaICellRendererParams<
}: VegaValueFormatterParams<
MarketMaybeWithData,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value = data && getAsset(data);
return value ? (
<ButtonLink
onClick={(e) => {
openAssetDetailsDialog(value.id, e.target as HTMLElement);
}}
>
{value.symbol}
</ButtonLink>
) : (
''
);
},
'data.openInterest'
>) =>
data?.data?.openInterest === undefined
? '-'
: addDecimalsFormatNumber(
data?.data?.openInterest,
data?.positionDecimalPlaces
),
},
{
headerName: t('Spread'),

View File

@ -25,15 +25,15 @@ def test_table_headers(page: Page, create_markets):
headers = [
"Market",
"Description",
"Settlement asset",
"Trading mode",
"Status",
"Mark price",
"24h volume",
"Settlement asset",
"Open Interest",
"Spread",
"",
]
page.wait_for_selector('[data-testid="tab-open-markets"]', state="visible")
page_headers = (
page.get_by_test_id("tab-open-markets").locator(".ag-header-cell-text").all()
@ -157,4 +157,4 @@ def test_drag_and_drop_column(page: Page, create_markets):
page.locator(col_instrument_code).drag_to(
page.locator('.ag-header-row [col-id="data.bestBidPrice"]')
)
expect(page.locator(col_instrument_code)).to_have_attribute("aria-colindex", "8")
expect(page.locator(col_instrument_code)).to_have_attribute("aria-colindex", "9")

View File

@ -39,6 +39,7 @@ export const AgGridThemed = ({
ref={gridRef}
overlayLoadingTemplate={t('Loading...')}
overlayNoRowsTemplate={t('No data')}
suppressDragLeaveHidesColumns
{...defaultProps}
{...props}
/>

View File

@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketsDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } };
export type MarketsDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, openInterest: string, market: { __typename?: 'Market', id: string } };
export type MarketsDataQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type MarketsDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } } | null } }> } | null };
export type MarketsDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, openInterest: string, market: { __typename?: 'Market', id: string } } | null } }> } | null };
export const MarketsDataFieldsFragmentDoc = gql`
fragment MarketsDataFields on MarketData {
@ -30,6 +30,7 @@ export const MarketsDataFieldsFragmentDoc = gql`
suppliedStake
auctionStart
auctionEnd
openInterest
}
`;
export const MarketsDataDocument = gql`

View File

@ -17,6 +17,7 @@ fragment MarketsDataFields on MarketData {
suppliedStake
auctionStart
auctionEnd
openInterest
}
query MarketsData {

View File

@ -40,6 +40,7 @@ export const createMarketsDataFragment = (
bestStaticBidPrice: '0',
bestStaticOfferPrice: '0',
indicativeVolume: '0',
openInterest: '0',
bestBidPrice: '0',
bestOfferPrice: '0',
markPrice: '4612690058',

View File

@ -267,6 +267,7 @@ export const preparePositions = (metrics: Position[], showClosed: boolean) => {
MarketState.STATE_ACTIVE,
MarketState.STATE_PENDING,
MarketState.STATE_SUSPENDED,
MarketState.STATE_SUSPENDED_VIA_GOVERNANCE,
].includes(p.marketState)
) {
return true;

View File

@ -4376,7 +4376,19 @@ export type Query = {
/** The last block process by the blockchain */
lastBlockHeight: Scalars['String'];
/**
* Get ledger entries by asset, market, party, account type, transfer type within the given date range.
* Get a list of ledger entries within the given date range. The date range is restricted to a maximum of 5 days.
* This query requests and sums the number of ledger entries from a given subset of accounts, specified via the 'filter' argument.
* It returns a time series - implemented as a list of AggregateLedgerEntry structs - with a row for every time
* the summed ledger entries of the set of specified accounts changes.
* Each account filter must contain no more than one party ID.
* At least one party ID must be specified in the from or to account filter.
*
* Entries can be filtered by:
* - the sending account (market ID, asset ID, account type)
* - receiving account (market ID, asset ID, account type)
* - sending AND receiving account
* - transfer type either in addition to the above filters or as a standalone option
*
* Note: The date range is restricted to any 5 days.
* If no start or end date is provided, only ledger entries from the last 5 days will be returned.
* If a start and end date are provided, but the end date is more than 5 days after the start date, only data up to 5 days after the start date will be returned.