diff --git a/apps/console-lite-e2e/src/integration/portfolio-page.test.ts b/apps/console-lite-e2e/src/integration/portfolio-page.test.ts
index 37ad33eab..6749b99db 100644
--- a/apps/console-lite-e2e/src/integration/portfolio-page.test.ts
+++ b/apps/console-lite-e2e/src/integration/portfolio-page.test.ts
@@ -66,7 +66,9 @@ describe('Portfolio page tabs', { tags: '@smoke' }, () => {
it('data should be properly rendered', () => {
cy.get('.ag-center-cols-container .ag-row').should('have.length', 5);
- cy.contains('.ag-center-cols-container button', 'tEURO').click();
+ cy.get('[role="gridcell"][col-id="account-asset"] button')
+ .contains('tEURO')
+ .click();
cy.getByTestId('dialog-title').should(
'have.text',
'Asset details - tEURO'
diff --git a/libs/fills/src/lib/fills-table.spec.tsx b/libs/fills/src/lib/fills-table.spec.tsx
index a4b9008ee..51175e234 100644
--- a/libs/fills/src/lib/fills-table.spec.tsx
+++ b/libs/fills/src/lib/fills-table.spec.tsx
@@ -1,4 +1,5 @@
import { act, render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
import * as Schema from '@vegaprotocol/types';
import type { PartialDeep } from 'type-fest';
@@ -57,8 +58,8 @@ describe('FillsTable', () => {
const expectedHeaders = [
'Market',
'Size',
- 'Value',
- 'Filled value',
+ 'Price',
+ 'Notional',
'Role',
'Fee',
'Date',
@@ -82,7 +83,7 @@ describe('FillsTable', () => {
},
});
- render();
+ render();
await waitForGridToBeInTheDOM();
await waitForDataToHaveLoaded();
@@ -179,4 +180,38 @@ describe('FillsTable', () => {
.find((c) => c.getAttribute('col-id') === 'aggressor')
).toHaveTextContent('Maker');
});
+
+ it('should render tooltip over fees', async () => {
+ const partyId = 'party-id';
+ const takerFill = generateFill({
+ seller: {
+ id: partyId,
+ },
+ aggressor: Schema.Side.SIDE_SELL,
+ });
+ act(() => {
+ render();
+ });
+ await waitForGridToBeInTheDOM();
+ await waitForDataToHaveLoaded();
+
+ const feeCell = screen
+ .getAllByRole('gridcell')
+ .find(
+ (c) =>
+ c.getAttribute('col-id') ===
+ 'market.tradableInstrument.instrument.product'
+ );
+
+ await waitFor(() => {
+ expect(feeCell).toBeInTheDocument();
+ });
+ act(() => {
+ userEvent.hover(feeCell as HTMLElement);
+ });
+
+ await waitFor(() => {
+ expect(screen.getByTestId('fee-breakdown-tooltip')).toBeInTheDocument();
+ });
+ });
});
diff --git a/libs/fills/src/lib/fills-table.tsx b/libs/fills/src/lib/fills-table.tsx
index 5fdbe1755..b2d1724ab 100644
--- a/libs/fills/src/lib/fills-table.tsx
+++ b/libs/fills/src/lib/fills-table.tsx
@@ -1,4 +1,9 @@
-import type { AgGridReact } from 'ag-grid-react';
+import type {
+ AgGridReact,
+ AgGridReactProps,
+ AgReactUiProps,
+} from 'ag-grid-react';
+import type { ITooltipParams } from 'ag-grid-community';
import {
addDecimal,
addDecimalsFormatNumber,
@@ -15,7 +20,6 @@ import type { VegaValueFormatterParams } from '@vegaprotocol/ui-toolkit';
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
import { forwardRef } from 'react';
import BigNumber from 'bignumber.js';
-import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
import type { Trade } from './fills-data-provider';
export type Props = (AgGridReactProps | AgReactUiProps) & {
@@ -31,6 +35,8 @@ export const FillsTable = forwardRef(
defaultColDef={{ flex: 1, resizable: true }}
style={{ width: '100%', height: '100%' }}
getRowId={({ data }) => data?.id}
+ tooltipShowDelay={0}
+ tooltipHideDelay={2000}
{...props}
>
(
valueFormatter={formatSize(partyId)}
/>
(
field="market.tradableInstrument.instrument.product"
valueFormatter={formatFee(partyId)}
type="rightAligned"
+ tooltipField="market.tradableInstrument.instrument.product"
+ tooltipComponent={FeesBreakdownTooltip}
+ tooltipComponentParams={{ partyId }}
/>
{
@@ -210,3 +218,50 @@ const formatFee = (partyId: string) => {
return `${totalFees} ${asset.symbol}`;
};
};
+
+const FeesBreakdownTooltip = ({
+ data,
+ value,
+ valueFormatted,
+ partyId,
+}: ITooltipParams & { partyId?: string }) => {
+ if (!value?.settlementAsset || !data) {
+ return null;
+ }
+ const asset = value.settlementAsset;
+ let feesObj;
+ if (data?.buyer.id === partyId) {
+ feesObj = data?.buyerFee;
+ } else if (data?.seller.id === partyId) {
+ feesObj = data?.sellerFee;
+ } else {
+ return null;
+ }
+
+ return (
+
+
+ - {t('Infrastructure fee')}
+ -
+ {addDecimalsFormatNumber(feesObj.infrastructureFee, asset.decimals)}{' '}
+ {asset.symbol}
+
+ - {t('Liquidity fee')}
+ -
+ {addDecimalsFormatNumber(feesObj.liquidityFee, asset.decimals)}{' '}
+ {asset.symbol}
+
+ - {t('Maker fee')}
+ -
+ {addDecimalsFormatNumber(feesObj.makerFee, asset.decimals)}{' '}
+ {asset.symbol}
+
+ - {t('Total fees')}
+ - {valueFormatted}
+
+
+ );
+};