chore(trading): tweaks and improvements of floating bottom buttons (#3138)

This commit is contained in:
Maciek 2023-03-10 00:52:38 +01:00 committed by GitHub
parent af2e52d59c
commit a575b4c502
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 106 additions and 18 deletions

View File

@ -76,6 +76,9 @@ describe(
cy.getByTestId(closeDialog).click();
cy.getByTestId('Trading').first().click();
cy.getByTestId(collateralTab).click();
cy.getByTestId(openTransferDialog).should('not.exist');
cy.getByTestId('Portfolio').eq(0).click();
cy.getByTestId(collateralTab).click();
cy.getByTestId(openTransferDialog).click();
cy.getByTestId(dialogTransferText).should(
'contain.text',

View File

@ -179,7 +179,10 @@ const MainGrid = ({
</Tab>
<Tab id="accounts" name={t('Collateral')}>
<VegaWalletContainer>
<TradingViews.Collateral pinnedAsset={pinnedAsset} />
<TradingViews.Collateral
pinnedAsset={pinnedAsset}
hideButtons
/>
</VegaWalletContainer>
</Tab>
</Tabs>

View File

@ -49,7 +49,10 @@ export const Portfolio = () => {
</Tab>
<Tab id="positions" name={t('Positions')}>
<VegaWalletContainer>
<PositionsContainer onMarketClick={onMarketClick} />
<PositionsContainer
onMarketClick={onMarketClick}
noBottomPlaceholder
/>
</VegaWalletContainer>
</Tab>
<Tab id="orders" name={t('Orders')}>

View File

@ -8,15 +8,14 @@ import { useVegaWallet } from '@vegaprotocol/wallet';
import type { PinnedAsset } from '@vegaprotocol/accounts';
import { AccountManager, useTransferDialog } from '@vegaprotocol/accounts';
import { useDepositDialog } from '@vegaprotocol/deposits';
import { useParams } from 'react-router-dom';
export const AccountsContainer = ({
pinnedAsset,
hideButtons,
}: {
pinnedAsset?: PinnedAsset;
hideButtons?: boolean;
}) => {
const params = useParams();
const hideButtons = 'marketId' in params;
const { pubKey, isReadOnly } = useVegaWallet();
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
const openWithdrawalDialog = useWithdrawalDialog((store) => store.open);
@ -49,7 +48,7 @@ export const AccountsContainer = ({
pinnedAsset={pinnedAsset}
/>
{!isReadOnly && !hideButtons && (
<div className="flex gap-2 justify-end p-2 px-[11px] fixed bottom-0 right-2 dark:bg-black/75 bg-white/75 rounded">
<div className="flex gap-2 justify-end p-2 px-[11px] absolute lg:fixed bottom-0 right-3 dark:bg-black/75 bg-white/75 rounded">
<Button
variant="primary"
size="sm"

View File

@ -14,7 +14,7 @@ export const Footer = () => {
const { blockDiff, datanodeBlockHeight } = useNodeHealth();
return (
<footer className="px-4 py-1 text-xs border-t border-default text-vega-light-300 dark:text-vega-dark-300 fixed bottom-0 left-0 border-r bg-white dark:bg-black">
<footer className="px-4 py-1 text-xs border-t border-default text-vega-light-300 dark:text-vega-dark-300 lg:fixed bottom-0 left-0 border-r bg-white dark:bg-black">
{/* Pull left to align with top nav, due to button padding */}
<div className="-ml-2">
{VEGA_URL && (

View File

@ -57,7 +57,10 @@ const update = (
});
};
export type Trade = Omit<FillFieldsFragment, 'market'> & { market?: Market };
export type Trade = Omit<FillFieldsFragment, 'market'> & {
market?: Market;
isLastPlaceholder?: boolean;
};
export type TradeEdge = Edge<Trade>;
const getData = (responseData: FillsQuery | null): FillEdgeFragment[] =>

View File

@ -1,10 +1,12 @@
import type { AgGridReact } from 'ag-grid-react';
import { useRef } from 'react';
import { useCallback, useRef } from 'react';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { FillsTable } from './fills-table';
import type { BodyScrollEvent, BodyScrollEndEvent } from 'ag-grid-community';
import { useFillsList } from './use-fills-list';
import type { Trade } from './fills-data-provider';
import { useBottomPlaceholder } from '@vegaprotocol/react-helpers';
interface FillsManagerProps {
partyId: string;
@ -19,22 +21,51 @@ export const FillsManager = ({
}: FillsManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const scrolledToTop = useRef(true);
const { data, error, loading, addNewRows, getRows, reload } = useFillsList({
const {
data,
error,
loading,
addNewRows,
getRows,
reload,
makeBottomPlaceholders,
} = useFillsList({
partyId,
marketId,
gridRef,
scrolledToTop,
});
const onBodyScrollEnd = (event: BodyScrollEndEvent) => {
if (event.top === 0) {
addNewRows();
const checkBottomPlaceholder = useCallback(() => {
const rowCont = gridRef.current?.api?.getModel().getRowCount() ?? 0;
const lastRowIndex = gridRef.current?.api?.getLastDisplayedRow();
if (lastRowIndex && rowCont - 1 === lastRowIndex) {
const lastrow = gridRef.current?.api.getDisplayedRowAtIndex(lastRowIndex);
lastrow?.setRowHeight(50);
makeBottomPlaceholders(lastrow?.data);
gridRef.current?.api.onRowHeightChanged();
gridRef.current?.api.refreshInfiniteCache();
}
};
}, [makeBottomPlaceholders]);
const onBodyScroll = (event: BodyScrollEvent) => {
const onBodyScrollEnd = useCallback(
(event: BodyScrollEndEvent) => {
if (event.top === 0) {
addNewRows();
}
checkBottomPlaceholder();
},
[addNewRows, checkBottomPlaceholder]
);
const onBodyScroll = useCallback((event: BodyScrollEvent) => {
scrolledToTop.current = event.top <= 0;
};
}, []);
const { isFullWidthRow, fullWidthCellRenderer, rowClassRules } =
useBottomPlaceholder<Trade>({
gridRef,
});
return (
<div className="h-full relative">
@ -48,6 +79,9 @@ export const FillsManager = ({
onMarketClick={onMarketClick}
suppressLoadingOverlay
suppressNoRowsOverlay
isFullWidthRow={isFullWidthRow}
fullWidthCellRenderer={fullWidthCellRenderer}
rowClassRules={rowClassRules}
/>
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer

View File

@ -22,6 +22,21 @@ export const useFillsList = ({
const dataRef = useRef<(TradeEdge | null)[] | null>(null);
const totalCountRef = useRef<number | undefined>(undefined);
const newRows = useRef(0);
const placeholderAdded = useRef(-1);
const makeBottomPlaceholders = useCallback((trade?: Trade) => {
if (!trade) {
if (placeholderAdded.current >= 0) {
dataRef.current?.splice(placeholderAdded.current, 1);
}
placeholderAdded.current = -1;
} else if (placeholderAdded.current === -1) {
dataRef.current?.push({
node: { ...trade, id: `${trade?.id}-1`, isLastPlaceholder: true },
});
placeholderAdded.current = (dataRef.current?.length || 0) - 1;
}
}, []);
const addNewRows = useCallback(() => {
if (newRows.current === 0) {
@ -87,5 +102,13 @@ export const useFillsList = ({
load,
newRows
);
return { data, error, loading, addNewRows, getRows, reload };
return {
data,
error,
loading,
addNewRows,
getRows,
reload,
makeBottomPlaceholders,
};
};

View File

@ -5,8 +5,10 @@ import { PositionsManager } from './positions-manager';
export const PositionsContainer = ({
onMarketClick,
noBottomPlaceholder,
}: {
onMarketClick?: (marketId: string) => void;
noBottomPlaceholder?: boolean;
}) => {
const { pubKey, isReadOnly } = useVegaWallet();
@ -22,6 +24,7 @@ export const PositionsContainer = ({
partyId={pubKey}
onMarketClick={onMarketClick}
isReadOnly={isReadOnly}
noBottomPlaceholder={noBottomPlaceholder}
/>
);
};

View File

@ -1,21 +1,25 @@
import { useRef } from 'react';
import { useCallback, useRef } from 'react';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import type { Position } from '../';
import { usePositionsData, PositionsTable } from '../';
import type { AgGridReact } from 'ag-grid-react';
import * as Schema from '@vegaprotocol/types';
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
import { t } from '@vegaprotocol/i18n';
import { useBottomPlaceholder } from '@vegaprotocol/react-helpers';
interface PositionsManagerProps {
partyId: string;
onMarketClick?: (marketId: string) => void;
isReadOnly: boolean;
noBottomPlaceholder?: boolean;
}
export const PositionsManager = ({
partyId,
onMarketClick,
isReadOnly,
noBottomPlaceholder,
}: PositionsManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const { data, error, loading, reload } = usePositionsData(
@ -52,6 +56,18 @@ export const PositionsManager = ({
],
},
});
const setId = useCallback((data: Position) => {
return {
...data,
marketId: `${data.marketId}-1`,
};
}, []);
const bottomPlaceholderProps = useBottomPlaceholder<Position>({
gridRef,
setId,
});
return (
<div className="h-full relative">
<PositionsTable
@ -61,6 +77,7 @@ export const PositionsManager = ({
onClose={onClose}
noRowsOverlayComponent={() => null}
isReadOnly={isReadOnly}
{...(noBottomPlaceholder ? null : bottomPlaceholderProps)}
/>
<div className="pointer-events-none absolute inset-0">
<AsyncRenderer