From b1cfd36f07c73764bbb8658a9bee2353bc6a17fa Mon Sep 17 00:00:00 2001 From: Madalina Raicu Date: Wed, 15 Feb 2023 20:15:58 +0000 Subject: [PATCH] feat(trading): deposit to trade collateral tab pinned row --- apps/trading/client-pages/market/market.tsx | 10 +- .../client-pages/market/trade-grid.tsx | 22 +++- .../accounts-container/accounts-container.tsx | 3 +- libs/accounts/src/lib/accounts-manager.tsx | 4 + libs/accounts/src/lib/accounts-table.tsx | 118 +++++++++++++----- .../src/lib/__generated__/markets.ts | 17 ++- libs/market-list/src/lib/markets.graphql | 14 +++ 7 files changed, 149 insertions(+), 39 deletions(-) diff --git a/apps/trading/client-pages/market/market.tsx b/apps/trading/client-pages/market/market.tsx index 99e8054ae..fd0b7b589 100644 --- a/apps/trading/client-pages/market/market.tsx +++ b/apps/trading/client-pages/market/market.tsx @@ -96,7 +96,15 @@ export const MarketPage = () => { const tradeView = useMemo(() => { if (w > 960) { - return ; + return ( + + ); } return ( void; + marketAsset?: Asset; } const MainGrid = ({ marketId, onSelect, + marketAsset, }: { marketId: string; onSelect?: (marketId: string) => void; + marketAsset?: Asset; }) => { const navigate = useNavigate(); const onMarketClick = (marketId: string) => { @@ -175,7 +179,7 @@ const MainGrid = ({ - + @@ -186,11 +190,19 @@ const MainGrid = ({ }; const MainGridWrapped = memo(MainGrid); -export const TradeGrid = ({ market, onSelect }: TradeGridProps) => { +export const TradeGrid = ({ + market, + onSelect, + marketAsset, +}: TradeGridProps) => { return (
- +
); }; @@ -214,12 +226,14 @@ interface TradePanelsProps { onSelect: (marketId: string) => void; onMarketClick?: (marketId: string) => void; onClickCollateral: () => void; + marketAsset?: Asset; } export const TradePanels = ({ market, onSelect, onClickCollateral, + marketAsset, }: TradePanelsProps) => { const [view, setView] = useState('Candles'); const renderView = () => { @@ -228,6 +242,7 @@ export const TradePanels = ({ onSelect: (marketId: string) => void; onMarketClick?: (marketId: string) => void; onClickCollateral: () => void; + marketAsset?: Asset; }>(TradingViews[view]); if (!Component) { @@ -241,6 +256,7 @@ export const TradePanels = ({ marketId={market?.id} onSelect={onSelect} onClickCollateral={onClickCollateral} + marketAsset={marketAsset} /> ); }; diff --git a/apps/trading/components/accounts-container/accounts-container.tsx b/apps/trading/components/accounts-container/accounts-container.tsx index d1fa0c7f8..e190d4561 100644 --- a/apps/trading/components/accounts-container/accounts-container.tsx +++ b/apps/trading/components/accounts-container/accounts-container.tsx @@ -8,7 +8,7 @@ import { useVegaWallet } from '@vegaprotocol/wallet'; import { AccountManager, useTransferDialog } from '@vegaprotocol/accounts'; import { useDepositDialog } from '@vegaprotocol/deposits'; -export const AccountsContainer = () => { +export const AccountsContainer = ({ marketAsset }: { marketAsset?: Asset }) => { const { pubKey, isReadOnly } = useVegaWallet(); const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore(); const openWithdrawalDialog = useWithdrawalDialog((store) => store.open); @@ -39,6 +39,7 @@ export const AccountsContainer = () => { onClickWithdraw={openWithdrawalDialog} onClickDeposit={openDepositDialog} isReadOnly={isReadOnly} + marketAsset={marketAsset} /> {!isReadOnly && ( diff --git a/libs/accounts/src/lib/accounts-manager.tsx b/libs/accounts/src/lib/accounts-manager.tsx index d8c8194a0..f2757ffea 100644 --- a/libs/accounts/src/lib/accounts-manager.tsx +++ b/libs/accounts/src/lib/accounts-manager.tsx @@ -1,4 +1,5 @@ import { t, useDataProvider } from '@vegaprotocol/react-helpers'; +import type { Asset } from '@vegaprotocol/types'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; import type { AgGridReact } from 'ag-grid-react'; import { useRef, useMemo, memo } from 'react'; @@ -12,6 +13,7 @@ interface AccountManagerProps { onClickWithdraw?: (assetId?: string) => void; onClickDeposit?: (assetId?: string) => void; isReadOnly: boolean; + marketAsset?: Asset; } export const AccountManager = ({ @@ -20,6 +22,7 @@ export const AccountManager = ({ onClickDeposit, partyId, isReadOnly, + marketAsset, }: AccountManagerProps) => { const gridRef = useRef(null); const variables = useMemo(() => ({ partyId }), [partyId]); @@ -38,6 +41,7 @@ export const AccountManager = ({ onClickWithdraw={onClickWithdraw} isReadOnly={isReadOnly} noRowsOverlayComponent={() => null} + marketAsset={marketAsset} />
{ successCallback(rowsThisBlock: AccountFields[], lastRow?: number): void; @@ -30,12 +32,42 @@ export interface AccountTableProps extends AgGridReactProps { onClickWithdraw?: (assetId: string) => void; onClickDeposit?: (assetId: string) => void; isReadOnly: boolean; + marketAsset?: Asset; } export const AccountTable = forwardRef( ({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => { const [openBreakdown, setOpenBreakdown] = useState(false); const [breakdown, setBreakdown] = useState(null); + const marketAssetId = props.marketAsset?.id; + + const marketAssetRow = useMemo( + () => props.rowData?.find((row) => row.asset.id === marketAssetId), + [marketAssetId, props.rowData] + ); + + const rows = useMemo(() => { + const data = props.rowData; + if (!marketAssetRow) { + if (props.marketAsset) { + const accountFields: AccountFields = { + asset: { + ...props.marketAsset, + __typename: 'Asset', + source: undefined, + }, + available: '0', + used: '0', + deposited: '0', + balance: '0', + breakdown: undefined, + }; + return data && [accountFields, ...data]; + } + } + return data; + }, [marketAssetRow, props.marketAsset, props.rowData]); + return ( <> ( sortable: true, }} {...props} + rowData={rows} + pinnedTopRowData={marketAssetRow ? [marketAssetRow] : undefined} > ( type="rightAligned" cellRenderer={({ data, + api, }: VegaICellRendererParams) => { - return data ? ( - <> - { - setOpenBreakdown(!openBreakdown); - setBreakdown(data.breakdown || null); - }} - > - {t('Breakdown')} - - - { - onClickDeposit && onClickDeposit(data.asset.id); - }} - > - {t('Deposit')} - - - - onClickWithdraw && onClickWithdraw(data.asset.id) - } - > - {t('Withdraw')} - - - ) : null; + if (!data) return null; + else { + if ( + data.asset.id === marketAssetId && + new BigNumber(data.available).isLessThanOrEqualTo(0) + ) { + return ( + { + onClickDeposit && onClickDeposit(data.asset.id); + }} + > + {t('Deposit to trade')} + + ); + } else { + return ( + <> + { + setOpenBreakdown(!openBreakdown); + setBreakdown(data.breakdown || null); + }} + > + {t('Breakdown')} + + + { + onClickDeposit && onClickDeposit(data.asset.id); + }} + > + {t('Deposit')} + + + + onClickWithdraw && onClickWithdraw(data.asset.id) + } + > + {t('Withdraw')} + + + ); + } + } }} /> )} diff --git a/libs/market-list/src/lib/__generated__/markets.ts b/libs/market-list/src/lib/__generated__/markets.ts index 58a8df387..74e04bf58 100644 --- a/libs/market-list/src/lib/__generated__/markets.ts +++ b/libs/market-list/src/lib/__generated__/markets.ts @@ -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 MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; +export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', quantum: string, status: Types.AssetStatus, id: string, symbol: string, name: string, decimals: number, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string } }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; export type MarketsQueryVariables = Types.Exact<{ [key: string]: never; }>; -export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; +export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', quantum: string, status: Types.AssetStatus, id: string, symbol: string, name: string, decimals: number, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string, lifetimeLimit: string, withdrawThreshold: string } }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; export const MarketFieldsFragmentDoc = gql` fragment MarketFields on Market { @@ -35,6 +35,19 @@ export const MarketFieldsFragmentDoc = gql` product { ... on Future { settlementAsset { + source { + __typename + ... on ERC20 { + contractAddress + lifetimeLimit + withdrawThreshold + } + ... on BuiltinAsset { + maxFaucetAmountMint + } + } + quantum + status id symbol name diff --git a/libs/market-list/src/lib/markets.graphql b/libs/market-list/src/lib/markets.graphql index 445f6a90c..818d6e846 100644 --- a/libs/market-list/src/lib/markets.graphql +++ b/libs/market-list/src/lib/markets.graphql @@ -16,12 +16,26 @@ fragment MarketFields on Market { id name code + metadata { tags } product { ... on Future { settlementAsset { + source { + __typename + ... on ERC20 { + contractAddress + lifetimeLimit + withdrawThreshold + } + ... on BuiltinAsset { + maxFaucetAmountMint + } + } + quantum + status id symbol name