From 7f1632d44d462b063c44dde6dc5f4fe723e7c2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Fri, 25 Mar 2022 13:32:14 +0100 Subject: [PATCH] [#128] add component --- .../data-providers/generic-data-provider.ts | 6 +- .../data-providers/markets-data-provider.ts | 5 +- .../data-providers/positions-data-provider.ts | 8 +- libs/graphql/src/index.ts | 7 +- libs/positions/src/index.ts | 2 +- .../src/lib/positions-table.spec.tsx | 22 +++ libs/positions/src/lib/positions-table.tsx | 125 ++++++++++++++++++ libs/positions/src/lib/positions.module.scss | 0 libs/positions/src/lib/positions.spec.tsx | 10 -- libs/positions/src/lib/positions.tsx | 14 -- libs/react-helpers/src/lib/format/format.ts | 13 ++ 11 files changed, 171 insertions(+), 41 deletions(-) create mode 100644 libs/positions/src/lib/positions-table.spec.tsx create mode 100644 libs/positions/src/lib/positions-table.tsx delete mode 100644 libs/positions/src/lib/positions.module.scss delete mode 100644 libs/positions/src/lib/positions.spec.tsx delete mode 100644 libs/positions/src/lib/positions.tsx diff --git a/libs/graphql/src/data-providers/generic-data-provider.ts b/libs/graphql/src/data-providers/generic-data-provider.ts index 328814263..b5c6ae68d 100644 --- a/libs/graphql/src/data-providers/generic-data-provider.ts +++ b/libs/graphql/src/data-providers/generic-data-provider.ts @@ -10,7 +10,7 @@ import type { Subscription } from 'zen-observable-ts'; export function makeDataProvider( query: DocumentNode | TypedDocumentNode, // eslint-disable-line @typescript-eslint/no-explicit-any subscriptionQuery: DocumentNode | TypedDocumentNode, // eslint-disable-line @typescript-eslint/no-explicit-any - update: (draft: Draft[] | null, delta: Delta) => void, + update: (draft: Draft[], delta: Delta) => void, getData: (subscriptionData: QueryData) => Data[] | null, getDelta: (subscriptionData: SubscriptionData) => Delta ) { @@ -61,7 +61,7 @@ export function makeDataProvider( return; } const delta = getDelta(subscriptionData); - if (loading) { + if (loading || !data) { updateQueue.push(delta); } else { const newData = produce(data, (draft) => { @@ -77,7 +77,7 @@ export function makeDataProvider( try { const res = await client.query({ query }); data = getData(res.data); - if (updateQueue && updateQueue.length > 0) { + if (data && updateQueue && updateQueue.length > 0) { data = produce(data, (draft) => { while (updateQueue.length) { const delta = updateQueue.shift(); diff --git a/libs/graphql/src/data-providers/markets-data-provider.ts b/libs/graphql/src/data-providers/markets-data-provider.ts index a921c84ec..795964379 100644 --- a/libs/graphql/src/data-providers/markets-data-provider.ts +++ b/libs/graphql/src/data-providers/markets-data-provider.ts @@ -63,10 +63,7 @@ export const marketsDataProvider = makeDataProvider< >( MARKETS_QUERY, MARKET_DATA_SUB, - (draft: Markets_markets[] | null, delta: MarketDataSub_marketData) => { - if (!draft) { - return; - } + (draft: Markets_markets[], delta: MarketDataSub_marketData) => { const index = draft.findIndex((m) => m.id === delta.market.id); if (index !== -1) { draft[index].data = delta; diff --git a/libs/graphql/src/data-providers/positions-data-provider.ts b/libs/graphql/src/data-providers/positions-data-provider.ts index b0b137f33..9e462d8a7 100644 --- a/libs/graphql/src/data-providers/positions-data-provider.ts +++ b/libs/graphql/src/data-providers/positions-data-provider.ts @@ -77,13 +77,7 @@ export const positionsDataProvider = makeDataProvider< >( POSITION_QUERY, POSITIONS_SUB, - ( - draft: positions_party_positions[] | null, - delta: positionSubscribe_positions - ) => { - if (!draft) { - return; - } + (draft: positions_party_positions[], delta: positionSubscribe_positions) => { const index = draft.findIndex((m) => m.market.id === delta.market.id); if (index !== -1) { draft[index] = delta; diff --git a/libs/graphql/src/index.ts b/libs/graphql/src/index.ts index 37e47e81f..5210717e1 100644 --- a/libs/graphql/src/index.ts +++ b/libs/graphql/src/index.ts @@ -2,10 +2,10 @@ export * from './__generated__/AssetsQuery'; export * from './__generated__/globalTypes'; export * from './__generated__/Guess'; export * from './__generated__/Market'; +export * from './__generated__/MarketDataFields'; +export * from './__generated__/MarketDataSub'; export * from './__generated__/Markets'; export * from './__generated__/MarketsQuery'; -export * from './__generated__/MarketDataSub'; -export * from './__generated__/MarketDataFields'; export * from './__generated__/NetworkParametersQuery'; export * from './__generated__/NodesQuery'; export * from './__generated__/OrderEvent'; @@ -13,6 +13,9 @@ export * from './__generated__/OrderFields'; export * from './__generated__/Orders'; export * from './__generated__/OrderSub'; export * from './__generated__/PartyAssetsQuery'; +export * from './__generated__/PositionDetails'; +export * from './__generated__/positions'; +export * from './__generated__/positionSubscribe'; export * from './__generated__/ProposalsQuery'; export * from './data-providers'; diff --git a/libs/positions/src/index.ts b/libs/positions/src/index.ts index 0ea617847..2b3811e35 100644 --- a/libs/positions/src/index.ts +++ b/libs/positions/src/index.ts @@ -1 +1 @@ -export * from './lib/positions'; +export * from './lib/positions-table'; diff --git a/libs/positions/src/lib/positions-table.spec.tsx b/libs/positions/src/lib/positions-table.spec.tsx new file mode 100644 index 000000000..bc5848c4b --- /dev/null +++ b/libs/positions/src/lib/positions-table.spec.tsx @@ -0,0 +1,22 @@ +import { render } from '@testing-library/react'; +import { act } from 'react-dom/test-utils'; +import { MockedProvider } from '@apollo/react-testing'; +import PositionsTable from './positions-table'; + +describe('PositionsTable', () => { + it('should render successfully', async () => { + await act(async () => { + const { baseElement } = render( + + { + console.log(marketId); + }} + /> + + ); + expect(baseElement).toBeTruthy(); + }); + }); +}); diff --git a/libs/positions/src/lib/positions-table.tsx b/libs/positions/src/lib/positions-table.tsx new file mode 100644 index 000000000..4d97a79e0 --- /dev/null +++ b/libs/positions/src/lib/positions-table.tsx @@ -0,0 +1,125 @@ +import { forwardRef, useMemo } from 'react'; +import type { ValueFormatterParams } from 'ag-grid-community'; +import { + PriceCell /*, MarginCell*/, + formatNumber, + volumePrefix, + addDecimal, +} from '@vegaprotocol/react-helpers'; +import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit'; +import { AgGridColumn } from 'ag-grid-react'; +import type { AgGridReact } from 'ag-grid-react'; +import compact from 'lodash/compact'; +import { + positions_party_positions, + MarketTradingMode, +} from '@vegaprotocol/graphql'; + +interface PositionsTableProps { + data: positions_party_positions[]; + onRowClicked: (marketId: string) => void; +} + +export const getRowNodeId = (data: { market: { id: string } }) => + data.market.id; + +const sortByName = ( + a: positions_party_positions, + b: positions_party_positions +) => { + if ( + a.market.tradableInstrument.instrument.name < + b.market.tradableInstrument.instrument.name + ) { + return -1; + } + + if ( + a.market.tradableInstrument.instrument.name > + b.market.tradableInstrument.instrument.name + ) { + return 1; + } + + return 0; +}; + +export const PositionsTable = forwardRef( + ({ data, onRowClicked }, ref) => { + const sortedData = useMemo(() => { + return compact(data).sort(sortByName); + }, [data]); + return ( + + onRowClicked(getRowNodeId(data)) + } + components={{ PriceCell }} + > + + + volumePrefix(value) + } + /> + + formatNumber(value, data.market.decimalPlaces) + } + /> + { + if ( + data.market.data.marketTradingMode === + MarketTradingMode.OpeningAuction + ) { + return '-'; + } + return addDecimal(value, data.market.decimalPlaces); + }} + /> + + Number(value) > 0, + 'color-vega-red': ({ value }: { value: string }) => + Number(value) < 0, + }} + valueFormatter={({ value }: ValueFormatterParams) => { + if (Number(value) > 0) { + return '+' + value; + } + return value; + }} + cellRenderer="PriceCell" + /> + + ); + } +); + +export default PositionsTable; diff --git a/libs/positions/src/lib/positions.module.scss b/libs/positions/src/lib/positions.module.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/libs/positions/src/lib/positions.spec.tsx b/libs/positions/src/lib/positions.spec.tsx deleted file mode 100644 index 3c2ac0d27..000000000 --- a/libs/positions/src/lib/positions.spec.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { render } from '@testing-library/react'; - -import Positions from './positions'; - -describe('Positions', () => { - it('should render successfully', () => { - const { baseElement } = render(); - expect(baseElement).toBeTruthy(); - }); -}); diff --git a/libs/positions/src/lib/positions.tsx b/libs/positions/src/lib/positions.tsx deleted file mode 100644 index 5fd46a0ed..000000000 --- a/libs/positions/src/lib/positions.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import './positions.module.scss'; - -/* eslint-disable-next-line */ -export interface PositionsProps {} - -export function Positions(props: PositionsProps) { - return ( -
-

Welcome to Positions!

-
- ); -} - -export default Positions; diff --git a/libs/react-helpers/src/lib/format/format.ts b/libs/react-helpers/src/lib/format/format.ts index 10c9716f2..33fd4db6b 100644 --- a/libs/react-helpers/src/lib/format/format.ts +++ b/libs/react-helpers/src/lib/format/format.ts @@ -7,6 +7,19 @@ const getUserLocale = () => 'default'; export const splitAt = (index: number) => (x: string) => [x.slice(0, index), x.slice(index)]; +/** + * Returns a number prefixed with either a '-' or a '+'. The open volume field + * already comes with a '-' if negative so we only need to actually prefix if + * its a positive value + */ +export function volumePrefix(value: string): string { + if (value === '0' || value.startsWith('-')) { + return value; + } + + return '+' + value; +} + export const getTimeFormat = once( () => new Intl.DateTimeFormat(getUserLocale(), {