chore(trading): remove unnecessary forwarding of grid refs (#4486)
This commit is contained in:
parent
015e0188ec
commit
1041864ad8
@ -4,12 +4,9 @@ import { depositsProvider } from '@vegaprotocol/deposits';
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { useRef } from 'react';
|
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { useSidebar, ViewType } from '../../components/sidebar';
|
import { useSidebar, ViewType } from '../../components/sidebar';
|
||||||
|
|
||||||
export const DepositsContainer = () => {
|
export const DepositsContainer = () => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const { pubKey, isReadOnly } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
const { data, error } = useDataProvider({
|
const { data, error } = useDataProvider({
|
||||||
dataProvider: depositsProvider,
|
dataProvider: depositsProvider,
|
||||||
@ -24,7 +21,6 @@ export const DepositsContainer = () => {
|
|||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<DepositsTable
|
<DepositsTable
|
||||||
rowData={data}
|
rowData={data}
|
||||||
ref={gridRef}
|
|
||||||
overlayNoRowsTemplate={error ? error.message : t('No deposits')}
|
overlayNoRowsTemplate={error ? error.message : t('No deposits')}
|
||||||
/>
|
/>
|
||||||
{!isReadOnly && (
|
{!isReadOnly && (
|
||||||
|
@ -118,7 +118,6 @@ export const AccountManager = ({
|
|||||||
onMarketClick,
|
onMarketClick,
|
||||||
gridProps,
|
gridProps,
|
||||||
}: AccountManagerProps) => {
|
}: AccountManagerProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const [breakdownAssetId, setBreakdownAssetId] = useState<string>();
|
const [breakdownAssetId, setBreakdownAssetId] = useState<string>();
|
||||||
const { data, error } = useDataProvider({
|
const { data, error } = useDataProvider({
|
||||||
dataProvider: aggregatedAccountsDataProvider,
|
dataProvider: aggregatedAccountsDataProvider,
|
||||||
@ -138,7 +137,6 @@ export const AccountManager = ({
|
|||||||
return (
|
return (
|
||||||
<div className="relative h-full">
|
<div className="relative h-full">
|
||||||
<AccountTable
|
<AccountTable
|
||||||
ref={gridRef}
|
|
||||||
rowData={data}
|
rowData={data}
|
||||||
onClickAsset={onClickAsset}
|
onClickAsset={onClickAsset}
|
||||||
onClickDeposit={onClickDeposit}
|
onClickDeposit={onClickDeposit}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { forwardRef, useMemo, useCallback } from 'react';
|
import { useMemo, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
addDecimalsFormatNumberQuantum,
|
addDecimalsFormatNumberQuantum,
|
||||||
@ -21,7 +21,7 @@ import type {
|
|||||||
RowHeightParams,
|
RowHeightParams,
|
||||||
ColDef,
|
ColDef,
|
||||||
} from 'ag-grid-community';
|
} from 'ag-grid-community';
|
||||||
import type { AgGridReact, AgGridReactProps } from 'ag-grid-react';
|
import type { AgGridReactProps } from 'ag-grid-react';
|
||||||
import type { AccountFields } from './accounts-data-provider';
|
import type { AccountFields } from './accounts-data-provider';
|
||||||
import type { Asset } from '@vegaprotocol/types';
|
import type { Asset } from '@vegaprotocol/types';
|
||||||
import { CenteredGridCellWrapper } from '@vegaprotocol/datagrid';
|
import { CenteredGridCellWrapper } from '@vegaprotocol/datagrid';
|
||||||
@ -75,256 +75,250 @@ export interface AccountTableProps extends AgGridReactProps {
|
|||||||
pinnedAsset?: PinnedAsset;
|
pinnedAsset?: PinnedAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
export const AccountTable = ({
|
||||||
(
|
onClickAsset,
|
||||||
{
|
onClickWithdraw,
|
||||||
onClickAsset,
|
onClickDeposit,
|
||||||
onClickWithdraw,
|
onClickBreakdown,
|
||||||
onClickDeposit,
|
onClickTransfer,
|
||||||
onClickBreakdown,
|
rowData,
|
||||||
onClickTransfer,
|
isReadOnly,
|
||||||
rowData,
|
pinnedAsset,
|
||||||
isReadOnly,
|
...props
|
||||||
pinnedAsset,
|
}: AccountTableProps) => {
|
||||||
...props
|
const pinnedRow = useMemo(() => {
|
||||||
|
if (!pinnedAsset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentPinnedAssetRow = rowData?.find(
|
||||||
|
(row) => row.asset.id === pinnedAsset?.id
|
||||||
|
);
|
||||||
|
if (!currentPinnedAssetRow) {
|
||||||
|
return {
|
||||||
|
asset: pinnedAsset,
|
||||||
|
available: '0',
|
||||||
|
used: '0',
|
||||||
|
total: '0',
|
||||||
|
balance: '0',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return currentPinnedAssetRow;
|
||||||
|
}, [pinnedAsset, rowData]);
|
||||||
|
|
||||||
|
const { getRowHeight } = props;
|
||||||
|
|
||||||
|
const getPinnedAssetRowHeight = useCallback(
|
||||||
|
(params: RowHeightParams) => {
|
||||||
|
if (
|
||||||
|
params.node.rowPinned &&
|
||||||
|
params.data.asset.id === pinnedAsset?.id &&
|
||||||
|
new BigNumber(params.data.total).isLessThanOrEqualTo(0)
|
||||||
|
) {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
return getRowHeight ? getRowHeight(params) : undefined;
|
||||||
},
|
},
|
||||||
ref
|
[pinnedAsset?.id, getRowHeight]
|
||||||
) => {
|
);
|
||||||
const pinnedRow = useMemo(() => {
|
|
||||||
if (!pinnedAsset) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const currentPinnedAssetRow = rowData?.find(
|
|
||||||
(row) => row.asset.id === pinnedAsset?.id
|
|
||||||
);
|
|
||||||
if (!currentPinnedAssetRow) {
|
|
||||||
return {
|
|
||||||
asset: pinnedAsset,
|
|
||||||
available: '0',
|
|
||||||
used: '0',
|
|
||||||
total: '0',
|
|
||||||
balance: '0',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return currentPinnedAssetRow;
|
|
||||||
}, [pinnedAsset, rowData]);
|
|
||||||
|
|
||||||
const { getRowHeight } = props;
|
const showDepositButton = pinnedRow?.balance === '0';
|
||||||
|
|
||||||
const getPinnedAssetRowHeight = useCallback(
|
const colDefs = useMemo(() => {
|
||||||
(params: RowHeightParams) => {
|
const defs: ColDef[] = [
|
||||||
if (
|
{
|
||||||
params.node.rowPinned &&
|
headerName: t('Asset'),
|
||||||
params.data.asset.id === pinnedAsset?.id &&
|
field: 'asset.symbol',
|
||||||
new BigNumber(params.data.total).isLessThanOrEqualTo(0)
|
headerTooltip: t(
|
||||||
) {
|
'Asset is the collateral that is deposited into the Vega protocol.'
|
||||||
return 32;
|
),
|
||||||
}
|
cellClass: 'underline',
|
||||||
return getRowHeight ? getRowHeight(params) : undefined;
|
onCellClicked: ({ data }) => {
|
||||||
|
if (data) {
|
||||||
|
onClickAsset(data.asset.id);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[pinnedAsset?.id, getRowHeight]
|
{
|
||||||
);
|
headerName: t('Used'),
|
||||||
|
type: 'rightAligned',
|
||||||
const showDepositButton = pinnedRow?.balance === '0';
|
field: 'used',
|
||||||
|
headerTooltip: t(
|
||||||
const colDefs = useMemo(() => {
|
'Currently allocated to a market as margin or bond. Check the breakdown for details.'
|
||||||
const defs: ColDef[] = [
|
),
|
||||||
{
|
tooltipValueGetter: ({ value, data }) => {
|
||||||
headerName: t('Asset'),
|
if (!value || !data) return null;
|
||||||
field: 'asset.symbol',
|
return addDecimalsFormatNumber(value, data.asset.decimals);
|
||||||
headerTooltip: t(
|
|
||||||
'Asset is the collateral that is deposited into the Vega protocol.'
|
|
||||||
),
|
|
||||||
cellClass: 'underline',
|
|
||||||
onCellClicked: ({ data }) => {
|
|
||||||
if (data) {
|
|
||||||
onClickAsset(data.asset.id);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
onCellClicked: ({ data }) => {
|
||||||
headerName: t('Used'),
|
if (!data || !onClickBreakdown) return;
|
||||||
type: 'rightAligned',
|
onClickBreakdown(data.asset.id);
|
||||||
field: 'used',
|
},
|
||||||
headerTooltip: t(
|
cellRenderer: ({
|
||||||
'Currently allocated to a market as margin or bond. Check the breakdown for details.'
|
data,
|
||||||
),
|
value,
|
||||||
tooltipValueGetter: ({ value, data }) => {
|
}: VegaICellRendererParams<AccountFields, 'used'>) => {
|
||||||
if (!value || !data) return null;
|
if (!value || !data) return '-';
|
||||||
return addDecimalsFormatNumber(value, data.asset.decimals);
|
const percentageUsed = percentageValue(value, data.total);
|
||||||
},
|
const valueFormatted = addDecimalsFormatNumberQuantum(
|
||||||
onCellClicked: ({ data }) => {
|
|
||||||
if (!data || !onClickBreakdown) return;
|
|
||||||
onClickBreakdown(data.asset.id);
|
|
||||||
},
|
|
||||||
cellRenderer: ({
|
|
||||||
data,
|
|
||||||
value,
|
value,
|
||||||
}: VegaICellRendererParams<AccountFields, 'used'>) => {
|
data.asset.decimals,
|
||||||
if (!value || !data) return '-';
|
data.asset.quantum
|
||||||
const percentageUsed = percentageValue(value, data.total);
|
);
|
||||||
const valueFormatted = addDecimalsFormatNumberQuantum(
|
|
||||||
value,
|
|
||||||
data.asset.decimals,
|
|
||||||
data.asset.quantum
|
|
||||||
);
|
|
||||||
|
|
||||||
return data.breakdown ? (
|
return data.breakdown ? (
|
||||||
<>
|
<>
|
||||||
<span className="underline">{valueFormatted}</span>
|
<span className="underline">{valueFormatted}</span>
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={classNames(
|
||||||
colorClass(percentageUsed),
|
colorClass(percentageUsed),
|
||||||
'ml-1 inline-block w-14'
|
'ml-1 inline-block w-14'
|
||||||
)}
|
)}
|
||||||
|
>
|
||||||
|
{percentageUsed.toFixed(2)}%
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="underline">{valueFormatted}</span>
|
||||||
|
<span className="ml-2 inline-block w-14 text-muted">
|
||||||
|
{t('0.00%')}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Available'),
|
||||||
|
field: 'available',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
'Deposited on the network, but not allocated to a market. Free to use for placing orders or providing liquidity.'
|
||||||
|
),
|
||||||
|
tooltipValueGetter: ({ value, data }) => {
|
||||||
|
if (!value || !data) return null;
|
||||||
|
return addDecimalsFormatNumber(value, data.asset.decimals);
|
||||||
|
},
|
||||||
|
cellClass: ({ data }) => {
|
||||||
|
const percentageUsed = percentageValue(data?.used, data?.total);
|
||||||
|
return colorClass(percentageUsed, true);
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<AccountFields, 'available'>) => {
|
||||||
|
if (!value || !data) return '-';
|
||||||
|
return addDecimalsFormatNumberQuantum(
|
||||||
|
value,
|
||||||
|
data.asset.decimals,
|
||||||
|
data.asset.quantum
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
headerName: t('Total'),
|
||||||
|
type: 'rightAligned',
|
||||||
|
field: 'total',
|
||||||
|
headerTooltip: t(
|
||||||
|
'The total amount of each asset on this key. Includes used and available collateral.'
|
||||||
|
),
|
||||||
|
tooltipValueGetter: ({ value, data }) => {
|
||||||
|
if (!value || !data) return null;
|
||||||
|
return addDecimalsFormatNumber(value, data.asset.decimals);
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
value,
|
||||||
|
}: VegaValueFormatterParams<AccountFields, 'total'>) => {
|
||||||
|
if (!data || !value) return '-';
|
||||||
|
return addDecimalsFormatNumberQuantum(
|
||||||
|
value,
|
||||||
|
data.asset.decimals,
|
||||||
|
data.asset.quantum
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colId: 'accounts-actions',
|
||||||
|
field: 'asset.id',
|
||||||
|
...COL_DEFS.actions,
|
||||||
|
minWidth: showDepositButton ? 130 : COL_DEFS.actions.minWidth,
|
||||||
|
maxWidth: showDepositButton ? 130 : COL_DEFS.actions.maxWidth,
|
||||||
|
cellRenderer: ({
|
||||||
|
value: assetId,
|
||||||
|
node,
|
||||||
|
}: VegaICellRendererParams<AccountFields, 'asset.id'>) => {
|
||||||
|
if (!assetId) return null;
|
||||||
|
if (node.rowPinned && node.data?.total === '0') {
|
||||||
|
return (
|
||||||
|
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
variant="primary"
|
||||||
|
data-testid="deposit"
|
||||||
|
onClick={() => {
|
||||||
|
onClickDeposit && onClickDeposit(assetId);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{percentageUsed.toFixed(2)}%
|
<VegaIcon name={VegaIconNames.DEPOSIT} /> {t('Deposit')}
|
||||||
</span>
|
</Button>
|
||||||
</>
|
</CenteredGridCellWrapper>
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<span className="underline">{valueFormatted}</span>
|
|
||||||
<span className="ml-2 inline-block w-14 text-muted">
|
|
||||||
{t('0.00%')}
|
|
||||||
</span>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
},
|
return isReadOnly ? null : (
|
||||||
{
|
<AccountsActionsDropdown
|
||||||
headerName: t('Available'),
|
assetId={assetId}
|
||||||
field: 'available',
|
assetContractAddress={
|
||||||
type: 'rightAligned',
|
node.data?.asset.source?.__typename === 'ERC20'
|
||||||
headerTooltip: t(
|
? node.data.asset.source.contractAddress
|
||||||
'Deposited on the network, but not allocated to a market. Free to use for placing orders or providing liquidity.'
|
: undefined
|
||||||
),
|
}
|
||||||
tooltipValueGetter: ({ value, data }) => {
|
onClickDeposit={() => {
|
||||||
if (!value || !data) return null;
|
onClickDeposit && onClickDeposit(assetId);
|
||||||
return addDecimalsFormatNumber(value, data.asset.decimals);
|
}}
|
||||||
},
|
onClickWithdraw={() => {
|
||||||
cellClass: ({ data }) => {
|
onClickWithdraw && onClickWithdraw(assetId);
|
||||||
const percentageUsed = percentageValue(data?.used, data?.total);
|
}}
|
||||||
return colorClass(percentageUsed, true);
|
onClickBreakdown={() => {
|
||||||
},
|
onClickBreakdown && onClickBreakdown(assetId);
|
||||||
valueFormatter: ({
|
}}
|
||||||
value,
|
onClickTransfer={() => {
|
||||||
data,
|
onClickTransfer && onClickTransfer(assetId);
|
||||||
}: VegaValueFormatterParams<AccountFields, 'available'>) => {
|
}}
|
||||||
if (!value || !data) return '-';
|
/>
|
||||||
return addDecimalsFormatNumberQuantum(
|
);
|
||||||
value,
|
|
||||||
data.asset.decimals,
|
|
||||||
data.asset.quantum
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return defs;
|
||||||
|
}, [
|
||||||
|
onClickAsset,
|
||||||
|
onClickBreakdown,
|
||||||
|
onClickDeposit,
|
||||||
|
onClickWithdraw,
|
||||||
|
onClickTransfer,
|
||||||
|
isReadOnly,
|
||||||
|
showDepositButton,
|
||||||
|
]);
|
||||||
|
|
||||||
{
|
const data = rowData?.filter((data) => data.asset.id !== pinnedAsset?.id);
|
||||||
headerName: t('Total'),
|
|
||||||
type: 'rightAligned',
|
|
||||||
field: 'total',
|
|
||||||
headerTooltip: t(
|
|
||||||
'The total amount of each asset on this key. Includes used and available collateral.'
|
|
||||||
),
|
|
||||||
tooltipValueGetter: ({ value, data }) => {
|
|
||||||
if (!value || !data) return null;
|
|
||||||
return addDecimalsFormatNumber(value, data.asset.decimals);
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
value,
|
|
||||||
}: VegaValueFormatterParams<AccountFields, 'total'>) => {
|
|
||||||
if (!data || !value) return '-';
|
|
||||||
return addDecimalsFormatNumberQuantum(
|
|
||||||
value,
|
|
||||||
data.asset.decimals,
|
|
||||||
data.asset.quantum
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
colId: 'accounts-actions',
|
|
||||||
field: 'asset.id',
|
|
||||||
...COL_DEFS.actions,
|
|
||||||
minWidth: showDepositButton ? 130 : COL_DEFS.actions.minWidth,
|
|
||||||
maxWidth: showDepositButton ? 130 : COL_DEFS.actions.maxWidth,
|
|
||||||
cellRenderer: ({
|
|
||||||
value: assetId,
|
|
||||||
node,
|
|
||||||
}: VegaICellRendererParams<AccountFields, 'asset.id'>) => {
|
|
||||||
if (!assetId) return null;
|
|
||||||
if (node.rowPinned && node.data?.total === '0') {
|
|
||||||
return (
|
|
||||||
<CenteredGridCellWrapper className="h-[30px] justify-end py-1">
|
|
||||||
<Button
|
|
||||||
size="xs"
|
|
||||||
variant="primary"
|
|
||||||
data-testid="deposit"
|
|
||||||
onClick={() => {
|
|
||||||
onClickDeposit && onClickDeposit(assetId);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<VegaIcon name={VegaIconNames.DEPOSIT} /> {t('Deposit')}
|
|
||||||
</Button>
|
|
||||||
</CenteredGridCellWrapper>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return isReadOnly ? null : (
|
|
||||||
<AccountsActionsDropdown
|
|
||||||
assetId={assetId}
|
|
||||||
assetContractAddress={
|
|
||||||
node.data?.asset.source?.__typename === 'ERC20'
|
|
||||||
? node.data.asset.source.contractAddress
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onClickDeposit={() => {
|
|
||||||
onClickDeposit && onClickDeposit(assetId);
|
|
||||||
}}
|
|
||||||
onClickWithdraw={() => {
|
|
||||||
onClickWithdraw && onClickWithdraw(assetId);
|
|
||||||
}}
|
|
||||||
onClickBreakdown={() => {
|
|
||||||
onClickBreakdown && onClickBreakdown(assetId);
|
|
||||||
}}
|
|
||||||
onClickTransfer={() => {
|
|
||||||
onClickTransfer && onClickTransfer(assetId);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return defs;
|
|
||||||
}, [
|
|
||||||
onClickAsset,
|
|
||||||
onClickBreakdown,
|
|
||||||
onClickDeposit,
|
|
||||||
onClickWithdraw,
|
|
||||||
onClickTransfer,
|
|
||||||
isReadOnly,
|
|
||||||
showDepositButton,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const data = rowData?.filter((data) => data.asset.id !== pinnedAsset?.id);
|
return (
|
||||||
|
<AgGrid
|
||||||
return (
|
{...props}
|
||||||
<AgGrid
|
style={{ width: '100%', height: '100%' }}
|
||||||
{...props}
|
getRowId={({ data }: { data: AccountFields }) => data.asset.id}
|
||||||
style={{ width: '100%', height: '100%' }}
|
tooltipShowDelay={500}
|
||||||
getRowId={({ data }: { data: AccountFields }) => data.asset.id}
|
rowData={data}
|
||||||
ref={ref}
|
defaultColDef={{
|
||||||
tooltipShowDelay={500}
|
resizable: true,
|
||||||
rowData={data}
|
tooltipComponent: TooltipCellComponent,
|
||||||
defaultColDef={{
|
sortable: true,
|
||||||
resizable: true,
|
comparator: accountValuesComparator,
|
||||||
tooltipComponent: TooltipCellComponent,
|
}}
|
||||||
sortable: true,
|
columnDefs={colDefs}
|
||||||
comparator: accountValuesComparator,
|
getRowHeight={getPinnedAssetRowHeight}
|
||||||
}}
|
pinnedTopRowData={pinnedRow ? [pinnedRow] : undefined}
|
||||||
columnDefs={colDefs}
|
/>
|
||||||
getRowHeight={getPinnedAssetRowHeight}
|
);
|
||||||
pinnedTopRowData={pinnedRow ? [pinnedRow] : undefined}
|
};
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
@ -21,5 +21,4 @@ export * from './lib/type-helpers';
|
|||||||
|
|
||||||
export * from './lib/cells/grid-progress-bar';
|
export * from './lib/cells/grid-progress-bar';
|
||||||
|
|
||||||
export * from './lib/ag-grid-update';
|
|
||||||
export * from './lib/use-datagrid-events';
|
export * from './lib/use-datagrid-events';
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
import type { MutableRefObject, RefObject } from 'react';
|
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
|
|
||||||
type AnyArray = Array<any> | null; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
|
|
||||||
export const isXOrWasEmpty = (prev?: AnyArray, curr?: AnyArray) =>
|
|
||||||
Boolean(Number(!!prev?.length) ^ Number(!!curr?.length));
|
|
||||||
|
|
||||||
export const updateGridData = (
|
|
||||||
dataRef: MutableRefObject<AnyArray>,
|
|
||||||
data: AnyArray,
|
|
||||||
gridRef: RefObject<AgGridReact>
|
|
||||||
) => {
|
|
||||||
const rerender = isXOrWasEmpty(dataRef.current, data);
|
|
||||||
dataRef.current = data;
|
|
||||||
if (gridRef.current?.api?.getModel().getType() === 'infinite') {
|
|
||||||
gridRef.current?.api?.refreshInfiniteCache();
|
|
||||||
}
|
|
||||||
return !rerender;
|
|
||||||
};
|
|
@ -1,4 +1,4 @@
|
|||||||
import { forwardRef, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
@ -6,7 +6,6 @@ import {
|
|||||||
isNumeric,
|
isNumeric,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
@ -17,10 +16,9 @@ import type { DepositFieldsFragment } from './__generated__/Deposit';
|
|||||||
import { EtherscanLink } from '@vegaprotocol/environment';
|
import { EtherscanLink } from '@vegaprotocol/environment';
|
||||||
import { DepositStatusMapping } from '@vegaprotocol/types';
|
import { DepositStatusMapping } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export const DepositsTable = forwardRef<
|
export const DepositsTable = (
|
||||||
AgGridReact,
|
props: TypedDataAgGrid<DepositFieldsFragment>
|
||||||
TypedDataAgGrid<DepositFieldsFragment>
|
) => {
|
||||||
>((props, ref) => {
|
|
||||||
const columnDefs = useMemo<ColDef[]>(
|
const columnDefs = useMemo<ColDef[]>(
|
||||||
() => [
|
() => [
|
||||||
{ headerName: 'Asset', field: 'asset.symbol' },
|
{ headerName: 'Asset', field: 'asset.symbol' },
|
||||||
@ -79,11 +77,10 @@ export const DepositsTable = forwardRef<
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
ref={ref}
|
|
||||||
defaultColDef={{ flex: 1 }}
|
defaultColDef={{ flex: 1 }}
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type * as Schema from '@vegaprotocol/types';
|
import type * as Schema from '@vegaprotocol/types';
|
||||||
import type { FilterChangedEvent } from 'ag-grid-community';
|
import type { FilterChangedEvent } from 'ag-grid-community';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import { useCallback, useState, useMemo } from 'react';
|
||||||
import { useCallback, useRef, useState, useMemo } from 'react';
|
|
||||||
import { subDays, formatRFC3339 } from 'date-fns';
|
import { subDays, formatRFC3339 } from 'date-fns';
|
||||||
import { ledgerEntriesProvider } from './ledger-entries-data-provider';
|
import { ledgerEntriesProvider } from './ledger-entries-data-provider';
|
||||||
import type { LedgerEntriesQueryVariables } from './__generated__/LedgerEntries';
|
import type { LedgerEntriesQueryVariables } from './__generated__/LedgerEntries';
|
||||||
@ -32,7 +31,6 @@ export const LedgerManager = ({
|
|||||||
partyId: string;
|
partyId: string;
|
||||||
gridProps: ReturnType<typeof useDataGridEvents>;
|
gridProps: ReturnType<typeof useDataGridEvents>;
|
||||||
}) => {
|
}) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const [filter, setFilter] = useState<Filter>(defaultFilter);
|
const [filter, setFilter] = useState<Filter>(defaultFilter);
|
||||||
|
|
||||||
const variables = useMemo<LedgerEntriesQueryVariables>(
|
const variables = useMemo<LedgerEntriesQueryVariables>(
|
||||||
@ -64,7 +62,6 @@ export const LedgerManager = ({
|
|||||||
return (
|
return (
|
||||||
<div className="h-full relative">
|
<div className="h-full relative">
|
||||||
<LedgerTable
|
<LedgerTable
|
||||||
ref={gridRef}
|
|
||||||
rowData={data}
|
rowData={data}
|
||||||
overlayNoRowsTemplate={error ? error.message : t('No entries')}
|
overlayNoRowsTemplate={error ? error.message : t('No entries')}
|
||||||
{...gridProps}
|
{...gridProps}
|
||||||
|
@ -14,7 +14,6 @@ import {
|
|||||||
DateRangeFilter,
|
DateRangeFilter,
|
||||||
SetFilter,
|
SetFilter,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type * as Types from '@vegaprotocol/types';
|
import type * as Types from '@vegaprotocol/types';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import {
|
import {
|
||||||
@ -23,7 +22,7 @@ import {
|
|||||||
TransferTypeMapping,
|
TransferTypeMapping,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import type { LedgerEntry } from './ledger-entries-data-provider';
|
import type { LedgerEntry } from './ledger-entries-data-provider';
|
||||||
import { forwardRef, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { formatRFC3339, subDays } from 'date-fns';
|
import { formatRFC3339, subDays } from 'date-fns';
|
||||||
|
|
||||||
export const TransferTooltipCellComponent = ({
|
export const TransferTooltipCellComponent = ({
|
||||||
@ -45,162 +44,159 @@ const dateRangeFilterParams = {
|
|||||||
};
|
};
|
||||||
type LedgerEntryProps = TypedDataAgGrid<LedgerEntry>;
|
type LedgerEntryProps = TypedDataAgGrid<LedgerEntry>;
|
||||||
|
|
||||||
export const LedgerTable = forwardRef<AgGridReact, LedgerEntryProps>(
|
export const LedgerTable = (props: LedgerEntryProps) => {
|
||||||
(props, ref) => {
|
const columnDefs = useMemo<ColDef[]>(
|
||||||
const columnDefs = useMemo<ColDef[]>(
|
() => [
|
||||||
() => [
|
{
|
||||||
{
|
headerName: t('Sender'),
|
||||||
headerName: t('Sender'),
|
field: 'fromAccountPartyId',
|
||||||
field: 'fromAccountPartyId',
|
cellRenderer: ({
|
||||||
cellRenderer: ({
|
value,
|
||||||
value,
|
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountPartyId'>) =>
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountPartyId'>) =>
|
truncateByChars(value || ''),
|
||||||
truncateByChars(value || ''),
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Account type'),
|
||||||
|
filter: SetFilter,
|
||||||
|
filterParams: {
|
||||||
|
set: AccountTypeMapping,
|
||||||
},
|
},
|
||||||
{
|
field: 'fromAccountType',
|
||||||
headerName: t('Account type'),
|
cellRenderer: ({
|
||||||
filter: SetFilter,
|
value,
|
||||||
filterParams: {
|
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountType'>) =>
|
||||||
set: AccountTypeMapping,
|
value ? AccountTypeMapping[value] : '-',
|
||||||
},
|
},
|
||||||
field: 'fromAccountType',
|
{
|
||||||
cellRenderer: ({
|
headerName: t('Market'),
|
||||||
value,
|
field: 'marketSender.tradableInstrument.instrument.code',
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountType'>) =>
|
cellRenderer: ({
|
||||||
value ? AccountTypeMapping[value] : '-',
|
value,
|
||||||
|
}: VegaValueFormatterParams<
|
||||||
|
LedgerEntry,
|
||||||
|
'marketSender.tradableInstrument.instrument.code'
|
||||||
|
>) => value || '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Receiver'),
|
||||||
|
field: 'toAccountPartyId',
|
||||||
|
cellRenderer: ({
|
||||||
|
value,
|
||||||
|
}: VegaValueFormatterParams<LedgerEntry, 'toAccountPartyId'>) =>
|
||||||
|
truncateByChars(value || ''),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Account type'),
|
||||||
|
filter: SetFilter,
|
||||||
|
filterParams: {
|
||||||
|
set: AccountTypeMapping,
|
||||||
},
|
},
|
||||||
{
|
field: 'toAccountType',
|
||||||
headerName: t('Market'),
|
cellRenderer: ({
|
||||||
field: 'marketSender.tradableInstrument.instrument.code',
|
value,
|
||||||
cellRenderer: ({
|
}: VegaValueFormatterParams<LedgerEntry, 'toAccountType'>) =>
|
||||||
value,
|
value ? AccountTypeMapping[value] : '-',
|
||||||
}: VegaValueFormatterParams<
|
},
|
||||||
LedgerEntry,
|
{
|
||||||
'marketSender.tradableInstrument.instrument.code'
|
headerName: t('Market'),
|
||||||
>) => value || '-',
|
field: 'marketReceiver.tradableInstrument.instrument.code',
|
||||||
|
cellRenderer: ({
|
||||||
|
value,
|
||||||
|
}: VegaValueFormatterParams<
|
||||||
|
LedgerEntry,
|
||||||
|
'marketReceiver.tradableInstrument.instrument.code'
|
||||||
|
>) => value || '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Transfer type'),
|
||||||
|
field: 'transferType',
|
||||||
|
tooltipField: 'transferType',
|
||||||
|
filter: SetFilter,
|
||||||
|
filterParams: {
|
||||||
|
set: TransferTypeMapping,
|
||||||
},
|
},
|
||||||
{
|
valueFormatter: ({
|
||||||
headerName: t('Receiver'),
|
value,
|
||||||
field: 'toAccountPartyId',
|
}: VegaValueFormatterParams<LedgerEntry, 'transferType'>) =>
|
||||||
cellRenderer: ({
|
value ? TransferTypeMapping[value] : '',
|
||||||
value,
|
},
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'toAccountPartyId'>) =>
|
{
|
||||||
truncateByChars(value || ''),
|
headerName: t('Quantity'),
|
||||||
|
field: 'quantity',
|
||||||
|
valueFormatter: ({
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<LedgerEntry, 'quantity'>) => {
|
||||||
|
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
||||||
|
return value
|
||||||
|
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
||||||
|
: '';
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
headerName: t('Account type'),
|
{
|
||||||
filter: SetFilter,
|
headerName: t('Asset'),
|
||||||
filterParams: {
|
field: 'assetId',
|
||||||
set: AccountTypeMapping,
|
valueFormatter: ({
|
||||||
},
|
value,
|
||||||
field: 'toAccountType',
|
data,
|
||||||
cellRenderer: ({
|
}: VegaValueFormatterParams<LedgerEntry, 'asset'>) =>
|
||||||
value,
|
data?.asset?.symbol || '',
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'toAccountType'>) =>
|
},
|
||||||
value ? AccountTypeMapping[value] : '-',
|
{
|
||||||
|
headerName: t('Sender account balance'),
|
||||||
|
field: 'fromAccountBalance',
|
||||||
|
valueFormatter: ({
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountBalance'>) => {
|
||||||
|
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
||||||
|
return value
|
||||||
|
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
||||||
|
: '';
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
headerName: t('Market'),
|
{
|
||||||
field: 'marketReceiver.tradableInstrument.instrument.code',
|
headerName: t('Receiver account balance'),
|
||||||
cellRenderer: ({
|
field: 'toAccountBalance',
|
||||||
value,
|
valueFormatter: ({
|
||||||
}: VegaValueFormatterParams<
|
value,
|
||||||
LedgerEntry,
|
data,
|
||||||
'marketReceiver.tradableInstrument.instrument.code'
|
}: VegaValueFormatterParams<LedgerEntry, 'toAccountBalance'>) => {
|
||||||
>) => value || '-',
|
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
||||||
|
return value
|
||||||
|
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
||||||
|
: '';
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
headerName: t('Transfer type'),
|
{
|
||||||
field: 'transferType',
|
headerName: t('Vega time'),
|
||||||
tooltipField: 'transferType',
|
field: 'vegaTime',
|
||||||
filter: SetFilter,
|
valueFormatter: ({
|
||||||
filterParams: {
|
value,
|
||||||
set: TransferTypeMapping,
|
}: VegaValueFormatterParams<LedgerEntry, 'vegaTime'>) =>
|
||||||
},
|
value ? getDateTimeFormat().format(fromNanoSeconds(value)) : '-',
|
||||||
valueFormatter: ({
|
filterParams: dateRangeFilterParams,
|
||||||
value,
|
filter: DateRangeFilter,
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'transferType'>) =>
|
flex: 1,
|
||||||
value ? TransferTypeMapping[value] : '',
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<AgGrid
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
tooltipShowDelay={500}
|
||||||
|
defaultColDef={{
|
||||||
|
resizable: true,
|
||||||
|
sortable: true,
|
||||||
|
tooltipComponent: TransferTooltipCellComponent,
|
||||||
|
filterParams: {
|
||||||
|
...dateRangeFilterParams,
|
||||||
|
buttons: ['reset'],
|
||||||
},
|
},
|
||||||
{
|
}}
|
||||||
headerName: t('Quantity'),
|
columnDefs={columnDefs}
|
||||||
field: 'quantity',
|
{...props}
|
||||||
valueFormatter: ({
|
/>
|
||||||
value,
|
);
|
||||||
data,
|
};
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'quantity'>) => {
|
|
||||||
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
|
||||||
return value
|
|
||||||
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
|
||||||
: '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headerName: t('Asset'),
|
|
||||||
field: 'assetId',
|
|
||||||
valueFormatter: ({
|
|
||||||
value,
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'asset'>) =>
|
|
||||||
data?.asset?.symbol || '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headerName: t('Sender account balance'),
|
|
||||||
field: 'fromAccountBalance',
|
|
||||||
valueFormatter: ({
|
|
||||||
value,
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'fromAccountBalance'>) => {
|
|
||||||
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
|
||||||
return value
|
|
||||||
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
|
||||||
: '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headerName: t('Receiver account balance'),
|
|
||||||
field: 'toAccountBalance',
|
|
||||||
valueFormatter: ({
|
|
||||||
value,
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'toAccountBalance'>) => {
|
|
||||||
const assetDecimalPlaces = data?.asset?.decimals || 0;
|
|
||||||
return value
|
|
||||||
? addDecimalsFormatNumber(value, assetDecimalPlaces)
|
|
||||||
: '';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
headerName: t('Vega time'),
|
|
||||||
field: 'vegaTime',
|
|
||||||
valueFormatter: ({
|
|
||||||
value,
|
|
||||||
}: VegaValueFormatterParams<LedgerEntry, 'vegaTime'>) =>
|
|
||||||
value ? getDateTimeFormat().format(fromNanoSeconds(value)) : '-',
|
|
||||||
filterParams: dateRangeFilterParams,
|
|
||||||
filter: DateRangeFilter,
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<AgGrid
|
|
||||||
style={{ width: '100%', height: '100%' }}
|
|
||||||
ref={ref}
|
|
||||||
tooltipShowDelay={500}
|
|
||||||
defaultColDef={{
|
|
||||||
resizable: true,
|
|
||||||
sortable: true,
|
|
||||||
tooltipComponent: TransferTooltipCellComponent,
|
|
||||||
filterParams: {
|
|
||||||
...dateRangeFilterParams,
|
|
||||||
buttons: ['reset'],
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
columnDefs={columnDefs}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import React, { forwardRef } from 'react';
|
|
||||||
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
||||||
import {
|
import {
|
||||||
AgGridLazy as AgGrid,
|
AgGridLazy as AgGrid,
|
||||||
PriceFlashCell,
|
PriceFlashCell,
|
||||||
MarketNameCell,
|
MarketNameCell,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type { MarketMaybeWithData } from '../../markets-provider';
|
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||||
import { OracleStatus } from './oracle-status';
|
import { OracleStatus } from './oracle-status';
|
||||||
import { useColumnDefs } from './use-column-defs';
|
import { useColumnDefs } from './use-column-defs';
|
||||||
@ -43,14 +41,15 @@ const defaultColDef = {
|
|||||||
filterParams: { buttons: ['reset'] },
|
filterParams: { buttons: ['reset'] },
|
||||||
minWidth: 100,
|
minWidth: 100,
|
||||||
};
|
};
|
||||||
|
type Props = TypedDataAgGrid<MarketMaybeWithData> & {
|
||||||
export const MarketListTable = forwardRef<
|
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
||||||
AgGridReact,
|
SuccessorMarketRenderer?: React.FC<{ value: string }>;
|
||||||
TypedDataAgGrid<MarketMaybeWithData> & {
|
};
|
||||||
onMarketClick: (marketId: string, metaKey?: boolean) => void;
|
export const MarketListTable = ({
|
||||||
SuccessorMarketRenderer?: React.FC<{ value: string }>;
|
onMarketClick,
|
||||||
}
|
SuccessorMarketRenderer,
|
||||||
>(({ onMarketClick, SuccessorMarketRenderer, ...props }, ref) => {
|
...props
|
||||||
|
}: Props) => {
|
||||||
const columnDefs = useColumnDefs({ onMarketClick });
|
const columnDefs = useColumnDefs({ onMarketClick });
|
||||||
const components = {
|
const components = {
|
||||||
PriceFlashCell,
|
PriceFlashCell,
|
||||||
@ -61,7 +60,6 @@ export const MarketListTable = forwardRef<
|
|||||||
<AgGrid
|
<AgGrid
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
getRowId={getRowId}
|
getRowId={getRowId}
|
||||||
ref={ref}
|
|
||||||
defaultColDef={defaultColDef}
|
defaultColDef={defaultColDef}
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
suppressCellFocus
|
suppressCellFocus
|
||||||
@ -69,6 +67,6 @@ export const MarketListTable = forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
};
|
||||||
|
|
||||||
export default MarketListTable;
|
export default MarketListTable;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type { CellClickedEvent } from 'ag-grid-community';
|
import type { CellClickedEvent } from 'ag-grid-community';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { MarketListTable } from './market-list-table';
|
import { MarketListTable } from './market-list-table';
|
||||||
@ -18,8 +17,6 @@ export const MarketsContainer = ({
|
|||||||
onSelect,
|
onSelect,
|
||||||
SuccessorMarketRenderer,
|
SuccessorMarketRenderer,
|
||||||
}: MarketsContainerProps) => {
|
}: MarketsContainerProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
|
|
||||||
const { data, error, reload } = useDataProvider({
|
const { data, error, reload } = useDataProvider({
|
||||||
dataProvider,
|
dataProvider,
|
||||||
variables: undefined,
|
variables: undefined,
|
||||||
@ -37,7 +34,6 @@ export const MarketsContainer = ({
|
|||||||
return (
|
return (
|
||||||
<div className="h-full relative">
|
<div className="h-full relative">
|
||||||
<MarketListTable
|
<MarketListTable
|
||||||
ref={gridRef}
|
|
||||||
rowData={data}
|
rowData={data}
|
||||||
onCellClicked={(cellEvent: CellClickedEvent) => {
|
onCellClicked={(cellEvent: CellClickedEvent) => {
|
||||||
const { data, column, event } = cellEvent;
|
const { data, column, event } = cellEvent;
|
||||||
|
@ -2,17 +2,13 @@ import { render, screen, act } from '@testing-library/react';
|
|||||||
import { StopOrdersManager } from './stop-orders-manager';
|
import { StopOrdersManager } from './stop-orders-manager';
|
||||||
import * as useDataProviderHook from '@vegaprotocol/data-provider';
|
import * as useDataProviderHook from '@vegaprotocol/data-provider';
|
||||||
import type { StopOrder } from '../order-data-provider/stop-orders-data-provider';
|
import type { StopOrder } from '../order-data-provider/stop-orders-data-provider';
|
||||||
import * as stopOrdersTableMock from '../stop-orders-table/stop-orders-table';
|
|
||||||
import { forwardRef } from 'react';
|
|
||||||
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
|
||||||
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
|
||||||
// @ts-ignore StopOrdersTable is read only but we need to override with the forwardRef to
|
jest.mock('../stop-orders-table/stop-orders-table', () => ({
|
||||||
// avoid warnings about padding refs
|
StopOrdersTable: () => <div>StopOrdersTable</div>,
|
||||||
stopOrdersTableMock.StopOrdersTable = forwardRef(() => (
|
}));
|
||||||
<div>StopOrdersTable</div>
|
|
||||||
));
|
|
||||||
|
|
||||||
const generateJsx = () => {
|
const generateJsx = () => {
|
||||||
const pubKey = '0x123';
|
const pubKey = '0x123';
|
||||||
|
@ -8,7 +8,7 @@ import { t } from '@vegaprotocol/i18n';
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ForwardedRef } from 'react';
|
import type { ForwardedRef } from 'react';
|
||||||
import { memo, forwardRef, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
AgGridLazy as AgGrid,
|
AgGridLazy as AgGrid,
|
||||||
SetFilter,
|
SetFilter,
|
||||||
@ -36,265 +36,252 @@ export type StopOrdersTableProps = TypedDataAgGrid<StopOrder> & {
|
|||||||
|
|
||||||
export const StopOrdersTable = memo<
|
export const StopOrdersTable = memo<
|
||||||
StopOrdersTableProps & { ref?: ForwardedRef<AgGridReact> }
|
StopOrdersTableProps & { ref?: ForwardedRef<AgGridReact> }
|
||||||
>(
|
>(({ onCancel, onMarketClick, ...props }: StopOrdersTableProps) => {
|
||||||
forwardRef<AgGridReact, StopOrdersTableProps>(
|
const showAllActions = !props.isReadOnly;
|
||||||
({ onCancel, onMarketClick, ...props }, ref) => {
|
const columnDefs: ColDef[] = useMemo(
|
||||||
const showAllActions = !props.isReadOnly;
|
() => [
|
||||||
const columnDefs: ColDef[] = useMemo(
|
{
|
||||||
() => [
|
headerName: t('Market'),
|
||||||
{
|
field: 'market.tradableInstrument.instrument.code',
|
||||||
headerName: t('Market'),
|
cellRenderer: 'MarketNameCell',
|
||||||
field: 'market.tradableInstrument.instrument.code',
|
cellRendererParams: { idPath: 'market.id', onMarketClick },
|
||||||
cellRenderer: 'MarketNameCell',
|
minWidth: 150,
|
||||||
cellRendererParams: { idPath: 'market.id', onMarketClick },
|
},
|
||||||
minWidth: 150,
|
{
|
||||||
},
|
headerName: t('Trigger'),
|
||||||
{
|
field: 'trigger',
|
||||||
headerName: t('Trigger'),
|
cellClass: 'font-mono text-right',
|
||||||
field: 'trigger',
|
type: 'rightAligned',
|
||||||
cellClass: 'font-mono text-right',
|
sortable: false,
|
||||||
type: 'rightAligned',
|
valueFormatter: ({
|
||||||
sortable: false,
|
data,
|
||||||
valueFormatter: ({
|
value,
|
||||||
data,
|
}: VegaValueFormatterParams<StopOrder, 'trigger'>): string => {
|
||||||
value,
|
if (data && value?.__typename === 'StopOrderPrice') {
|
||||||
}: VegaValueFormatterParams<StopOrder, 'trigger'>): string => {
|
return `${t('Mark')} ${
|
||||||
if (data && value?.__typename === 'StopOrderPrice') {
|
data?.triggerDirection ===
|
||||||
return `${t('Mark')} ${
|
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||||
data?.triggerDirection ===
|
? '<'
|
||||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
: '>'
|
||||||
? '<'
|
} ${addDecimalsFormatNumber(
|
||||||
: '>'
|
value.price,
|
||||||
} ${addDecimalsFormatNumber(
|
data.market.decimalPlaces
|
||||||
value.price,
|
)}`;
|
||||||
data.market.decimalPlaces
|
}
|
||||||
)}`;
|
if (data && value?.__typename === 'StopOrderTrailingPercentOffset') {
|
||||||
}
|
return `${t('Mark')} ${
|
||||||
if (
|
data?.triggerDirection ===
|
||||||
data &&
|
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||||
value?.__typename === 'StopOrderTrailingPercentOffset'
|
? '+'
|
||||||
) {
|
: '-'
|
||||||
return `${t('Mark')} ${
|
}${(Number(value.trailingPercentOffset) * 100).toFixed(1)}%`;
|
||||||
data?.triggerDirection ===
|
}
|
||||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
return '-';
|
||||||
? '+'
|
},
|
||||||
: '-'
|
minWidth: 100,
|
||||||
}${(Number(value.trailingPercentOffset) * 100).toFixed(1)}%`;
|
},
|
||||||
}
|
{
|
||||||
return '-';
|
field: 'expiresAt',
|
||||||
},
|
valueFormatter: ({
|
||||||
minWidth: 100,
|
value,
|
||||||
},
|
data,
|
||||||
{
|
}: VegaValueFormatterParams<StopOrder, 'expiresAt'>) => {
|
||||||
field: 'expiresAt',
|
if (
|
||||||
valueFormatter: ({
|
data &&
|
||||||
value,
|
value &&
|
||||||
data,
|
data?.expiryStrategy !==
|
||||||
}: VegaValueFormatterParams<StopOrder, 'expiresAt'>) => {
|
Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_UNSPECIFIED
|
||||||
if (
|
) {
|
||||||
data &&
|
const expiresAt = getDateTimeFormat().format(new Date(value));
|
||||||
value &&
|
const expiryStrategy =
|
||||||
data?.expiryStrategy !==
|
data.expiryStrategy ===
|
||||||
Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_UNSPECIFIED
|
Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_SUBMIT
|
||||||
) {
|
? t('Submit')
|
||||||
const expiresAt = getDateTimeFormat().format(new Date(value));
|
: t('Cancels');
|
||||||
const expiryStrategy =
|
return `${expiryStrategy} ${expiresAt}`;
|
||||||
data.expiryStrategy ===
|
}
|
||||||
Schema.StopOrderExpiryStrategy.EXPIRY_STRATEGY_SUBMIT
|
return '';
|
||||||
? t('Submit')
|
},
|
||||||
: t('Cancels');
|
minWidth: 150,
|
||||||
return `${expiryStrategy} ${expiresAt}`;
|
},
|
||||||
}
|
{
|
||||||
return '';
|
headerName: t('Size'),
|
||||||
},
|
field: 'submission.size',
|
||||||
minWidth: 150,
|
cellClass: 'font-mono text-right',
|
||||||
},
|
type: 'rightAligned',
|
||||||
{
|
cellClassRules: {
|
||||||
headerName: t('Size'),
|
[positiveClassNames]: ({ data }: { data: StopOrder }) =>
|
||||||
field: 'submission.size',
|
data?.submission.size === Schema.Side.SIDE_BUY,
|
||||||
cellClass: 'font-mono text-right',
|
[negativeClassNames]: ({ data }: { data: StopOrder }) =>
|
||||||
type: 'rightAligned',
|
data?.submission.size === Schema.Side.SIDE_SELL,
|
||||||
cellClassRules: {
|
},
|
||||||
[positiveClassNames]: ({ data }: { data: StopOrder }) =>
|
valueGetter: ({ data }: VegaValueGetterParams<StopOrder>) => {
|
||||||
data?.submission.size === Schema.Side.SIDE_BUY,
|
return data?.submission.size && data.market
|
||||||
[negativeClassNames]: ({ data }: { data: StopOrder }) =>
|
? toBigNum(
|
||||||
data?.submission.size === Schema.Side.SIDE_SELL,
|
data.submission.size,
|
||||||
},
|
data.market.positionDecimalPlaces ?? 0
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<StopOrder>) => {
|
)
|
||||||
return data?.submission.size && data.market
|
.multipliedBy(
|
||||||
? toBigNum(
|
data.submission.side === Schema.Side.SIDE_SELL ? -1 : 1
|
||||||
data.submission.size,
|
|
||||||
data.market.positionDecimalPlaces ?? 0
|
|
||||||
)
|
|
||||||
.multipliedBy(
|
|
||||||
data.submission.side === Schema.Side.SIDE_SELL ? -1 : 1
|
|
||||||
)
|
|
||||||
.toNumber()
|
|
||||||
: undefined;
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<StopOrder, 'size'>) => {
|
|
||||||
if (!data) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if (!data?.market || !isNumeric(data.submission.size)) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
const prefix = data
|
|
||||||
? data.submission.side === Schema.Side.SIDE_BUY
|
|
||||||
? '+'
|
|
||||||
: '-'
|
|
||||||
: '';
|
|
||||||
return (
|
|
||||||
prefix +
|
|
||||||
addDecimalsFormatNumber(
|
|
||||||
data.submission.size,
|
|
||||||
data.market.positionDecimalPlaces
|
|
||||||
)
|
)
|
||||||
);
|
.toNumber()
|
||||||
},
|
: undefined;
|
||||||
minWidth: 80,
|
},
|
||||||
},
|
valueFormatter: ({
|
||||||
{
|
data,
|
||||||
field: 'submission.type',
|
}: VegaValueFormatterParams<StopOrder, 'size'>) => {
|
||||||
filter: SetFilter,
|
if (!data) {
|
||||||
filterParams: {
|
return '';
|
||||||
set: Schema.OrderTypeMapping,
|
}
|
||||||
},
|
if (!data?.market || !isNumeric(data.submission.size)) {
|
||||||
cellRenderer: ({
|
return '-';
|
||||||
value,
|
}
|
||||||
}: VegaICellRendererParams<StopOrder, 'submission.type'>) =>
|
const prefix = data
|
||||||
value ? Schema.OrderTypeMapping[value] : '',
|
? data.submission.side === Schema.Side.SIDE_BUY
|
||||||
minWidth: 80,
|
? '+'
|
||||||
},
|
: '-'
|
||||||
{
|
: '';
|
||||||
field: 'status',
|
return (
|
||||||
filter: SetFilter,
|
prefix +
|
||||||
filterParams: {
|
addDecimalsFormatNumber(
|
||||||
set: Schema.StopOrderStatusMapping,
|
data.submission.size,
|
||||||
},
|
data.market.positionDecimalPlaces
|
||||||
valueFormatter: ({
|
)
|
||||||
value,
|
);
|
||||||
}: VegaValueFormatterParams<StopOrder, 'status'>) => {
|
},
|
||||||
return value ? Schema.StopOrderStatusMapping[value] : '';
|
minWidth: 80,
|
||||||
},
|
},
|
||||||
cellRenderer: ({
|
{
|
||||||
valueFormatted,
|
field: 'submission.type',
|
||||||
data,
|
filter: SetFilter,
|
||||||
}: {
|
filterParams: {
|
||||||
valueFormatted: string;
|
set: Schema.OrderTypeMapping,
|
||||||
data: StopOrder;
|
},
|
||||||
}) => (
|
cellRenderer: ({
|
||||||
<span data-testid={`order-status-${data?.id}`}>
|
value,
|
||||||
{valueFormatted}
|
}: VegaICellRendererParams<StopOrder, 'submission.type'>) =>
|
||||||
</span>
|
value ? Schema.OrderTypeMapping[value] : '',
|
||||||
),
|
minWidth: 80,
|
||||||
minWidth: 100,
|
},
|
||||||
},
|
{
|
||||||
{
|
field: 'status',
|
||||||
field: 'submission.price',
|
filter: SetFilter,
|
||||||
type: 'rightAligned',
|
filterParams: {
|
||||||
cellClass: 'font-mono text-right',
|
set: Schema.StopOrderStatusMapping,
|
||||||
valueFormatter: ({
|
},
|
||||||
value,
|
valueFormatter: ({
|
||||||
data,
|
value,
|
||||||
}: VegaValueFormatterParams<StopOrder, 'submission.price'>) => {
|
}: VegaValueFormatterParams<StopOrder, 'status'>) => {
|
||||||
if (!data) {
|
return value ? Schema.StopOrderStatusMapping[value] : '';
|
||||||
return '';
|
},
|
||||||
}
|
cellRenderer: ({
|
||||||
if (
|
valueFormatted,
|
||||||
!data?.market ||
|
data,
|
||||||
data.submission.type === Schema.OrderType.TYPE_MARKET ||
|
}: {
|
||||||
!isNumeric(value)
|
valueFormatted: string;
|
||||||
) {
|
data: StopOrder;
|
||||||
return '-';
|
}) => (
|
||||||
}
|
<span data-testid={`order-status-${data?.id}`}>{valueFormatted}</span>
|
||||||
return addDecimalsFormatNumber(value, data.market.decimalPlaces);
|
),
|
||||||
},
|
minWidth: 100,
|
||||||
minWidth: 100,
|
},
|
||||||
},
|
{
|
||||||
{
|
field: 'submission.price',
|
||||||
field: 'submission.timeInForce',
|
type: 'rightAligned',
|
||||||
filter: SetFilter,
|
cellClass: 'font-mono text-right',
|
||||||
filterParams: {
|
valueFormatter: ({
|
||||||
set: Schema.OrderTimeInForceMapping,
|
value,
|
||||||
},
|
data,
|
||||||
valueFormatter: ({
|
}: VegaValueFormatterParams<StopOrder, 'submission.price'>) => {
|
||||||
value,
|
if (!data) {
|
||||||
}: VegaValueFormatterParams<
|
return '';
|
||||||
StopOrder,
|
}
|
||||||
'submission.timeInForce'
|
if (
|
||||||
>) => {
|
!data?.market ||
|
||||||
return value ? Schema.OrderTimeInForceCode[value] : '';
|
data.submission.type === Schema.OrderType.TYPE_MARKET ||
|
||||||
},
|
!isNumeric(value)
|
||||||
minWidth: 150,
|
) {
|
||||||
},
|
return '-';
|
||||||
{
|
}
|
||||||
field: 'updatedAt',
|
return addDecimalsFormatNumber(value, data.market.decimalPlaces);
|
||||||
filter: DateRangeFilter,
|
},
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<StopOrder>) =>
|
minWidth: 100,
|
||||||
data?.updatedAt || data?.createdAt,
|
},
|
||||||
cellRenderer: ({
|
{
|
||||||
data,
|
field: 'submission.timeInForce',
|
||||||
}: VegaICellRendererParams<StopOrder, 'createdAt'>) => {
|
filter: SetFilter,
|
||||||
if (!data) {
|
filterParams: {
|
||||||
return undefined;
|
set: Schema.OrderTimeInForceMapping,
|
||||||
}
|
},
|
||||||
const value = data.updatedAt || data.createdAt;
|
valueFormatter: ({
|
||||||
return (
|
value,
|
||||||
<span data-value={value}>
|
}: VegaValueFormatterParams<StopOrder, 'submission.timeInForce'>) => {
|
||||||
{value ? getDateTimeFormat().format(new Date(value)) : '-'}
|
return value ? Schema.OrderTimeInForceCode[value] : '';
|
||||||
</span>
|
},
|
||||||
);
|
minWidth: 150,
|
||||||
},
|
},
|
||||||
minWidth: 150,
|
{
|
||||||
},
|
field: 'updatedAt',
|
||||||
{
|
filter: DateRangeFilter,
|
||||||
colId: 'actions',
|
valueGetter: ({ data }: VegaValueGetterParams<StopOrder>) =>
|
||||||
...COL_DEFS.actions,
|
data?.updatedAt || data?.createdAt,
|
||||||
minWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
|
cellRenderer: ({
|
||||||
maxWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
|
data,
|
||||||
cellRenderer: ({ data }: { data?: StopOrder }) => {
|
}: VegaICellRendererParams<StopOrder, 'createdAt'>) => {
|
||||||
if (!data) return null;
|
if (!data) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const value = data.updatedAt || data.createdAt;
|
||||||
|
return (
|
||||||
|
<span data-value={value}>
|
||||||
|
{value ? getDateTimeFormat().format(new Date(value)) : '-'}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
minWidth: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
colId: 'actions',
|
||||||
|
...COL_DEFS.actions,
|
||||||
|
minWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
|
||||||
|
maxWidth: showAllActions ? 120 : COL_DEFS.actions.minWidth,
|
||||||
|
cellRenderer: ({ data }: { data?: StopOrder }) => {
|
||||||
|
if (!data) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2 items-center justify-end">
|
<div className="flex gap-2 items-center justify-end">
|
||||||
{data.status === Schema.StopOrderStatus.STATUS_PENDING &&
|
{data.status === Schema.StopOrderStatus.STATUS_PENDING &&
|
||||||
!props.isReadOnly && (
|
!props.isReadOnly && (
|
||||||
<ButtonLink
|
<ButtonLink
|
||||||
data-testid="cancel"
|
data-testid="cancel"
|
||||||
onClick={() => onCancel(data)}
|
onClick={() => onCancel(data)}
|
||||||
>
|
>
|
||||||
{t('Cancel')}
|
{t('Cancel')}
|
||||||
</ButtonLink>
|
</ButtonLink>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[onCancel, onMarketClick, props.isReadOnly, showAllActions]
|
[onCancel, onMarketClick, props.isReadOnly, showAllActions]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
ref={ref}
|
defaultColDef={{
|
||||||
defaultColDef={{
|
resizable: true,
|
||||||
resizable: true,
|
sortable: true,
|
||||||
sortable: true,
|
filterParams: { buttons: ['reset'] },
|
||||||
filterParams: { buttons: ['reset'] },
|
}}
|
||||||
}}
|
columnDefs={columnDefs}
|
||||||
columnDefs={columnDefs}
|
style={{
|
||||||
style={{
|
width: '100%',
|
||||||
width: '100%',
|
height: '100%',
|
||||||
height: '100%',
|
}}
|
||||||
}}
|
getRowId={({ data }) => data.id}
|
||||||
getRowId={({ data }) => data.id}
|
components={{ MarketNameCell }}
|
||||||
components={{ MarketNameCell }}
|
{...props}
|
||||||
{...props}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
});
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { forwardRef, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { CSSProperties, ReactNode } from 'react';
|
import type { CSSProperties, ReactNode } from 'react';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import type {
|
import type {
|
||||||
@ -33,7 +33,6 @@ import {
|
|||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type { Position } from './positions-data-providers';
|
import type { Position } from './positions-data-providers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
|
import { PositionStatus, PositionStatusMapping } from '@vegaprotocol/types';
|
||||||
@ -87,383 +86,367 @@ AmountCell.displayName = 'AmountCell';
|
|||||||
export const getRowId = ({ data }: { data: Position }) =>
|
export const getRowId = ({ data }: { data: Position }) =>
|
||||||
`${data.partyId}-${data.marketId}`;
|
`${data.partyId}-${data.marketId}`;
|
||||||
|
|
||||||
export const PositionsTable = forwardRef<AgGridReact, Props>(
|
export const PositionsTable = ({
|
||||||
(
|
onClose,
|
||||||
{
|
onMarketClick,
|
||||||
onClose,
|
multipleKeys,
|
||||||
onMarketClick,
|
isReadOnly,
|
||||||
multipleKeys,
|
pubKeys,
|
||||||
isReadOnly,
|
pubKey,
|
||||||
pubKeys,
|
...props
|
||||||
pubKey,
|
}: Props) => {
|
||||||
...props
|
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||||
},
|
return (
|
||||||
ref
|
<AgGrid
|
||||||
) => {
|
style={{ width: '100%', height: '100%' }}
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
overlayNoRowsTemplate={t('No positions')}
|
||||||
return (
|
getRowId={getRowId}
|
||||||
<AgGrid
|
tooltipShowDelay={500}
|
||||||
style={{ width: '100%', height: '100%' }}
|
defaultColDef={{
|
||||||
overlayNoRowsTemplate={t('No positions')}
|
resizable: true,
|
||||||
getRowId={getRowId}
|
sortable: true,
|
||||||
ref={ref}
|
filter: true,
|
||||||
tooltipShowDelay={500}
|
filterParams: { buttons: ['reset'] },
|
||||||
defaultColDef={{
|
tooltipComponent: TooltipCellComponent,
|
||||||
resizable: true,
|
}}
|
||||||
sortable: true,
|
components={{
|
||||||
filter: true,
|
AmountCell,
|
||||||
filterParams: { buttons: ['reset'] },
|
PriceFlashCell,
|
||||||
tooltipComponent: TooltipCellComponent,
|
ProgressBarCell,
|
||||||
}}
|
MarketNameCell,
|
||||||
components={{
|
}}
|
||||||
AmountCell,
|
{...props}
|
||||||
PriceFlashCell,
|
columnDefs={useMemo<ColDef[]>(() => {
|
||||||
ProgressBarCell,
|
const columnDefs: (ColDef | null)[] = [
|
||||||
MarketNameCell,
|
multipleKeys
|
||||||
}}
|
? {
|
||||||
{...props}
|
headerName: t('Vega key'),
|
||||||
columnDefs={useMemo<ColDef[]>(() => {
|
field: 'partyId',
|
||||||
const columnDefs: (ColDef | null)[] = [
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) =>
|
||||||
multipleKeys
|
(data?.partyId &&
|
||||||
? {
|
pubKeys &&
|
||||||
headerName: t('Vega key'),
|
pubKeys.find((key) => key.publicKey === data.partyId)
|
||||||
field: 'partyId',
|
?.name) ||
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) =>
|
data?.partyId,
|
||||||
(data?.partyId &&
|
minWidth: 190,
|
||||||
pubKeys &&
|
}
|
||||||
pubKeys.find((key) => key.publicKey === data.partyId)
|
: null,
|
||||||
?.name) ||
|
{
|
||||||
data?.partyId,
|
headerName: t('Market'),
|
||||||
minWidth: 190,
|
field: 'marketName',
|
||||||
}
|
cellRenderer: 'MarketNameCell',
|
||||||
: null,
|
cellRendererParams: { idPath: 'marketId', onMarketClick },
|
||||||
{
|
minWidth: 190,
|
||||||
headerName: t('Market'),
|
},
|
||||||
field: 'marketName',
|
{
|
||||||
cellRenderer: 'MarketNameCell',
|
headerName: t('Notional'),
|
||||||
cellRendererParams: { idPath: 'marketId', onMarketClick },
|
headerTooltip: t('Mark price x open volume.'),
|
||||||
minWidth: 190,
|
field: 'notional',
|
||||||
|
type: 'rightAligned',
|
||||||
|
cellClass: 'font-mono text-right',
|
||||||
|
filter: 'agNumberColumnFilter',
|
||||||
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
|
return !data?.notional
|
||||||
|
? undefined
|
||||||
|
: toBigNum(data.notional, data.marketDecimalPlaces).toNumber();
|
||||||
},
|
},
|
||||||
{
|
valueFormatter: ({
|
||||||
headerName: t('Notional'),
|
data,
|
||||||
headerTooltip: t('Mark price x open volume.'),
|
}: VegaValueFormatterParams<Position, 'notional'>) => {
|
||||||
field: 'notional',
|
return !data || !data.notional
|
||||||
type: 'rightAligned',
|
? '-'
|
||||||
cellClass: 'font-mono text-right',
|
: addDecimalsFormatNumber(
|
||||||
filter: 'agNumberColumnFilter',
|
data.notional,
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
data.marketDecimalPlaces
|
||||||
return !data?.notional
|
);
|
||||||
? undefined
|
|
||||||
: toBigNum(
|
|
||||||
data.notional,
|
|
||||||
data.marketDecimalPlaces
|
|
||||||
).toNumber();
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<Position, 'notional'>) => {
|
|
||||||
return !data || !data.notional
|
|
||||||
? '-'
|
|
||||||
: addDecimalsFormatNumber(
|
|
||||||
data.notional,
|
|
||||||
data.marketDecimalPlaces
|
|
||||||
);
|
|
||||||
},
|
|
||||||
minWidth: 80,
|
|
||||||
},
|
},
|
||||||
{
|
minWidth: 80,
|
||||||
headerName: t('Open volume'),
|
},
|
||||||
field: 'openVolume',
|
{
|
||||||
type: 'rightAligned',
|
headerName: t('Open volume'),
|
||||||
cellClass: 'font-mono text-right',
|
field: 'openVolume',
|
||||||
cellClassRules: signedNumberCssClassRules,
|
type: 'rightAligned',
|
||||||
filter: 'agNumberColumnFilter',
|
cellClass: 'font-mono text-right',
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
cellClassRules: signedNumberCssClassRules,
|
||||||
return data?.openVolume === undefined
|
filter: 'agNumberColumnFilter',
|
||||||
? undefined
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
: toBigNum(
|
return data?.openVolume === undefined
|
||||||
data?.openVolume,
|
? undefined
|
||||||
|
: toBigNum(
|
||||||
|
data?.openVolume,
|
||||||
|
data.positionDecimalPlaces
|
||||||
|
).toNumber();
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<Position, 'openVolume'>): string => {
|
||||||
|
return data?.openVolume === undefined
|
||||||
|
? ''
|
||||||
|
: volumePrefix(
|
||||||
|
addDecimalsFormatNumber(
|
||||||
|
data.openVolume,
|
||||||
data.positionDecimalPlaces
|
data.positionDecimalPlaces
|
||||||
).toNumber();
|
)
|
||||||
},
|
);
|
||||||
valueFormatter: ({
|
},
|
||||||
data,
|
cellRenderer: OpenVolumeCell,
|
||||||
}: VegaValueFormatterParams<Position, 'openVolume'>): string => {
|
minWidth: 100,
|
||||||
return data?.openVolume === undefined
|
},
|
||||||
? ''
|
{
|
||||||
: volumePrefix(
|
headerName: t('Mark price'),
|
||||||
addDecimalsFormatNumber(
|
field: 'markPrice',
|
||||||
data.openVolume,
|
type: 'rightAligned',
|
||||||
data.positionDecimalPlaces
|
cellRenderer: PriceFlashCell,
|
||||||
)
|
filter: 'agNumberColumnFilter',
|
||||||
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
|
return !data ||
|
||||||
|
!data.markPrice ||
|
||||||
|
data.marketTradingMode ===
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
||||||
|
? undefined
|
||||||
|
: toBigNum(data.markPrice, data.marketDecimalPlaces).toNumber();
|
||||||
|
},
|
||||||
|
valueFormatter: ({
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<Position, 'markPrice'>) => {
|
||||||
|
if (!data) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!data.markPrice ||
|
||||||
|
data.marketTradingMode ===
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
||||||
|
) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
return addDecimalsFormatNumber(
|
||||||
|
data.markPrice,
|
||||||
|
data.marketDecimalPlaces
|
||||||
|
);
|
||||||
|
},
|
||||||
|
minWidth: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Liquidation price'),
|
||||||
|
colId: 'liquidationPrice',
|
||||||
|
type: 'rightAligned',
|
||||||
|
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
|
||||||
|
if (!data) return null;
|
||||||
|
return (
|
||||||
|
<LiquidationPrice
|
||||||
|
marketId={data.marketId}
|
||||||
|
openVolume={data.openVolume}
|
||||||
|
collateralAvailable={data.totalBalance}
|
||||||
|
decimalPlaces={data.decimals}
|
||||||
|
formatDecimals={data.marketDecimalPlaces}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Settlement asset'),
|
||||||
|
field: 'assetSymbol',
|
||||||
|
colId: 'asset',
|
||||||
|
minWidth: 100,
|
||||||
|
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
|
||||||
|
if (!data) return null;
|
||||||
|
return (
|
||||||
|
<ButtonLink
|
||||||
|
title={t('View settlement asset details')}
|
||||||
|
onClick={(e) => {
|
||||||
|
openAssetDetailsDialog(
|
||||||
|
data.assetId,
|
||||||
|
e.target as HTMLElement
|
||||||
);
|
);
|
||||||
},
|
}}
|
||||||
cellRenderer: OpenVolumeCell,
|
>
|
||||||
minWidth: 100,
|
{data?.assetSymbol}
|
||||||
|
</ButtonLink>
|
||||||
|
);
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
headerName: t('Mark price'),
|
{
|
||||||
field: 'markPrice',
|
headerName: t('Entry price'),
|
||||||
type: 'rightAligned',
|
field: 'averageEntryPrice',
|
||||||
cellRenderer: PriceFlashCell,
|
type: 'rightAligned',
|
||||||
filter: 'agNumberColumnFilter',
|
cellRenderer: PriceFlashCell,
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
filter: 'agNumberColumnFilter',
|
||||||
return !data ||
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
!data.markPrice ||
|
return data?.markPrice === undefined || !data
|
||||||
data.marketTradingMode ===
|
? undefined
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
: toBigNum(
|
||||||
? undefined
|
data.averageEntryPrice,
|
||||||
: toBigNum(
|
data.marketDecimalPlaces
|
||||||
data.markPrice,
|
).toNumber();
|
||||||
data.marketDecimalPlaces
|
|
||||||
).toNumber();
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<Position, 'markPrice'>) => {
|
|
||||||
if (!data) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
!data.markPrice ||
|
|
||||||
data.marketTradingMode ===
|
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
|
||||||
) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
return addDecimalsFormatNumber(
|
|
||||||
data.markPrice,
|
|
||||||
data.marketDecimalPlaces
|
|
||||||
);
|
|
||||||
},
|
|
||||||
minWidth: 100,
|
|
||||||
},
|
},
|
||||||
{
|
valueFormatter: ({
|
||||||
headerName: t('Liquidation price'),
|
data,
|
||||||
colId: 'liquidationPrice',
|
}: VegaValueFormatterParams<
|
||||||
type: 'rightAligned',
|
Position,
|
||||||
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
|
'averageEntryPrice'
|
||||||
if (!data) return null;
|
>): string => {
|
||||||
return (
|
if (!data) {
|
||||||
<LiquidationPrice
|
return '';
|
||||||
marketId={data.marketId}
|
}
|
||||||
openVolume={data.openVolume}
|
return addDecimalsFormatNumber(
|
||||||
collateralAvailable={data.totalBalance}
|
data.averageEntryPrice,
|
||||||
decimalPlaces={data.decimals}
|
data.marketDecimalPlaces
|
||||||
formatDecimals={data.marketDecimalPlaces}
|
);
|
||||||
/>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
minWidth: 100,
|
||||||
headerName: t('Settlement asset'),
|
},
|
||||||
field: 'assetSymbol',
|
multipleKeys
|
||||||
colId: 'asset',
|
? null
|
||||||
minWidth: 100,
|
: {
|
||||||
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
|
headerName: t('Leverage'),
|
||||||
if (!data) return null;
|
field: 'currentLeverage',
|
||||||
return (
|
type: 'rightAligned',
|
||||||
<ButtonLink
|
filter: 'agNumberColumnFilter',
|
||||||
title={t('View settlement asset details')}
|
cellRenderer: PriceFlashCell,
|
||||||
onClick={(e) => {
|
valueFormatter: ({
|
||||||
openAssetDetailsDialog(
|
value,
|
||||||
data.assetId,
|
}: VegaValueFormatterParams<Position, 'currentLeverage'>) =>
|
||||||
e.target as HTMLElement
|
value === undefined ? '' : formatNumber(value.toString(), 1),
|
||||||
);
|
minWidth: 100,
|
||||||
}}
|
|
||||||
>
|
|
||||||
{data?.assetSymbol}
|
|
||||||
</ButtonLink>
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
multipleKeys
|
||||||
{
|
? null
|
||||||
headerName: t('Entry price'),
|
: {
|
||||||
field: 'averageEntryPrice',
|
headerName: t('Margin allocated'),
|
||||||
type: 'rightAligned',
|
field: 'marginAccountBalance',
|
||||||
cellRenderer: PriceFlashCell,
|
type: 'rightAligned',
|
||||||
filter: 'agNumberColumnFilter',
|
filter: 'agNumberColumnFilter',
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
cellRenderer: PriceFlashCell,
|
||||||
return data?.markPrice === undefined || !data
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
? undefined
|
return !data
|
||||||
: toBigNum(
|
? undefined
|
||||||
data.averageEntryPrice,
|
: toBigNum(
|
||||||
data.marketDecimalPlaces
|
data.marginAccountBalance,
|
||||||
).toNumber();
|
data.decimals
|
||||||
},
|
).toNumber();
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<
|
|
||||||
Position,
|
|
||||||
'averageEntryPrice'
|
|
||||||
>): string => {
|
|
||||||
if (!data) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return addDecimalsFormatNumber(
|
|
||||||
data.averageEntryPrice,
|
|
||||||
data.marketDecimalPlaces
|
|
||||||
);
|
|
||||||
},
|
|
||||||
minWidth: 100,
|
|
||||||
},
|
|
||||||
multipleKeys
|
|
||||||
? null
|
|
||||||
: {
|
|
||||||
headerName: t('Leverage'),
|
|
||||||
field: 'currentLeverage',
|
|
||||||
type: 'rightAligned',
|
|
||||||
filter: 'agNumberColumnFilter',
|
|
||||||
cellRenderer: PriceFlashCell,
|
|
||||||
valueFormatter: ({
|
|
||||||
value,
|
|
||||||
}: VegaValueFormatterParams<Position, 'currentLeverage'>) =>
|
|
||||||
value === undefined
|
|
||||||
? ''
|
|
||||||
: formatNumber(value.toString(), 1),
|
|
||||||
minWidth: 100,
|
|
||||||
},
|
},
|
||||||
multipleKeys
|
valueFormatter: ({
|
||||||
? null
|
data,
|
||||||
: {
|
}: VegaValueFormatterParams<
|
||||||
headerName: t('Margin allocated'),
|
Position,
|
||||||
field: 'marginAccountBalance',
|
'marginAccountBalance'
|
||||||
type: 'rightAligned',
|
>): string => {
|
||||||
filter: 'agNumberColumnFilter',
|
if (!data) {
|
||||||
cellRenderer: PriceFlashCell,
|
return '';
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
}
|
||||||
return !data
|
return addDecimalsFormatNumber(
|
||||||
? undefined
|
data.marginAccountBalance,
|
||||||
: toBigNum(
|
data.decimals
|
||||||
data.marginAccountBalance,
|
);
|
||||||
data.decimals
|
|
||||||
).toNumber();
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<
|
|
||||||
Position,
|
|
||||||
'marginAccountBalance'
|
|
||||||
>): string => {
|
|
||||||
if (!data) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return addDecimalsFormatNumber(
|
|
||||||
data.marginAccountBalance,
|
|
||||||
data.decimals
|
|
||||||
);
|
|
||||||
},
|
|
||||||
minWidth: 100,
|
|
||||||
},
|
},
|
||||||
{
|
minWidth: 100,
|
||||||
headerName: t('Realised PNL'),
|
|
||||||
field: 'realisedPNL',
|
|
||||||
type: 'rightAligned',
|
|
||||||
cellClassRules: signedNumberCssClassRules,
|
|
||||||
cellClass: 'font-mono text-right',
|
|
||||||
filter: 'agNumberColumnFilter',
|
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
|
||||||
return !data
|
|
||||||
? undefined
|
|
||||||
: toBigNum(data.realisedPNL, data.decimals).toNumber();
|
|
||||||
},
|
},
|
||||||
valueFormatter: ({
|
{
|
||||||
data,
|
headerName: t('Realised PNL'),
|
||||||
}: VegaValueFormatterParams<Position, 'realisedPNL'>) => {
|
field: 'realisedPNL',
|
||||||
return !data
|
type: 'rightAligned',
|
||||||
? ''
|
cellClassRules: signedNumberCssClassRules,
|
||||||
: addDecimalsFormatNumber(data.realisedPNL, data.decimals);
|
cellClass: 'font-mono text-right',
|
||||||
},
|
filter: 'agNumberColumnFilter',
|
||||||
headerTooltip: t(
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.'
|
return !data
|
||||||
),
|
? undefined
|
||||||
cellRenderer: PNLCell,
|
: toBigNum(data.realisedPNL, data.decimals).toNumber();
|
||||||
minWidth: 100,
|
|
||||||
},
|
},
|
||||||
{
|
valueFormatter: ({
|
||||||
headerName: t('Unrealised PNL'),
|
data,
|
||||||
field: 'unrealisedPNL',
|
}: VegaValueFormatterParams<Position, 'realisedPNL'>) => {
|
||||||
type: 'rightAligned',
|
return !data
|
||||||
cellClassRules: signedNumberCssClassRules,
|
? ''
|
||||||
cellClass: 'font-mono text-right',
|
: addDecimalsFormatNumber(data.realisedPNL, data.decimals);
|
||||||
filter: 'agNumberColumnFilter',
|
|
||||||
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
|
||||||
return !data
|
|
||||||
? undefined
|
|
||||||
: toBigNum(data.unrealisedPNL, data.decimals).toNumber();
|
|
||||||
},
|
|
||||||
valueFormatter: ({
|
|
||||||
data,
|
|
||||||
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
|
|
||||||
!data
|
|
||||||
? ''
|
|
||||||
: addDecimalsFormatNumber(data.unrealisedPNL, data.decimals),
|
|
||||||
headerTooltip: t(
|
|
||||||
'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.'
|
|
||||||
),
|
|
||||||
cellRenderer: PNLCell,
|
|
||||||
minWidth: 100,
|
|
||||||
},
|
},
|
||||||
{
|
headerTooltip: t(
|
||||||
headerName: t('Updated'),
|
'Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.'
|
||||||
field: 'updatedAt',
|
),
|
||||||
type: 'rightAligned',
|
cellRenderer: PNLCell,
|
||||||
filter: DateRangeFilter,
|
minWidth: 100,
|
||||||
valueFormatter: ({
|
},
|
||||||
value,
|
{
|
||||||
}: VegaValueFormatterParams<Position, 'updatedAt'>) => {
|
headerName: t('Unrealised PNL'),
|
||||||
if (!value) {
|
field: 'unrealisedPNL',
|
||||||
return '';
|
type: 'rightAligned',
|
||||||
}
|
cellClassRules: signedNumberCssClassRules,
|
||||||
return getDateTimeFormat().format(new Date(value));
|
cellClass: 'font-mono text-right',
|
||||||
},
|
filter: 'agNumberColumnFilter',
|
||||||
minWidth: 150,
|
valueGetter: ({ data }: VegaValueGetterParams<Position>) => {
|
||||||
|
return !data
|
||||||
|
? undefined
|
||||||
|
: toBigNum(data.unrealisedPNL, data.decimals).toNumber();
|
||||||
},
|
},
|
||||||
onClose && !isReadOnly
|
valueFormatter: ({
|
||||||
? {
|
data,
|
||||||
...COL_DEFS.actions,
|
}: VegaValueFormatterParams<Position, 'unrealisedPNL'>) =>
|
||||||
cellRenderer: ({
|
!data
|
||||||
data,
|
? ''
|
||||||
}: VegaICellRendererParams<Position>) => {
|
: addDecimalsFormatNumber(data.unrealisedPNL, data.decimals),
|
||||||
return (
|
headerTooltip: t(
|
||||||
<div className="flex gap-2 items-center justify-end">
|
'Unrealised profit is the current profit on your open position. Margin is still allocated to your position.'
|
||||||
{data?.openVolume &&
|
),
|
||||||
data?.openVolume !== '0' &&
|
cellRenderer: PNLCell,
|
||||||
data.partyId === pubKey ? (
|
minWidth: 100,
|
||||||
<ButtonLink
|
},
|
||||||
data-testid="close-position"
|
{
|
||||||
onClick={() => data && onClose(data)}
|
headerName: t('Updated'),
|
||||||
>
|
field: 'updatedAt',
|
||||||
{t('Close')}
|
type: 'rightAligned',
|
||||||
</ButtonLink>
|
filter: DateRangeFilter,
|
||||||
) : null}
|
valueFormatter: ({
|
||||||
{data?.assetId && (
|
value,
|
||||||
<PositionActionsDropdown assetId={data?.assetId} />
|
}: VegaValueFormatterParams<Position, 'updatedAt'>) => {
|
||||||
)}
|
if (!value) {
|
||||||
</div>
|
return '';
|
||||||
);
|
}
|
||||||
},
|
return getDateTimeFormat().format(new Date(value));
|
||||||
minWidth: 90,
|
},
|
||||||
maxWidth: 90,
|
minWidth: 150,
|
||||||
}
|
},
|
||||||
: null,
|
onClose && !isReadOnly
|
||||||
];
|
? {
|
||||||
return columnDefs.filter<ColDef>(
|
...COL_DEFS.actions,
|
||||||
(colDef: ColDef | null): colDef is ColDef => colDef !== null
|
cellRenderer: ({ data }: VegaICellRendererParams<Position>) => {
|
||||||
);
|
return (
|
||||||
}, [
|
<div className="flex gap-2 items-center justify-end">
|
||||||
isReadOnly,
|
{data?.openVolume &&
|
||||||
multipleKeys,
|
data?.openVolume !== '0' &&
|
||||||
onClose,
|
data.partyId === pubKey ? (
|
||||||
onMarketClick,
|
<ButtonLink
|
||||||
openAssetDetailsDialog,
|
data-testid="close-position"
|
||||||
pubKey,
|
onClick={() => data && onClose(data)}
|
||||||
pubKeys,
|
>
|
||||||
])}
|
{t('Close')}
|
||||||
/>
|
</ButtonLink>
|
||||||
);
|
) : null}
|
||||||
}
|
{data?.assetId && (
|
||||||
);
|
<PositionActionsDropdown assetId={data?.assetId} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
minWidth: 90,
|
||||||
|
maxWidth: 90,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
];
|
||||||
|
return columnDefs.filter<ColDef>(
|
||||||
|
(colDef: ColDef | null): colDef is ColDef => colDef !== null
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
isReadOnly,
|
||||||
|
multipleKeys,
|
||||||
|
onClose,
|
||||||
|
onMarketClick,
|
||||||
|
openAssetDetailsDialog,
|
||||||
|
pubKey,
|
||||||
|
pubKeys,
|
||||||
|
])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default PositionsTable;
|
export default PositionsTable;
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useRef } from 'react';
|
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import * as Types from '@vegaprotocol/types';
|
import * as Types from '@vegaprotocol/types';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { useColumnDefs } from './use-column-defs';
|
import { useColumnDefs } from './use-column-defs';
|
||||||
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
||||||
import { useProposalsListQuery } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
import { useProposalsListQuery } from '../../lib/proposals-data-provider/__generated__/Proposals';
|
||||||
@ -25,7 +23,6 @@ interface ProposalListProps {
|
|||||||
export const ProposalsList = ({
|
export const ProposalsList = ({
|
||||||
SuccessorMarketRenderer,
|
SuccessorMarketRenderer,
|
||||||
}: ProposalListProps) => {
|
}: ProposalListProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const { data } = useProposalsListQuery({
|
const { data } = useProposalsListQuery({
|
||||||
variables: {
|
variables: {
|
||||||
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
|
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
|
||||||
@ -40,7 +37,6 @@ export const ProposalsList = ({
|
|||||||
return (
|
return (
|
||||||
<div className="relative h-full">
|
<div className="relative h-full">
|
||||||
<AgGrid
|
<AgGrid
|
||||||
ref={gridRef}
|
|
||||||
className="w-full h-full"
|
className="w-full h-full"
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
rowData={filteredData}
|
rowData={filteredData}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { useDataProvider } from '@vegaprotocol/data-provider';
|
import { useDataProvider } from '@vegaprotocol/data-provider';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { useRef } from 'react';
|
|
||||||
import { tradesWithMarketProvider } from './trades-data-provider';
|
import { tradesWithMarketProvider } from './trades-data-provider';
|
||||||
import { TradesTable } from './trades-table';
|
import { TradesTable } from './trades-table';
|
||||||
import { useCreateOrderStore } from '@vegaprotocol/orders';
|
import { useCreateOrderStore } from '@vegaprotocol/orders';
|
||||||
@ -11,7 +9,6 @@ interface TradesContainerProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const useOrderStoreRef = useCreateOrderStore();
|
const useOrderStoreRef = useCreateOrderStore();
|
||||||
const updateOrder = useOrderStoreRef((store) => store.update);
|
const updateOrder = useOrderStoreRef((store) => store.update);
|
||||||
|
|
||||||
@ -22,7 +19,6 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TradesTable
|
<TradesTable
|
||||||
ref={gridRef}
|
|
||||||
rowData={data}
|
rowData={data}
|
||||||
onClick={(price?: string) => {
|
onClick={(price?: string) => {
|
||||||
if (price) {
|
if (price) {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import { forwardRef } from 'react';
|
|
||||||
import type {
|
import type {
|
||||||
VegaICellRendererParams,
|
VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
VegaValueFormatterParams,
|
||||||
@ -48,90 +46,87 @@ interface Props extends AgGridReactProps {
|
|||||||
onClick?: (price?: string) => void;
|
onClick?: (price?: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TradesTable = forwardRef<AgGridReact, Props>(
|
export const TradesTable = ({ onClick, ...props }: Props) => {
|
||||||
({ onClick, ...props }, ref) => {
|
const columnDefs = useMemo<ColDef[]>(
|
||||||
const columnDefs = useMemo<ColDef[]>(
|
() => [
|
||||||
() => [
|
{
|
||||||
{
|
headerName: t('Price'),
|
||||||
headerName: t('Price'),
|
field: 'price',
|
||||||
field: 'price',
|
type: 'rightAligned',
|
||||||
type: 'rightAligned',
|
width: 130,
|
||||||
width: 130,
|
cellClass: changeCellClass,
|
||||||
cellClass: changeCellClass,
|
valueFormatter: ({
|
||||||
valueFormatter: ({
|
value,
|
||||||
value,
|
data,
|
||||||
data,
|
}: VegaValueFormatterParams<Trade, 'price'>) => {
|
||||||
}: VegaValueFormatterParams<Trade, 'price'>) => {
|
if (!value || !data?.market) {
|
||||||
if (!value || !data?.market) {
|
return '';
|
||||||
return '';
|
}
|
||||||
}
|
return addDecimalsFormatNumber(value, data.market.decimalPlaces);
|
||||||
return addDecimalsFormatNumber(value, data.market.decimalPlaces);
|
|
||||||
},
|
|
||||||
cellRenderer: ({
|
|
||||||
value,
|
|
||||||
data,
|
|
||||||
}: VegaICellRendererParams<Trade, 'price'>) => {
|
|
||||||
if (!data?.market || !value) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
onClick &&
|
|
||||||
onClick(addDecimal(value, data.market?.decimalPlaces || 0))
|
|
||||||
}
|
|
||||||
className="hover:dark:bg-vega-cdark-800 hover:bg-vega-clight-800"
|
|
||||||
>
|
|
||||||
{addDecimalsFormatNumber(value, data.market.decimalPlaces)}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
cellRenderer: ({
|
||||||
headerName: t('Size'),
|
value,
|
||||||
field: 'size',
|
data,
|
||||||
width: 125,
|
}: VegaICellRendererParams<Trade, 'price'>) => {
|
||||||
type: 'rightAligned',
|
if (!data?.market || !value) {
|
||||||
valueFormatter: ({
|
return '';
|
||||||
value,
|
}
|
||||||
data,
|
return (
|
||||||
}: VegaValueFormatterParams<Trade, 'size'>) => {
|
<button
|
||||||
if (!value || !data?.market) {
|
onClick={() =>
|
||||||
return '';
|
onClick &&
|
||||||
}
|
onClick(addDecimal(value, data.market?.decimalPlaces || 0))
|
||||||
return addDecimalsFormatNumber(
|
}
|
||||||
value,
|
className="hover:dark:bg-vega-cdark-800 hover:bg-vega-clight-800"
|
||||||
data.market.positionDecimalPlaces
|
>
|
||||||
);
|
{addDecimalsFormatNumber(value, data.market.decimalPlaces)}
|
||||||
},
|
</button>
|
||||||
cellRenderer: NumericCell,
|
);
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
headerName: t('Created at'),
|
{
|
||||||
field: 'createdAt',
|
headerName: t('Size'),
|
||||||
type: 'rightAligned',
|
field: 'size',
|
||||||
width: 170,
|
width: 125,
|
||||||
cellClass: 'text-right',
|
type: 'rightAligned',
|
||||||
valueFormatter: ({
|
valueFormatter: ({
|
||||||
|
value,
|
||||||
|
data,
|
||||||
|
}: VegaValueFormatterParams<Trade, 'size'>) => {
|
||||||
|
if (!value || !data?.market) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return addDecimalsFormatNumber(
|
||||||
value,
|
value,
|
||||||
}: VegaValueFormatterParams<Trade, 'createdAt'>) => {
|
data.market.positionDecimalPlaces
|
||||||
return value && getDateTimeFormat().format(new Date(value));
|
);
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
cellRenderer: NumericCell,
|
||||||
[onClick]
|
},
|
||||||
);
|
{
|
||||||
return (
|
headerName: t('Created at'),
|
||||||
<AgGrid
|
field: 'createdAt',
|
||||||
style={{ width: '100%', height: '100%' }}
|
type: 'rightAligned',
|
||||||
getRowId={({ data }) => data.id}
|
width: 170,
|
||||||
ref={ref}
|
cellClass: 'text-right',
|
||||||
defaultColDef={{
|
valueFormatter: ({
|
||||||
flex: 1,
|
value,
|
||||||
}}
|
}: VegaValueFormatterParams<Trade, 'createdAt'>) => {
|
||||||
columnDefs={columnDefs}
|
return value && getDateTimeFormat().format(new Date(value));
|
||||||
{...props}
|
},
|
||||||
/>
|
},
|
||||||
);
|
],
|
||||||
}
|
[onClick]
|
||||||
);
|
);
|
||||||
|
return (
|
||||||
|
<AgGrid
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
getRowId={({ data }) => data.id}
|
||||||
|
defaultColDef={{
|
||||||
|
flex: 1,
|
||||||
|
}}
|
||||||
|
columnDefs={columnDefs}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useEffect, useRef, useState, useMemo } from 'react';
|
import { useEffect, useRef, useState, useMemo } from 'react';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import type { ColDef } from 'ag-grid-community';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
@ -40,7 +39,6 @@ export const WithdrawalsTable = ({
|
|||||||
ready?: TimestampedWithdrawals;
|
ready?: TimestampedWithdrawals;
|
||||||
delayed?: TimestampedWithdrawals;
|
delayed?: TimestampedWithdrawals;
|
||||||
}) => {
|
}) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const createWithdrawApproval = useEthWithdrawApprovalsStore(
|
const createWithdrawApproval = useEthWithdrawApprovalsStore(
|
||||||
(store) => store.create
|
(store) => store.create
|
||||||
);
|
);
|
||||||
@ -146,7 +144,6 @@ export const WithdrawalsTable = ({
|
|||||||
CompleteCell,
|
CompleteCell,
|
||||||
}}
|
}}
|
||||||
suppressCellFocus
|
suppressCellFocus
|
||||||
ref={gridRef}
|
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user