vega-frontend-monorepo/apps/trading/client-pages/market/trade-grid.tsx
Matthew Russell 68e0009ab0
feat(trading,markets,proposals): market banners (#5494)
Co-authored-by: bwallacee <ben@vega.xyz>
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2024-01-02 11:04:43 +00:00

252 lines
8.8 KiB
TypeScript

import { memo, type ReactNode } from 'react';
import { LayoutPriority } from 'allotment';
import classNames from 'classnames';
import AutoSizer from 'react-virtualized-auto-sizer';
import { useFeatureFlags } from '@vegaprotocol/environment';
import { type PinnedAsset } from '@vegaprotocol/accounts';
import { type Market } from '@vegaprotocol/markets';
import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit';
import {
ResizableGrid,
ResizableGridPanel,
usePaneLayout,
} from '../../components/resizable-grid';
import { TradingViews } from './trade-views';
import { useT } from '../../lib/use-t';
import { ErrorBoundary } from '../../components/error-boundary';
import { MarketBanner } from '../../components/market-banner';
interface TradeGridProps {
market: Market;
pinnedAsset?: PinnedAsset | undefined;
}
const MainGrid = memo(
({ market, pinnedAsset }: { market: Market; pinnedAsset?: PinnedAsset }) => {
const featureFlags = useFeatureFlags((state) => state.flags);
const t = useT();
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'top' });
const [sizesMiddle, handleOnMiddleLayoutChange] = usePaneLayout({
id: 'middle-1',
});
return (
<ResizableGrid vertical onChange={handleOnLayoutChange}>
<ResizableGridPanel
preferredSize={sizes[0]}
priority={LayoutPriority.High}
minSize={200}
>
<ResizableGrid onChange={handleOnMiddleLayoutChange}>
<ResizableGridPanel
priority={LayoutPriority.High}
minSize={200}
preferredSize={sizesMiddle[0] || '75%'}
>
<TradeGridChild>
<Tabs storageKey="console-trade-grid-main-left">
<Tab
id="chart"
overflowHidden
name={t('Chart')}
menu={<TradingViews.chart.menu />}
>
<ErrorBoundary feature="chart">
<TradingViews.chart.component marketId={market.id} />
</ErrorBoundary>
</Tab>
<Tab id="depth" name={t('Depth')}>
<ErrorBoundary feature="depth">
<TradingViews.depth.component marketId={market.id} />
</ErrorBoundary>
</Tab>
<Tab id="liquidity" name={t('Liquidity')}>
<ErrorBoundary feature="liquidity">
<TradingViews.liquidity.component marketId={market.id} />
</ErrorBoundary>
</Tab>
{market &&
market.tradableInstrument.instrument.product.__typename ===
'Perpetual' ? (
<Tab id="funding-history" name={t('Funding history')}>
<ErrorBoundary feature="funding-history">
<TradingViews.funding.component marketId={market.id} />
</ErrorBoundary>
</Tab>
) : null}
{market &&
market.tradableInstrument.instrument.product.__typename ===
'Perpetual' ? (
<Tab
id="funding-payments"
name={t('Funding payments')}
settings={<TradingViews.fundingPayments.settings />}
>
<ErrorBoundary feature="funding-payments">
<TradingViews.fundingPayments.component
marketId={market.id}
/>
</ErrorBoundary>
</Tab>
) : null}
</Tabs>
</TradeGridChild>
</ResizableGridPanel>
<ResizableGridPanel
minSize={200}
preferredSize={sizesMiddle[1] || 275}
>
<TradeGridChild>
<Tabs storageKey="console-trade-grid-main-right">
<Tab id="orderbook" name={t('Orderbook')}>
<ErrorBoundary feature="orderbook">
<TradingViews.orderbook.component marketId={market.id} />
</ErrorBoundary>
</Tab>
<Tab
id="trades"
name={t('Trades')}
settings={<TradingViews.trades.settings />}
>
<ErrorBoundary feature="trades">
<TradingViews.trades.component marketId={market.id} />
</ErrorBoundary>
</Tab>
</Tabs>
</TradeGridChild>
</ResizableGridPanel>
</ResizableGrid>
</ResizableGridPanel>
<ResizableGridPanel
preferredSize={sizes[1] || '25%'}
minSize={50}
priority={LayoutPriority.Low}
>
<TradeGridChild>
<Tabs storageKey="console-trade-grid-bottom">
<Tab
id="positions"
name={t('Positions')}
menu={<TradingViews.positions.menu />}
settings={<TradingViews.positions.settings />}
>
<ErrorBoundary feature="positions">
<TradingViews.positions.component />
</ErrorBoundary>
</Tab>
<Tab
id="open-orders"
name={t('Open')}
menu={<TradingViews.activeOrders.menu />}
settings={<TradingViews.activeOrders.settings />}
>
<ErrorBoundary feature="activeOrders">
<TradingViews.activeOrders.component />
</ErrorBoundary>
</Tab>
<Tab
id="closed-orders"
name={t('Closed')}
settings={<TradingViews.closedOrders.settings />}
>
<ErrorBoundary feature="closedOrders">
<TradingViews.closedOrders.component />
</ErrorBoundary>
</Tab>
<Tab
id="rejected-orders"
name={t('Rejected')}
settings={<TradingViews.rejectedOrders.settings />}
>
<ErrorBoundary feature="rejectedOrders">
<TradingViews.rejectedOrders.component />
</ErrorBoundary>
</Tab>
<Tab
id="orders"
name={t('All')}
menu={<TradingViews.orders.menu />}
settings={<TradingViews.orders.settings />}
>
<ErrorBoundary feature="orders">
<TradingViews.orders.component />
</ErrorBoundary>
</Tab>
{featureFlags.STOP_ORDERS ? (
<Tab
id="stop-orders"
name={t('Stop orders')}
settings={<TradingViews.stopOrders.settings />}
>
<ErrorBoundary feature="stop-orders">
<TradingViews.stopOrders.component />
</ErrorBoundary>
</Tab>
) : null}
<Tab
id="fills"
name={t('Fills')}
settings={<TradingViews.fills.settings />}
>
<TradingViews.fills.component />
</Tab>
<Tab
id="accounts"
name={t('Collateral')}
menu={<TradingViews.collateral.menu />}
settings={<TradingViews.collateral.settings />}
>
<ErrorBoundary feature="collateral">
<TradingViews.collateral.component
pinnedAsset={pinnedAsset}
/>
</ErrorBoundary>
</Tab>
</Tabs>
</TradeGridChild>
</ResizableGridPanel>
</ResizableGrid>
);
}
);
MainGrid.displayName = 'MainGrid';
export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
const wrapperClasses = classNames(
'h-full grid',
'grid-rows-[min-content_1fr]'
);
return (
<div className={wrapperClasses}>
<div>
<MarketBanner market={market} />
</div>
<div className="min-h-0 p-0.5">
<MainGrid market={market} pinnedAsset={pinnedAsset} />
</div>
</div>
);
};
interface TradeGridChildProps {
children: ReactNode;
}
const TradeGridChild = ({ children }: TradeGridChildProps) => {
return (
<section className="h-full p-1">
<AutoSizer>
{({ width, height }) => (
<div
style={{ width, height }}
className="border rounded-sm border-default"
>
{children}
</div>
)}
</AutoSizer>
</section>
);
};