feat(trading): deposit to trade collateral tab pinned row
This commit is contained in:
@@ -96,7 +96,15 @@ export const MarketPage = () => {
|
||||
|
||||
const tradeView = useMemo(() => {
|
||||
if (w > 960) {
|
||||
return <TradeGrid market={data} onSelect={onSelect} />;
|
||||
return (
|
||||
<TradeGrid
|
||||
market={data}
|
||||
onSelect={onSelect}
|
||||
marketAsset={
|
||||
data?.tradableInstrument.instrument.product.settlementAsset
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TradePanels
|
||||
|
||||
@@ -28,6 +28,7 @@ import { NO_MARKET } from './constants';
|
||||
import { LiquidityContainer } from '../liquidity/liquidity';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
|
||||
type MarketDependantView =
|
||||
| typeof CandlesChartContainer
|
||||
@@ -65,14 +66,17 @@ type TradingView = keyof typeof TradingViews;
|
||||
interface TradeGridProps {
|
||||
market: Market | null;
|
||||
onSelect: (marketId: string) => 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 = ({
|
||||
</Tab>
|
||||
<Tab id="accounts" name={t('Collateral')}>
|
||||
<VegaWalletContainer>
|
||||
<TradingViews.Collateral />
|
||||
<TradingViews.Collateral marketAsset={marketAsset} />
|
||||
</VegaWalletContainer>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -186,11 +190,19 @@ const MainGrid = ({
|
||||
};
|
||||
const MainGridWrapped = memo(MainGrid);
|
||||
|
||||
export const TradeGrid = ({ market, onSelect }: TradeGridProps) => {
|
||||
export const TradeGrid = ({
|
||||
market,
|
||||
onSelect,
|
||||
marketAsset,
|
||||
}: TradeGridProps) => {
|
||||
return (
|
||||
<div className="h-full grid grid-rows-[min-content_1fr]">
|
||||
<TradeMarketHeader market={market} onSelect={onSelect} />
|
||||
<MainGridWrapped marketId={market?.id || ''} onSelect={onSelect} />
|
||||
<MainGridWrapped
|
||||
marketId={market?.id || ''}
|
||||
onSelect={onSelect}
|
||||
marketAsset={marketAsset}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -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<TradingView>('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}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
|
||||
@@ -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<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
@@ -38,6 +41,7 @@ export const AccountManager = ({
|
||||
onClickWithdraw={onClickWithdraw}
|
||||
isReadOnly={isReadOnly}
|
||||
noRowsOverlayComponent={() => null}
|
||||
marketAsset={marketAsset}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { forwardRef, useState } from 'react';
|
||||
import { forwardRef, useMemo, useState } from 'react';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
isNumeric,
|
||||
@@ -14,6 +14,8 @@ import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
|
||||
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
|
||||
import BreakdownTable from './breakdown-table';
|
||||
import type { AccountFields } from './accounts-data-provider';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export interface GetRowsParams extends Omit<IGetRowsParams, 'successCallback'> {
|
||||
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<AgGridReact, AccountTableProps>(
|
||||
({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => {
|
||||
const [openBreakdown, setOpenBreakdown] = useState(false);
|
||||
const [breakdown, setBreakdown] = useState<AccountFields[] | null>(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 (
|
||||
<>
|
||||
<AgGrid
|
||||
@@ -51,6 +83,8 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
sortable: true,
|
||||
}}
|
||||
{...props}
|
||||
rowData={rows}
|
||||
pinnedTopRowData={marketAssetRow ? [marketAssetRow] : undefined}
|
||||
>
|
||||
<AgGridColumn
|
||||
headerName={t('Asset')}
|
||||
@@ -137,38 +171,58 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
type="rightAligned"
|
||||
cellRenderer={({
|
||||
data,
|
||||
api,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
return data ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
) : null;
|
||||
if (!data) return null;
|
||||
else {
|
||||
if (
|
||||
data.asset.id === marketAssetId &&
|
||||
new BigNumber(data.available).isLessThanOrEqualTo(0)
|
||||
) {
|
||||
return (
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit to trade')}
|
||||
</ButtonLink>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
+15
-2
@@ -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<string> | 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<string> | 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<string> | 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<string> | 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user