fix(#2345): positions table link to markets (#2652)

This commit is contained in:
m.ray 2023-01-19 16:53:10 -05:00 committed by GitHub
parent 805e8fbee7
commit e4ada295e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 139 additions and 24 deletions

View File

@ -26,6 +26,8 @@ import { VegaWalletContainer } from '../../components/vega-wallet-container';
import { TradeMarketHeader } from './trade-market-header';
import { NO_MARKET } from './constants';
import { LiquidityContainer } from '../liquidity/liquidity';
import { useNavigate } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
type MarketDependantView =
| typeof CandlesChartContainer
@ -72,6 +74,12 @@ const MainGrid = ({
marketId: string;
onSelect?: (marketId: string) => void;
}) => {
const navigate = useNavigate();
const onMarketClick = (marketId: string) => {
navigate(Links[Routes.MARKET](marketId), {
replace: true,
});
};
return (
<ResizableGrid vertical>
<ResizableGridPanel minSize={75} priority={LayoutPriority.High}>
@ -143,17 +151,23 @@ const MainGrid = ({
<Tabs>
<Tab id="positions" name={t('Positions')}>
<VegaWalletContainer>
<TradingViews.Positions />
<TradingViews.Positions onMarketClick={onMarketClick} />
</VegaWalletContainer>
</Tab>
<Tab id="orders" name={t('Orders')}>
<VegaWalletContainer>
<TradingViews.Orders marketId={marketId} />
<TradingViews.Orders
marketId={marketId}
onMarketClick={onMarketClick}
/>
</VegaWalletContainer>
</Tab>
<Tab id="fills" name={t('Fills')}>
<VegaWalletContainer>
<TradingViews.Fills marketId={marketId} />
<TradingViews.Fills
marketId={marketId}
onMarketClick={onMarketClick}
/>
</VegaWalletContainer>
</Tab>
<Tab id="accounts" name={t('Collateral')}>
@ -195,15 +209,16 @@ const TradeGridChild = ({ children }: TradeGridChildProps) => {
interface TradePanelsProps {
market: SingleMarketFieldsFragment | null;
onSelect: (marketId: string) => void;
onMarketClick?: (marketId: string) => void;
}
export const TradePanels = ({ market, onSelect }: TradePanelsProps) => {
const [view, setView] = useState<TradingView>('Candles');
const renderView = () => {
const Component = memo<{
marketId: string;
onSelect: (marketId: string) => void;
onMarketClick?: (marketId: string) => void;
}>(TradingViews[view]);
if (!Component) {

View File

@ -14,16 +14,26 @@ import { usePageTitleStore } from '../../stores';
import { LedgerContainer } from '@vegaprotocol/ledger';
import { AccountsContainer } from '../../components/accounts-container';
import { AccountHistoryContainer } from './account-history-container';
import { useNavigate } from 'react-router-dom';
import { Links, Routes } from '../../pages/client-router';
export const Portfolio = () => {
const { updateTitle } = usePageTitleStore((store) => ({
updateTitle: store.updateTitle,
}));
const navigate = useNavigate();
useEffect(() => {
updateTitle(titlefy([t('Portfolio')]));
}, [updateTitle]);
const onMarketClick = (marketId: string) => {
navigate(Links[Routes.MARKET](marketId), {
replace: true,
});
};
const wrapperClasses = 'h-full max-h-full flex flex-col';
return (
<div className={wrapperClasses}>
@ -38,17 +48,17 @@ export const Portfolio = () => {
</Tab>
<Tab id="positions" name={t('Positions')}>
<VegaWalletContainer>
<PositionsContainer />
<PositionsContainer onMarketClick={onMarketClick} />
</VegaWalletContainer>
</Tab>
<Tab id="orders" name={t('Orders')}>
<VegaWalletContainer>
<OrderListContainer />
<OrderListContainer onMarketClick={onMarketClick} />
</VegaWalletContainer>
</Tab>
<Tab id="fills" name={t('Fills')}>
<VegaWalletContainer>
<FillsContainer />
<FillsContainer onMarketClick={onMarketClick} />
</VegaWalletContainer>
</Tab>
<Tab id="ledger-entries" name={t('Ledger entries')}>

View File

@ -3,7 +3,13 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { FillsManager } from './fills-manager';
export const FillsContainer = ({ marketId }: { marketId?: string }) => {
export const FillsContainer = ({
marketId,
onMarketClick,
}: {
marketId?: string;
onMarketClick?: (marketId: string) => void;
}) => {
const { pubKey } = useVegaWallet();
if (!pubKey) {
@ -14,5 +20,11 @@ export const FillsContainer = ({ marketId }: { marketId?: string }) => {
);
}
return <FillsManager partyId={pubKey} marketId={marketId} />;
return (
<FillsManager
partyId={pubKey}
marketId={marketId}
onMarketClick={onMarketClick}
/>
);
};

View File

@ -9,9 +9,14 @@ import { useFillsList } from './use-fills-list';
interface FillsManagerProps {
partyId: string;
marketId?: string;
onMarketClick?: (marketId: string) => void;
}
export const FillsManager = ({ partyId, marketId }: FillsManagerProps) => {
export const FillsManager = ({
partyId,
marketId,
onMarketClick,
}: FillsManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const scrolledToTop = useRef(true);
const { data, error, loading, addNewRows, getRows } = useFillsList({
@ -41,6 +46,7 @@ export const FillsManager = ({ partyId, marketId }: FillsManagerProps) => {
onBodyScrollEnd={onBodyScrollEnd}
onBodyScroll={onBodyScroll}
noRowsOverlayComponent={() => null}
onMarketClick={onMarketClick}
/>
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer

View File

@ -16,7 +16,11 @@ import {
} from '@vegaprotocol/react-helpers';
import * as Schema from '@vegaprotocol/types';
import { AgGridColumn } from 'ag-grid-react';
import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
import type {
VegaICellRendererParams,
VegaValueFormatterParams,
} from '@vegaprotocol/ui-toolkit';
import { Link } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import { forwardRef } from 'react';
import BigNumber from 'bignumber.js';
@ -24,10 +28,11 @@ import type { Trade } from './fills-data-provider';
export type Props = (AgGridReactProps | AgReactUiProps) & {
partyId: string;
onMarketClick?: (marketId: string) => void;
};
export const FillsTable = forwardRef<AgGridReact, Props>(
({ partyId, ...props }, ref) => {
({ partyId, onMarketClick, ...props }, ref) => {
return (
<AgGrid
ref={ref}
@ -42,6 +47,25 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
<AgGridColumn
headerName={t('Market')}
field="market.tradableInstrument.instrument.name"
cellRenderer={({
value,
data,
}: VegaICellRendererParams<
Trade,
'market.tradableInstrument.instrument.name'
>) =>
onMarketClick ? (
<Link
onClick={() =>
data?.market?.id && onMarketClick(data?.market?.id)
}
>
{value}
</Link>
) : (
value
)
}
/>
<AgGridColumn
headerName={t('Size')}

View File

@ -3,12 +3,24 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { OrderListManager } from './order-list-manager';
export const OrderListContainer = ({ marketId }: { marketId?: string }) => {
export const OrderListContainer = ({
marketId,
onMarketClick,
}: {
marketId?: string;
onMarketClick?: (marketId: string) => void;
}) => {
const { pubKey } = useVegaWallet();
if (!pubKey) {
return <Splash>{t('Please connect Vega wallet')}</Splash>;
}
return <OrderListManager partyId={pubKey} marketId={marketId} />;
return (
<OrderListManager
partyId={pubKey}
marketId={marketId}
onMarketClick={onMarketClick}
/>
);
};

View File

@ -30,6 +30,7 @@ import type { Order } from '../order-data-provider';
export interface OrderListManagerProps {
partyId: string;
marketId?: string;
onMarketClick?: (marketId: string) => void;
}
export const TransactionComplete = ({
@ -70,6 +71,7 @@ export const TransactionComplete = ({
export const OrderListManager = ({
partyId,
marketId,
onMarketClick,
}: OrderListManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const scrolledToTop = useRef(true);
@ -143,6 +145,7 @@ export const OrderListManager = ({
});
}}
setEditOrder={setEditOrder}
onMarketClick={onMarketClick}
/>
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer

View File

@ -31,10 +31,11 @@ type OrderListProps = TypedDataAgGrid<Order> & { marketId?: string };
export type OrderListTableProps = OrderListProps & {
cancel: (order: Order) => void;
setEditOrder: (order: Order) => void;
onMarketClick?: (marketId: string) => void;
};
export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
({ cancel, setEditOrder, ...props }, ref) => {
({ cancel, setEditOrder, onMarketClick, ...props }, ref) => {
return (
<AgGrid
ref={ref}
@ -58,8 +59,14 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
Order,
'market.tradableInstrument.instrument.code'
>) =>
data?.market?.id ? (
<Link href={`/#/markets/${data?.market?.id}`}>{value}</Link>
onMarketClick ? (
<Link
onClick={() =>
data?.market?.id && onMarketClick(data?.market?.id)
}
>
{value}
</Link>
) : (
value
)

View File

@ -3,7 +3,11 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { PositionsManager } from './positions-manager';
export const PositionsContainer = () => {
export const PositionsContainer = ({
onMarketClick,
}: {
onMarketClick?: (marketId: string) => void;
}) => {
const { pubKey } = useVegaWallet();
if (!pubKey) {
@ -13,6 +17,5 @@ export const PositionsContainer = () => {
</Splash>
);
}
return <PositionsManager partyId={pubKey} />;
return <PositionsManager partyId={pubKey} onMarketClick={onMarketClick} />;
};

View File

@ -8,9 +8,13 @@ import { t } from '@vegaprotocol/react-helpers';
interface PositionsManagerProps {
partyId: string;
onMarketClick?: (marketId: string) => void;
}
export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
export const PositionsManager = ({
partyId,
onMarketClick,
}: PositionsManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const { data, error, loading, getRows } = usePositionsData(partyId, gridRef);
const create = useVegaTransactionStore((store) => store.create);
@ -21,6 +25,7 @@ export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
rowModelType="infinite"
ref={gridRef}
datasource={{ getRows }}
onMarketClick={onMarketClick}
onClose={({ marketId, openVolume }) =>
create({
batchMarketInstructions: {

View File

@ -20,7 +20,7 @@ import {
DateRangeFilter,
addDecimalsFormatNumber,
} from '@vegaprotocol/react-helpers';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid, Link } from '@vegaprotocol/ui-toolkit';
import { AgGridColumn } from 'ag-grid-react';
import type { AgGridReact } from 'ag-grid-react';
import type { Position } from './positions-data-providers';
@ -31,6 +31,7 @@ import type { VegaICellRendererParams } from '@vegaprotocol/ui-toolkit';
interface Props extends TypedDataAgGrid<Position> {
onClose?: (data: Position) => void;
onMarketClick?: (id: string) => void;
style?: CSSProperties;
}
@ -66,7 +67,7 @@ export const AmountCell = ({ valueFormatted }: AmountCellProps) => {
AmountCell.displayName = 'AmountCell';
export const PositionsTable = forwardRef<AgGridReact, Props>(
({ onClose, ...props }, ref) => {
({ onClose, onMarketClick, ...props }, ref) => {
return (
<AgGrid
style={{ width: '100%', height: '100%' }}
@ -85,7 +86,24 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
components={{ AmountCell, PriceFlashCell, ProgressBarCell }}
{...props}
>
<AgGridColumn headerName={t('Market')} field="marketName" />
<AgGridColumn
headerName={t('Market')}
field="marketName"
cellRenderer={({
value,
data,
}: VegaICellRendererParams<Position, 'marketName'>) =>
onMarketClick ? (
<Link
onClick={() => data?.marketId && onMarketClick(data?.marketId)}
>
{value}
</Link>
) : (
value
)
}
/>
<AgGridColumn
headerName={t('Notional')}
headerTooltip={t('Mark price x open volume.')}