From 5a0da4e15886bc3bd3432b87ca2db5351b29cd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Mon, 16 Jan 2023 18:51:30 +0100 Subject: [PATCH] feat: update market data components when they are in view (#2607) --- .../deal-ticket/use-order-validation.tsx | 16 +- .../__generated__/CandleLive.ts | 27 ---- .../__generated___/Candles.ts | 43 ------ .../last-24h-volume/last-24h-volume.tsx | 6 +- apps/trading/assets/.gitkeep | 0 apps/trading/assets/env-config.js | 1 - apps/trading/assets/green-cloud.png | Bin 61657 -> 0 bytes apps/trading/assets/poster-image.jpg | Bin 32448 -> 0 bytes .../market/trade-market-header.tsx | 43 ++++-- apps/trading/components/constants.ts | 2 +- .../last-24h-price-change.tsx | 86 ++++------- .../last-24h-volume/last-24h-volume.tsx | 95 ++++-------- .../market-mark-price/market-mark-price.tsx | 80 ++++------ .../components/market-state/market-state.tsx | 2 +- .../market-trading-mode.tsx | 142 +++++++----------- .../market-volume/market-volume.tsx | 2 +- .../select-market/select-market-columns.tsx | 37 ++--- .../select-market/select-market.tsx | 30 ++-- apps/trading/setup-tests.ts | 2 + .../deal-ticket/time-in-force-selector.tsx | 12 +- .../components/deal-ticket/type-selector.tsx | 12 +- .../compile-grid-data.tsx | 54 ++++--- .../trading-mode-tooltip.tsx | 26 +++- .../src/lib/market-data-provider.ts | 53 +++++++ libs/market-list/src/lib/markets-provider.ts | 22 +++ .../src/lib/format/number.spec.tsx | 4 +- libs/react-helpers/src/lib/format/number.tsx | 2 +- .../src/lib/generic-data-provider.ts | 8 +- .../react-helpers/src/lib/grid/price-cell.tsx | 58 +++---- .../price-change/price-change-cell.tsx | 51 ++++--- 30 files changed, 443 insertions(+), 473 deletions(-) delete mode 100644 apps/console-lite/src/app/components/simple-market-list/__generated__/CandleLive.ts delete mode 100644 apps/console-lite/src/app/components/simple-market-list/__generated___/Candles.ts delete mode 100644 apps/trading/assets/.gitkeep delete mode 100644 apps/trading/assets/env-config.js delete mode 100644 apps/trading/assets/green-cloud.png delete mode 100644 apps/trading/assets/poster-image.jpg diff --git a/apps/console-lite/src/app/components/deal-ticket/use-order-validation.tsx b/apps/console-lite/src/app/components/deal-ticket/use-order-validation.tsx index b657ff34e..8ad27a917 100644 --- a/apps/console-lite/src/app/components/deal-ticket/use-order-validation.tsx +++ b/apps/console-lite/src/app/components/deal-ticket/use-order-validation.tsx @@ -215,7 +215,9 @@ export const useOrderValidation = ({ {t('This market is in auction until it reaches')}{' '} } + description={ + + } > {t('sufficient liquidity')} @@ -237,7 +239,9 @@ export const useOrderValidation = ({ {t('This market is in auction due to')}{' '} } + description={ + + } > {t('high price volatility')} @@ -276,7 +280,9 @@ export const useOrderValidation = ({ {t('This market is in auction until it reaches')}{' '} } + description={ + + } > {t('sufficient liquidity')} @@ -300,7 +306,9 @@ export const useOrderValidation = ({ {t('This market is in auction due to')}{' '} } + description={ + + } > {t('high price volatility')} diff --git a/apps/console-lite/src/app/components/simple-market-list/__generated__/CandleLive.ts b/apps/console-lite/src/app/components/simple-market-list/__generated__/CandleLive.ts deleted file mode 100644 index 6c390a93d..000000000 --- a/apps/console-lite/src/app/components/simple-market-list/__generated__/CandleLive.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ -// @generated -// This file was automatically generated and should not be edited. - -// ==================================================== -// GraphQL subscription operation: CandleLive -// ==================================================== - -export interface CandleLive_candles { - __typename: "Candle"; - /** - * Close price (uint64) - */ - close: string; -} - -export interface CandleLive { - /** - * Subscribe to the candles updates - */ - candles: CandleLive_candles; -} - -export interface CandleLiveVariables { - marketId: string; -} diff --git a/apps/console-lite/src/app/components/simple-market-list/__generated___/Candles.ts b/apps/console-lite/src/app/components/simple-market-list/__generated___/Candles.ts deleted file mode 100644 index 0a71e9633..000000000 --- a/apps/console-lite/src/app/components/simple-market-list/__generated___/Candles.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as Types from '@vegaprotocol/types'; - -import { gql } from '@apollo/client'; -import * as Apollo from '@apollo/client'; -const defaultOptions = {} as const; -export type CandleLiveSubscriptionVariables = Types.Exact<{ - marketId: Types.Scalars['ID']; -}>; - - -export type CandleLiveSubscription = { __typename?: 'Subscription', candles: { __typename?: 'Candle', close: string } }; - - -export const CandleLiveDocument = gql` - subscription CandleLive($marketId: ID!) { - candles(marketId: $marketId, interval: INTERVAL_I1H) { - close - } -} - `; - -/** - * __useCandleLiveSubscription__ - * - * To run a query within a React component, call `useCandleLiveSubscription` and pass it any options that fit your needs. - * When your component renders, `useCandleLiveSubscription` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useCandleLiveSubscription({ - * variables: { - * marketId: // value for 'marketId' - * }, - * }); - */ -export function useCandleLiveSubscription(baseOptions: Apollo.SubscriptionHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useSubscription(CandleLiveDocument, options); - } -export type CandleLiveSubscriptionHookResult = ReturnType; -export type CandleLiveSubscriptionResult = Apollo.SubscriptionResult; \ No newline at end of file diff --git a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx b/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx index 3a416fe8e..6b4a96c83 100644 --- a/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx +++ b/apps/liquidity-provision-dashboard/src/app/components/detail/last-24h-volume/last-24h-volume.tsx @@ -15,7 +15,7 @@ import { import type { Candle } from '@vegaprotocol/market-list'; import { marketCandlesProvider } from '@vegaprotocol/market-list'; -const DEBOUNCE_UPDATE_TIME = 500; +const THROTTLE_UPDATE_TIME = 500; export const Last24hVolume = ({ marketId, @@ -54,7 +54,7 @@ export const Last24hVolume = ({ const throttledSetCandles = useRef( throttle((data: Candle[]) => { setCandleVolume(calcDayVolume(data)); - }, DEBOUNCE_UPDATE_TIME) + }, THROTTLE_UPDATE_TIME) ).current; const update = useCallback( @@ -78,7 +78,7 @@ export const Last24hVolume = ({ throttle((candles: Candle[]) => { const candle24hAgo = candles?.[0]; setVolumeChange(getChange(data || [], candle24hAgo?.close)); - }, DEBOUNCE_UPDATE_TIME) + }, THROTTLE_UPDATE_TIME) ).current; const updateCandle24hAgo = useCallback( diff --git a/apps/trading/assets/.gitkeep b/apps/trading/assets/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/trading/assets/env-config.js b/apps/trading/assets/env-config.js deleted file mode 100644 index b8be63bb5..000000000 --- a/apps/trading/assets/env-config.js +++ /dev/null @@ -1 +0,0 @@ -window._env_ = {}; diff --git a/apps/trading/assets/green-cloud.png b/apps/trading/assets/green-cloud.png deleted file mode 100644 index 08eeb94a55fa141d41cb3116b582d990e1c976b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61657 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 KMNUMnLSTZ_$QBU* diff --git a/apps/trading/assets/poster-image.jpg b/apps/trading/assets/poster-image.jpg deleted file mode 100644 index e11b2801c9bf260bb1bddae262504400c5e20220..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32448 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

Ur(wsOs*hLbsE5v}3>%mG-P5P#)QJjS`(|49 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 PI@Kn3)LQTM?#TZDmDgkM diff --git a/apps/trading/client-pages/market/trade-market-header.tsx b/apps/trading/client-pages/market/trade-market-header.tsx index 494c56e5b..629241077 100644 --- a/apps/trading/client-pages/market/trade-market-header.tsx +++ b/apps/trading/client-pages/market/trade-market-header.tsx @@ -16,7 +16,7 @@ import { MarketMarkPrice } from '../../components/market-mark-price'; import { Last24hPriceChange } from '../../components/last-24h-price-change'; import { Last24hVolume } from '../../components/last-24h-volume'; import { MarketState } from '../../components/market-state'; -import { MarketTradingMode } from '../../components/market-trading-mode'; +import { HeaderStatMarketTradingMode } from '../../components/market-trading-mode'; import { MarketLiquiditySupplied } from '../../components/liquidity-supplied'; import { MarketState as State } from '@vegaprotocol/types'; @@ -64,22 +64,35 @@ export const TradeMarketHeader = ({ > - + + + + + + + + + - - - {asset ? ( ; } export const Last24hPriceChange = ({ marketId, decimalPlaces, initialValue, - isHeader = false, - noUpdate = false, + inViewRoot, }: Props) => { - const [candlesClose, setCandlesClose] = useState( - initialValue || [] - ); + const [ref, inView] = useInView({ root: inViewRoot?.current }); const yesterday = useYesterday(); - // Cache timestamp for yesterday to prevent full unmount of market page when - // a rerender occurs - const yTimestamp = useMemo(() => { - return new Date(yesterday).toISOString(); - }, [yesterday]); - const variables = useMemo( () => ({ marketId: marketId, interval: Schema.Interval.INTERVAL_I1H, - since: yTimestamp, + since: new Date(yesterday).toISOString(), }), - [marketId, yTimestamp] + [marketId, yesterday] ); - const throttledSetCandles = useRef( - throttle((data: Candle[]) => { - if (!noUpdate) { - const candlesClose: string[] = data - .map((candle) => candle?.close) - .filter((c): c is CandleClose => c !== null); - setCandlesClose(candlesClose); - } - }, constants.DEBOUNCE_UPDATE_TIME) - ).current; - const update = useCallback( - ({ data }: { data: Candle[] | null }) => { - if (data) { - throttledSetCandles(data); - } - return true; + const { data, error } = useThrottledDataProvider( + { + dataProvider: marketCandlesProvider, + variables, + skip: !marketId || !inView, }, - [throttledSetCandles] + THROTTLE_UPDATE_TIME ); - const { error } = useDataProvider({ - dataProvider: marketCandlesProvider, - update, - variables, - skip: noUpdate || !marketId, - }); + const candles = + data + ?.map((candle) => candle?.close) + .filter((c): c is CandleClose => c !== null) || initialValue; - const content = useMemo(() => { - if (error || !isNumeric(decimalPlaces)) { - return <>-; - } - return ( - - ); - }, [candlesClose, decimalPlaces, error]); - - return isHeader ? ( - - {content} - - ) : ( - content + if (error || !isNumeric(decimalPlaces)) { + return -; + } + return ( + ); }; diff --git a/apps/trading/components/last-24h-volume/last-24h-volume.tsx b/apps/trading/components/last-24h-volume/last-24h-volume.tsx index b5fa4d052..d1011463f 100644 --- a/apps/trading/components/last-24h-volume/last-24h-volume.tsx +++ b/apps/trading/components/last-24h-volume/last-24h-volume.tsx @@ -1,102 +1,65 @@ +import type { RefObject } from 'react'; +import { useInView } from 'react-intersection-observer'; import { calcCandleVolume, marketCandlesProvider, } from '@vegaprotocol/market-list'; import { addDecimalsFormatNumber, - t, - useDataProvider, + useThrottledDataProvider, useYesterday, isNumeric, } from '@vegaprotocol/react-helpers'; import * as Schema from '@vegaprotocol/types'; -import throttle from 'lodash/throttle'; -import { useCallback, useMemo, useRef, useState } from 'react'; -import * as constants from '../constants'; -import { HeaderStat } from '../header'; +import { useMemo } from 'react'; import type { Candle } from '@vegaprotocol/market-list'; +import { THROTTLE_UPDATE_TIME } from '../constants'; interface Props { marketId?: string; positionDecimalPlaces?: number; - noUpdate?: boolean; - isHeader?: boolean; + formatDecimals?: number; + inViewRoot?: RefObject; initialValue?: string; } export const Last24hVolume = ({ marketId, positionDecimalPlaces, - noUpdate = false, - isHeader = false, + formatDecimals, + inViewRoot, initialValue, }: Props) => { - const [candleVolume, setCandleVolume] = useState(initialValue || ''); const yesterday = useYesterday(); - // Cache timestamp for yesterday to prevent full unmount of market page when - // a rerender occurs - const yTimestamp = useMemo(() => { - return new Date(yesterday).toISOString(); - }, [yesterday]); + const [ref, inView] = useInView({ root: inViewRoot?.current }); const variables = useMemo( () => ({ marketId: marketId, interval: Schema.Interval.INTERVAL_I1H, - since: yTimestamp, + since: new Date(yesterday).toISOString(), }), - [marketId, yTimestamp] + [marketId, yesterday] ); - const throttledSetCandles = useRef( - throttle((data: Candle[]) => { - noUpdate || setCandleVolume(calcCandleVolume(data) || ''); - }, constants.DEBOUNCE_UPDATE_TIME) - ).current; - const update = useCallback( - ({ data }: { data: Candle[] | null }) => { - if (data) { - throttledSetCandles(data); - } - return true; + const { data } = useThrottledDataProvider( + { + dataProvider: marketCandlesProvider, + variables, + skip: !(inView && marketId), }, - [throttledSetCandles] + THROTTLE_UPDATE_TIME ); - - const { error } = useDataProvider({ - dataProvider: marketCandlesProvider, - update, - variables, - skip: noUpdate || !marketId, - }); - - const formatDecimals = isHeader ? positionDecimalPlaces || 0 : 2; - const content = useMemo(() => { - return ( - <> - {!error && candleVolume && isNumeric(positionDecimalPlaces) - ? addDecimalsFormatNumber( - candleVolume, - positionDecimalPlaces, - formatDecimals - ) - : '-'} - - ); - }, [error, candleVolume, positionDecimalPlaces, formatDecimals]); - return isHeader ? ( - - {content} - - ) : ( - content + const candleVolume = data ? calcCandleVolume(data) : initialValue; + return ( + + {candleVolume && isNumeric(positionDecimalPlaces) + ? addDecimalsFormatNumber( + candleVolume, + positionDecimalPlaces, + formatDecimals + ) + : '-'} + ); }; diff --git a/apps/trading/components/market-mark-price/market-mark-price.tsx b/apps/trading/components/market-mark-price/market-mark-price.tsx index 3f45eebc1..423b23ed3 100644 --- a/apps/trading/components/market-mark-price/market-mark-price.tsx +++ b/apps/trading/components/market-mark-price/market-mark-price.tsx @@ -1,10 +1,10 @@ -import { useCallback, useMemo, useRef, useState } from 'react'; -import throttle from 'lodash/throttle'; +import type { RefObject } from 'react'; +import { useMemo } from 'react'; +import { useInView } from 'react-intersection-observer'; import { addDecimalsFormatNumber, - t, PriceCell, - useDataProvider, + useThrottledDataProvider, isNumeric, } from '@vegaprotocol/react-helpers'; import type { @@ -12,14 +12,13 @@ import type { MarketDataUpdateFieldsFragment, } from '@vegaprotocol/market-list'; import { marketDataProvider } from '@vegaprotocol/market-list'; -import { HeaderStat } from '../header'; -import * as constants from '../constants'; +import { THROTTLE_UPDATE_TIME } from '../constants'; interface Props { marketId?: string; decimalPlaces?: number; - isHeader?: boolean; - noUpdate?: boolean; + asPriceCell?: boolean; + inViewRoot?: RefObject; initialValue?: string; } @@ -27,58 +26,39 @@ export const MarketMarkPrice = ({ marketId, decimalPlaces, initialValue, - isHeader = false, - noUpdate = false, + inViewRoot, + asPriceCell, }: Props) => { - const [marketPrice, setMarketPrice] = useState( - initialValue || null - ); - const variables = useMemo( - () => ({ - marketId: marketId, - }), - [marketId] - ); + const [ref, inView] = useInView({ root: inViewRoot?.current }); + const variables = useMemo(() => ({ marketId }), [marketId]); - const throttledSetMarketPrice = useRef( - throttle((price: string) => { - noUpdate || setMarketPrice(price); - }, constants.DEBOUNCE_UPDATE_TIME) - ).current; - const update = useCallback( - ({ data: marketData }: { data: MarketData | null }) => { - throttledSetMarketPrice(marketData?.markPrice || ''); - return true; + const { data } = useThrottledDataProvider< + MarketData, + MarketDataUpdateFieldsFragment + >( + { + dataProvider: marketDataProvider, + variables, + skip: !inView, }, - [throttledSetMarketPrice] + THROTTLE_UPDATE_TIME ); - useDataProvider({ - dataProvider: marketDataProvider, - update, - variables, - skip: noUpdate || !marketId, - }); + const marketPrice = data?.markPrice || initialValue; - const content = useMemo(() => { - if (!marketPrice || !isNumeric(decimalPlaces)) { - return <>-; - } - return isHeader ? ( -

- ) : ( + if (!marketPrice || !isNumeric(decimalPlaces)) { + return -; + } + if (asPriceCell) { + return ( ); - }, [marketPrice, decimalPlaces, isHeader]); - - return isHeader ? ( - - {content} - - ) : ( - content + } + return ( + {addDecimalsFormatNumber(marketPrice, decimalPlaces)} ); }; diff --git a/apps/trading/components/market-state/market-state.tsx b/apps/trading/components/market-state/market-state.tsx index 4e94e97b6..4c1d91ce0 100644 --- a/apps/trading/components/market-state/market-state.tsx +++ b/apps/trading/components/market-state/market-state.tsx @@ -23,7 +23,7 @@ export const MarketState = ({ const throttledSetMarketState = useRef( throttle((state: Schema.MarketState) => { setMarketState(state); - }, constants.DEBOUNCE_UPDATE_TIME) + }, constants.THROTTLE_UPDATE_TIME) ).current; const update = useCallback( diff --git a/apps/trading/components/market-trading-mode/market-trading-mode.tsx b/apps/trading/components/market-trading-mode/market-trading-mode.tsx index fb25d3b9a..ccb551e79 100644 --- a/apps/trading/components/market-trading-mode/market-trading-mode.tsx +++ b/apps/trading/components/market-trading-mode/market-trading-mode.tsx @@ -1,110 +1,78 @@ -import { useCallback, useMemo, useState } from 'react'; -import { t, useDataProvider } from '@vegaprotocol/react-helpers'; -import type { MarketDealTicket } from '@vegaprotocol/market-list'; -import { compileGridData, TradingModeTooltip } from '@vegaprotocol/deal-ticket'; +import type { RefObject } from 'react'; +import { t } from '@vegaprotocol/react-helpers'; +import { TradingModeTooltip } from '@vegaprotocol/deal-ticket'; +import { useInView } from 'react-intersection-observer'; import * as Schema from '@vegaprotocol/types'; -import type { - MarketData, - MarketDataUpdateFieldsFragment, - SingleMarketFieldsFragment, -} from '@vegaprotocol/market-list'; -import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list'; +import { useStaticMarketData } from '@vegaprotocol/market-list'; import { HeaderStat } from '../header'; import { Tooltip } from '@vegaprotocol/ui-toolkit'; -interface Props { - marketId?: string; - onSelect?: (marketId: string) => void; - isHeader?: boolean; - noUpdate?: boolean; - initialMode?: Schema.MarketTradingMode; - initialTrigger?: Schema.AuctionTrigger; -} - -export const MarketTradingMode = ({ - marketId, - onSelect, - isHeader = false, - noUpdate = false, - initialMode, - initialTrigger, -}: Props) => { - const [tradingMode, setTradingMode] = - useState(initialMode || null); - const [trigger, setTrigger] = useState( - initialTrigger || null - ); - const [market, setMarket] = useState(null); - const variables = useMemo( - () => ({ - marketId: marketId, - }), - [marketId] - ); - - const { data } = useDataProvider({ - dataProvider: marketProvider, - variables, - skip: !marketId, - }); - - const update = useCallback( - ({ data: marketData }: { data: MarketData | null }) => { - if (!noUpdate && marketData) { - setTradingMode(marketData.marketTradingMode); - setTrigger(marketData.trigger); - setMarket({ - ...data, - data: marketData, - } as MarketDealTicket); - } - return true; - }, - [noUpdate, data] - ); - - useDataProvider({ - dataProvider: marketDataProvider, - update, - variables, - skip: noUpdate || !marketId || !data, - }); - - const content = +const getTradingModeLabel = ( + tradingMode?: Schema.MarketTradingMode, + trigger?: Schema.AuctionTrigger +) => { + return ( (tradingMode === Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && trigger && trigger !== Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED ? `${Schema.MarketTradingModeMapping[tradingMode]} - ${Schema.AuctionTriggerMapping[trigger]}` : Schema.MarketTradingModeMapping[ tradingMode as Schema.MarketTradingMode - ]) || '-'; + ]) || '-' + ); +}; - return isHeader ? ( +interface HeaderStatMarketTradingModeProps { + marketId?: string; + onSelect?: (marketId: string) => void; + initialTradingMode?: Schema.MarketTradingMode; + initialTrigger?: Schema.AuctionTrigger; +} + +export const HeaderStatMarketTradingMode = ({ + marketId, + onSelect, + initialTradingMode, + initialTrigger, +}: HeaderStatMarketTradingModeProps) => { + const data = useStaticMarketData(marketId); + const tradingMode = data?.marketTradingMode ?? initialTradingMode; + const trigger = data?.trigger ?? initialTrigger; + + return ( - ) + } testId="market-trading-mode" > -
{content}
+
{getTradingModeLabel(tradingMode, trigger)}
- ) : ( + ); +}; + +export const MarketTradingMode = ({ + marketId, + initialTradingMode, + initialTrigger, + inViewRoot, +}: Omit & { + inViewRoot?: RefObject; +}) => { + const [ref, inView] = useInView({ root: inViewRoot?.current }); + const data = useStaticMarketData(marketId, !inView); + + return ( - ) - } + description={} > - {content} + + {getTradingModeLabel( + data?.marketTradingMode ?? initialTradingMode, + data?.trigger ?? initialTrigger + )} + ); }; diff --git a/apps/trading/components/market-volume/market-volume.tsx b/apps/trading/components/market-volume/market-volume.tsx index 4e2974211..ea5c14baf 100644 --- a/apps/trading/components/market-volume/market-volume.tsx +++ b/apps/trading/components/market-volume/market-volume.tsx @@ -31,7 +31,7 @@ export const MarketVolume = ({ marketId }: { marketId: string }) => { const throttledSetMarketVolume = useRef( throttle((volume: string) => { setMarketVolume(volume); - }, constants.DEBOUNCE_UPDATE_TIME) + }, constants.THROTTLE_UPDATE_TIME) ).current; const update = useCallback( ({ data: marketData }: { data: MarketData | null }) => { diff --git a/apps/trading/components/select-market/select-market-columns.tsx b/apps/trading/components/select-market/select-market-columns.tsx index 86e6ceabd..7c3a97818 100644 --- a/apps/trading/components/select-market/select-market-columns.tsx +++ b/apps/trading/components/select-market/select-market-columns.tsx @@ -1,3 +1,4 @@ +import type { RefObject } from 'react'; import { FeesCell } from '@vegaprotocol/market-info'; import { calcCandleHigh, @@ -173,7 +174,7 @@ export const columns = ( market: Market, onSelect: (id: string) => void, onCellClick: OnCellClickHandler, - activeMarketId?: string | null + inViewRoot?: RefObject ) => { const candlesClose = market.candles ?.map((candle) => candle?.close) @@ -189,7 +190,6 @@ export const columns = ( return onSelect(id); } }; - const noUpdate = !activeMarketId || market.id !== activeMarketId; const selectMarketColumns: Column[] = [ { kind: ColumnKind.Market, @@ -221,8 +221,9 @@ export const columns = ( ), className: `${cellClassNames} max-w-[100px]`, @@ -234,7 +235,7 @@ export const columns = ( ), @@ -317,7 +318,8 @@ export const columns = ( marketId={market.id} positionDecimalPlaces={market.positionDecimalPlaces} initialValue={candleVolume} - noUpdate={noUpdate} + inViewRoot={inViewRoot} + formatDecimals={2} /> ), className: `${cellClassNames} hidden lg:table-cell font-mono`, @@ -329,8 +331,8 @@ export const columns = ( value: ( ), @@ -359,9 +361,9 @@ export const columns = ( export const columnsPositionMarkets = ( market: Market, onSelect: (id: string) => void, + inViewRoot?: RefObject, openVolume?: string, - onCellClick?: OnCellClickHandler, - activeMarketId?: string | null + onCellClick?: OnCellClickHandler ) => { const candlesClose = market.candles ?.map((candle) => candle?.close) @@ -377,7 +379,6 @@ export const columnsPositionMarkets = ( } }; const candleVolume = market.candles && calcCandleVolume(market.candles); - const noUpdate = !activeMarketId || market.id !== activeMarketId; const selectMarketColumns: Column[] = [ { kind: ColumnKind.Market, @@ -409,8 +410,9 @@ export const columnsPositionMarkets = ( ), className: cellClassNames, @@ -422,7 +424,7 @@ export const columnsPositionMarkets = ( ), @@ -503,9 +505,10 @@ export const columnsPositionMarkets = ( value: ( ), className: `${cellClassNames} hidden lg:table-cell font-mono`, @@ -517,8 +520,8 @@ export const columnsPositionMarkets = ( value: ( ), diff --git a/apps/trading/components/select-market/select-market.tsx b/apps/trading/components/select-market/select-market.tsx index 008c72cf8..f2477af20 100644 --- a/apps/trading/components/select-market/select-market.tsx +++ b/apps/trading/components/select-market/select-market.tsx @@ -1,4 +1,5 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState, useRef } from 'react'; +import type { RefObject } from 'react'; import { useMarketList } from '@vegaprotocol/market-list'; import { positionsDataProvider } from '@vegaprotocol/positions'; import { t, useDataProvider } from '@vegaprotocol/react-helpers'; @@ -27,7 +28,6 @@ import { TOKEN_NEW_MARKET_PROPOSAL, useLinks, } from '@vegaprotocol/environment'; -import { useGlobalStore } from '../../stores'; export type Market = MarketWithCandles & MarketWithData; @@ -36,19 +36,22 @@ export const SelectAllMarketsTableBody = ({ positions, onSelect, onCellClick, - activeMarketId, + inViewRoot, headers = columnHeaders, - tableColumns = (market) => - columns(market, onSelect, onCellClick, activeMarketId), + tableColumns = (market) => columns(market, onSelect, onCellClick, inViewRoot), }: { markets?: Market[] | null; positions?: PositionFieldsFragment[]; title?: string; onSelect: (id: string) => void; onCellClick: OnCellClickHandler; - activeMarketId?: string | null; headers?: Column[]; - tableColumns?: (market: Market, openVolume?: string) => Column[]; + tableColumns?: ( + market: Market, + inViewRoot?: RefObject, + openVolume?: string + ) => Column[]; + inViewRoot?: RefObject; }) => { const tokenLink = useLinks(DApp.Token); if (!markets) return null; @@ -68,6 +71,7 @@ export const SelectAllMarketsTableBody = ({ onSelect={onSelect} columns={tableColumns( market, + inViewRoot, positions && positions.find((p) => p.market.id === market.id)?.openVolume )} @@ -95,11 +99,11 @@ export const SelectMarketPopover = ({ onSelect: (id: string) => void; onCellClick: OnCellClickHandler; }) => { - const activeMarketId = useGlobalStore((store) => store.marketId); const triggerClasses = '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 mt-1'; const { pubKey } = useVegaWallet(); const [open, setOpen] = useState(false); + const inViewRoot = useRef(null); const { data, loading: marketsLoading, @@ -155,6 +159,7 @@ export const SelectMarketPopover = ({
{marketsLoading || (pubKey && positionsLoading) ? (
@@ -167,6 +172,7 @@ export const SelectMarketPopover = ({ <> {t('My markets')} edge.node) @@ -174,13 +180,13 @@ export const SelectMarketPopover = ({ onSelect={onSelectMarket} onCellClick={onCellClick} headers={columnHeadersPositionMarkets} - tableColumns={(market, openVolume) => + tableColumns={(market, inViewRoot, openVolume) => columnsPositionMarkets( market, onSelectMarket, + inViewRoot, openVolume, - onCellClick, - activeMarketId + onCellClick ) } /> @@ -188,10 +194,10 @@ export const SelectMarketPopover = ({ ) : null} {t('All markets')} )} diff --git a/apps/trading/setup-tests.ts b/apps/trading/setup-tests.ts index 17e7e61cb..ebaab45f9 100644 --- a/apps/trading/setup-tests.ts +++ b/apps/trading/setup-tests.ts @@ -1,7 +1,9 @@ import '@testing-library/jest-dom'; import 'jest-canvas-mock'; import ResizeObserver from 'resize-observer-polyfill'; +import { defaultFallbackInView } from 'react-intersection-observer'; +defaultFallbackInView(true); global.ResizeObserver = ResizeObserver; // Required by radix-ui/react-tooltip diff --git a/libs/deal-ticket/src/components/deal-ticket/time-in-force-selector.tsx b/libs/deal-ticket/src/components/deal-ticket/time-in-force-selector.tsx index f56fac56e..a64969d90 100644 --- a/libs/deal-ticket/src/components/deal-ticket/time-in-force-selector.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/time-in-force-selector.tsx @@ -78,7 +78,11 @@ export const TimeInForceSelector = ({ return ( {t('This market is in auction until it reaches')}{' '} - }> + + } + > {t('sufficient liquidity')} {'. '} @@ -93,7 +97,11 @@ export const TimeInForceSelector = ({ return ( {t('This market is in auction due to')}{' '} - }> + + } + > {t('high price volatility')} {'. '} diff --git a/libs/deal-ticket/src/components/deal-ticket/type-selector.tsx b/libs/deal-ticket/src/components/deal-ticket/type-selector.tsx index 973c2c5ff..c6add5c08 100644 --- a/libs/deal-ticket/src/components/deal-ticket/type-selector.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/type-selector.tsx @@ -33,7 +33,11 @@ export const TypeSelector = ({ return ( {t('This market is in auction until it reaches')}{' '} - }> + + } + > {t('sufficient liquidity')} {'. '} @@ -46,7 +50,11 @@ export const TypeSelector = ({ return ( {t('This market is in auction due to')}{' '} - }> + + } + > {t('high price volatility')} {'. '} diff --git a/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx b/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx index 1ce35ceb9..60a2e5271 100644 --- a/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx +++ b/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx @@ -8,17 +8,31 @@ import * as Schema from '@vegaprotocol/types'; import { Link as UILink } from '@vegaprotocol/ui-toolkit'; import type { ReactNode } from 'react'; import { Link } from 'react-router-dom'; -import type { MarketDealTicket } from '@vegaprotocol/market-list'; +import type { Market, MarketData } from '@vegaprotocol/market-list'; export const compileGridData = ( - market: MarketDealTicket, + market: Pick< + Market, + 'tradableInstrument' | 'id' | 'decimalPlaces' | 'positionDecimalPlaces' + >, + marketData: Pick< + MarketData, + | 'marketTradingMode' + | 'auctionStart' + | 'auctionEnd' + | 'indicativePrice' + | 'indicativeVolume' + | 'suppliedStake' + | 'targetStake' + | 'trigger' + >, onSelect?: (id: string) => void ): { label: ReactNode; value?: ReactNode }[] => { const grid: DataGridProps['grid'] = []; const isLiquidityMonitoringAuction = - market.data.marketTradingMode === + marketData.marketTradingMode === Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION && - market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY; + marketData.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY; const formatStake = (value: string) => { const formattedValue = addDecimalsFormatNumber( @@ -30,19 +44,17 @@ export const compileGridData = ( return `${formattedValue} ${asset}`; }; - if (!market.data) return grid; + if (!marketData) return grid; - if (market.data.auctionStart) { + if (marketData.auctionStart) { grid.push({ label: t('Auction start'), - value: getDateTimeFormat().format(new Date(market.data.auctionStart)), + value: getDateTimeFormat().format(new Date(marketData.auctionStart)), }); } - if (market.data.auctionEnd) { - const endDate = getDateTimeFormat().format( - new Date(market.data.auctionEnd) - ); + if (marketData.auctionEnd) { + const endDate = getDateTimeFormat().format(new Date(marketData.auctionEnd)); grid.push({ label: isLiquidityMonitoringAuction ? t('Est. auction end') @@ -51,14 +63,14 @@ export const compileGridData = ( }); } - if (isLiquidityMonitoringAuction && market.data.targetStake) { + if (isLiquidityMonitoringAuction && marketData.targetStake) { grid.push({ label: t('Target liquidity'), - value: formatStake(market.data.targetStake), + value: formatStake(marketData.targetStake), }); } - if (isLiquidityMonitoringAuction && market.data.suppliedStake) { + if (isLiquidityMonitoringAuction && marketData.suppliedStake) { grid.push({ label: ( {t('Current liquidity')} ), - value: formatStake(market.data.suppliedStake), + value: formatStake(marketData.suppliedStake), }); } - if (market.data.indicativePrice) { + if (marketData.indicativePrice) { grid.push({ label: t('Est. uncrossing price'), value: - market.data.indicativePrice && market.data.indicativePrice !== '0' + marketData.indicativePrice && marketData.indicativePrice !== '0' ? `~ ${addDecimalsFormatNumber( - market.data.indicativePrice, + marketData.indicativePrice, market.decimalPlaces )}` : '-', }); } - if (market.data.indicativeVolume) { + if (marketData.indicativeVolume) { grid.push({ label: t('Est. uncrossing vol'), value: - market.data.indicativeVolume && market.data.indicativeVolume !== '0' + marketData.indicativeVolume && marketData.indicativeVolume !== '0' ? '~' + addDecimalsFormatNumber( - market.data.indicativeVolume, + marketData.indicativeVolume, market.positionDecimalPlaces ) : '-', diff --git a/libs/deal-ticket/src/components/trading-mode-tooltip/trading-mode-tooltip.tsx b/libs/deal-ticket/src/components/trading-mode-tooltip/trading-mode-tooltip.tsx index d60b52e8a..a6a4042f1 100644 --- a/libs/deal-ticket/src/components/trading-mode-tooltip/trading-mode-tooltip.tsx +++ b/libs/deal-ticket/src/components/trading-mode-tooltip/trading-mode-tooltip.tsx @@ -1,23 +1,35 @@ -import type { ReactNode } from 'react'; import classNames from 'classnames'; import { useEnvironment } from '@vegaprotocol/environment'; import { DataGrid, t } from '@vegaprotocol/react-helpers'; import * as Schema from '@vegaprotocol/types'; import { ExternalLink } from '@vegaprotocol/ui-toolkit'; import { createDocsLinks } from '@vegaprotocol/react-helpers'; +import { compileGridData } from './compile-grid-data'; +import { useMarket, useStaticMarketData } from '@vegaprotocol/market-list'; type TradingModeTooltipProps = { - tradingMode: Schema.MarketTradingMode | null; - trigger: Schema.AuctionTrigger | null; - compiledGrid?: { label: ReactNode; value?: ReactNode }[]; + marketId?: string; + onSelect?: (marketId: string) => void; + skip?: boolean; }; export const TradingModeTooltip = ({ - tradingMode, - trigger, - compiledGrid, + marketId, + onSelect, + skip, }: TradingModeTooltipProps) => { const { VEGA_DOCS_URL } = useEnvironment(); + const market = useMarket(marketId); + const marketData = useStaticMarketData(marketId, skip); + + if (!market || !marketData) { + return null; + } + + const compiledGrid = + onSelect && compileGridData(market, marketData, onSelect); + const { marketTradingMode: tradingMode, trigger } = marketData; + switch (tradingMode) { case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: { return ( diff --git a/libs/market-list/src/lib/market-data-provider.ts b/libs/market-list/src/lib/market-data-provider.ts index df65cb219..a2a5288fb 100644 --- a/libs/market-list/src/lib/market-data-provider.ts +++ b/libs/market-list/src/lib/market-data-provider.ts @@ -1,4 +1,9 @@ import produce from 'immer'; +import { useMemo } from 'react'; +import { + makeDerivedDataProvider, + useDataProvider, +} from '@vegaprotocol/react-helpers'; import { makeDataProvider } from '@vegaprotocol/react-helpers'; import { MarketDataDocument, @@ -39,3 +44,51 @@ export const marketDataProvider = makeDataProvider< getData, getDelta, }); + +export type StaticMarketData = Pick< + MarketData, + | 'marketTradingMode' + | 'auctionStart' + | 'auctionEnd' + | 'indicativePrice' + | 'indicativeVolume' + | 'suppliedStake' + | 'targetStake' + | 'trigger' +>; + +export const staticMarketDataProvider = makeDerivedDataProvider< + StaticMarketData, + never +>([marketDataProvider], (parts, variables, prevData) => { + const marketData = parts[0] as ReturnType; + if (!marketData) { + return marketData; + } + const data: StaticMarketData = { + marketTradingMode: marketData.marketTradingMode, + auctionStart: marketData.auctionStart, + auctionEnd: marketData.auctionEnd, + indicativePrice: marketData.indicativePrice, + indicativeVolume: marketData.indicativeVolume, + suppliedStake: marketData.suppliedStake, + targetStake: marketData.targetStake, + trigger: marketData.trigger, + }; + if (!prevData) { + return data; + } + return produce(prevData, (draft) => { + Object.assign(draft, data); + }); +}); + +export const useStaticMarketData = (marketId?: string, skip?: boolean) => { + const variables = useMemo(() => ({ marketId }), [marketId]); + const { data } = useDataProvider({ + dataProvider: staticMarketDataProvider, + variables, + skip: skip || !marketId, + }); + return data; +}; diff --git a/libs/market-list/src/lib/markets-provider.ts b/libs/market-list/src/lib/markets-provider.ts index 77e091890..494c5a201 100644 --- a/libs/market-list/src/lib/markets-provider.ts +++ b/libs/market-list/src/lib/markets-provider.ts @@ -35,6 +35,28 @@ export const marketsProvider = makeDataProvider< fetchPolicy: 'cache-first', }); +const marketProvider = makeDerivedDataProvider< + Market, + never, + { marketId: string } +>( + [marketsProvider], + ([markets], variables) => + ((markets as ReturnType) || []).find( + (market) => market.id === variables?.marketId + ) || null +); + +export const useMarket = (marketId?: string) => { + const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]); + const { data } = useDataProvider({ + dataProvider: marketProvider, + variables, + skip: !marketId, + }); + return data; +}; + export const activeMarketsProvider = makeDerivedDataProvider( [marketsProvider], ([markets]) => filterAndSortMarkets(markets) diff --git a/libs/react-helpers/src/lib/format/number.spec.tsx b/libs/react-helpers/src/lib/format/number.spec.tsx index 5a599d519..0dccbc44b 100644 --- a/libs/react-helpers/src/lib/format/number.spec.tsx +++ b/libs/react-helpers/src/lib/format/number.spec.tsx @@ -86,6 +86,8 @@ describe('isNumeric', () => { { i: '--123.01', o: false }, { i: '123.', o: false }, { i: '123.1.1', o: false }, + { i: BigInt(123), o: true }, + { i: BigInt(-1), o: true }, { i: new BigNumber(123), o: true }, { i: new BigNumber(123.123), o: true }, { i: new BigNumber(123.123).toString(), o: true }, @@ -98,7 +100,7 @@ describe('isNumeric', () => { i, o, }: { - i: number | string | undefined | null | BigNumber; + i: number | string | undefined | null | BigNumber | bigint; o: boolean; }) => { expect(isNumeric(i)).toStrictEqual(o); diff --git a/libs/react-helpers/src/lib/format/number.tsx b/libs/react-helpers/src/lib/format/number.tsx index 51f0aea76..14f4be2e3 100644 --- a/libs/react-helpers/src/lib/format/number.tsx +++ b/libs/react-helpers/src/lib/format/number.tsx @@ -138,7 +138,7 @@ export const useNumberParts = ( }; export const isNumeric = ( - value?: string | number | BigNumber | null + value?: string | number | BigNumber | bigint | null ): value is NonNullable => /^-?\d*\.?\d+$/.test(String(value)); const INFINITY = '∞'; diff --git a/libs/react-helpers/src/lib/generic-data-provider.ts b/libs/react-helpers/src/lib/generic-data-provider.ts index 11e45d337..391236db1 100644 --- a/libs/react-helpers/src/lib/generic-data-provider.ts +++ b/libs/react-helpers/src/lib/generic-data-provider.ts @@ -560,7 +560,8 @@ export type CombineDerivedData< Variables extends OperationVariables = OperationVariables > = ( data: DerivedPart['data'][], - variables?: Variables + variables: Variables | undefined, + prevData: Data | null ) => Data | null; export type CombineDerivedDelta< @@ -641,7 +642,8 @@ function makeDerivedDataProviderInternal< const newData = newLoaded ? combineData( parts.map((part) => part.data), - variables + variables, + data ) : data; if ( @@ -655,7 +657,7 @@ function makeDerivedDataProviderInternal< loaded = newLoaded; const previousData = data; data = newData; - if (newLoaded) { + if (loaded) { const updatedPart = parts[updatedPartIndex]; if (updatedPart.isUpdate) { isUpdate = true; diff --git a/libs/react-helpers/src/lib/grid/price-cell.tsx b/libs/react-helpers/src/lib/grid/price-cell.tsx index 09945c91a..15a141dac 100644 --- a/libs/react-helpers/src/lib/grid/price-cell.tsx +++ b/libs/react-helpers/src/lib/grid/price-cell.tsx @@ -1,37 +1,41 @@ -import React from 'react'; -import { getDecimalSeparator } from '../format'; +import { memo, forwardRef } from 'react'; +import { getDecimalSeparator, isNumeric } from '../format'; export interface IPriceCellProps { value: number | bigint | null | undefined; valueFormatted: string; testId?: string; } -export const PriceCell = React.memo( - ({ value, valueFormatted, testId }: IPriceCellProps) => { - if ( - (!value && value !== 0) || - (typeof value === 'number' && isNaN(Number(value))) - ) { - return -; +export const PriceCell = memo( + forwardRef( + ({ value, valueFormatted, testId }: IPriceCellProps, ref) => { + if (!isNumeric(value)) { + return ( + + - + + ); + } + const decimalSeparator = getDecimalSeparator(); + const valueSplit: string[] = decimalSeparator + ? valueFormatted.split(decimalSeparator).map((v) => `${v}`) + : [`${value}`]; + return ( + + {valueSplit[0]} + {valueSplit[1] ? decimalSeparator : null} + {valueSplit[1] ? ( + {valueSplit[1]} + ) : null} + + ); } - const decimalSeparator = getDecimalSeparator(); - const valueSplit: string[] = decimalSeparator - ? valueFormatted.split(decimalSeparator).map((v) => `${v}`) - : [`${value}`]; - return ( - - {valueSplit[0]} - {valueSplit[1] ? decimalSeparator : null} - {valueSplit[1] ? ( - {valueSplit[1]} - ) : null} - - ); - } + ) ); PriceCell.displayName = 'PriceCell'; diff --git a/libs/ui-toolkit/src/components/price-change/price-change-cell.tsx b/libs/ui-toolkit/src/components/price-change/price-change-cell.tsx index dfd9830f2..dbda4080b 100644 --- a/libs/ui-toolkit/src/components/price-change/price-change-cell.tsx +++ b/libs/ui-toolkit/src/components/price-change/price-change-cell.tsx @@ -3,7 +3,7 @@ import { formatNumberPercentage, } from '@vegaprotocol/react-helpers'; import BigNumber from 'bignumber.js'; -import React from 'react'; +import { memo, forwardRef } from 'react'; import { signedNumberCssClass } from '@vegaprotocol/react-helpers'; import { Arrow } from '../arrows/arrow'; @@ -36,30 +36,33 @@ export const priceChange = (candles: string[]) => { : 0; }; -export const PriceCellChange = React.memo( - ({ candles, decimalPlaces }: PriceChangeCellProps) => { - const change = priceChange(candles); - const changePercentage = priceChangePercentage(candles); - return ( - - - - {formatNumberPercentage( - new BigNumber(changePercentage.toString()), - 2 - )} -   +export const PriceCellChange = memo( + forwardRef( + ({ candles, decimalPlaces }: PriceChangeCellProps, ref) => { + const change = priceChange(candles); + const changePercentage = priceChangePercentage(candles); + return ( + + + + {formatNumberPercentage( + new BigNumber(changePercentage.toString()), + 2 + )} +   + + + {addDecimalsFormatNumber(change.toString(), decimalPlaces ?? 0, 3)} + - - {addDecimalsFormatNumber(change.toString(), decimalPlaces ?? 0, 3)} - - - ); - } + ); + } + ) ); PriceCellChange.displayName = 'PriceCellChange';