From c8ec793b656f66cfa7b94bdacb08546e2d1ce7bd Mon Sep 17 00:00:00 2001 From: Maciek Date: Wed, 15 Mar 2023 16:08:48 +0100 Subject: [PATCH] chore(trading): make loading masks in tabs consistent along the app (#3155) --- .../portfolio/deposits-container.tsx | 3 +- .../portfolio/withdrawals-container.tsx | 3 +- .../src/lib/accounts-manager.spec.tsx | 138 +++++++++++------- libs/accounts/src/lib/accounts-manager.tsx | 3 +- libs/positions/src/lib/positions-manager.tsx | 17 ++- 5 files changed, 106 insertions(+), 58 deletions(-) diff --git a/apps/trading/client-pages/portfolio/deposits-container.tsx b/apps/trading/client-pages/portfolio/deposits-container.tsx index 94bef6141..b73bb9d5c 100644 --- a/apps/trading/client-pages/portfolio/deposits-container.tsx +++ b/apps/trading/client-pages/portfolio/deposits-container.tsx @@ -25,7 +25,8 @@ export const DepositsContainer = () => {
null} + suppressLoadingOverlay + suppressNoRowsOverlay ref={gridRef} {...bottomPlaceholderProps} /> diff --git a/apps/trading/client-pages/portfolio/withdrawals-container.tsx b/apps/trading/client-pages/portfolio/withdrawals-container.tsx index 409e1df5d..4168ac6a4 100644 --- a/apps/trading/client-pages/portfolio/withdrawals-container.tsx +++ b/apps/trading/client-pages/portfolio/withdrawals-container.tsx @@ -24,7 +24,8 @@ export const WithdrawalsContainer = () => { null} + suppressLoadingOverlay + suppressNoRowsOverlay />
({ })); describe('AccountManager', () => { - beforeEach(() => { - mockedUseDataProvider - .mockImplementationOnce((args) => { - return { - data: [], - }; - }) - .mockImplementationOnce((args) => { - return { - data: [ - { asset: { id: 'a1' }, party: { id: 't1' } }, - { asset: { id: 'a2' }, party: { id: 't2' } }, - ], - }; - }); - }); - - it('change partyId should reload data provider', async () => { - const { rerender } = render( - - ); - expect( - (helpers.useDataProvider as jest.Mock).mock.calls[0][0].variables.partyId - ).toEqual('partyOne'); - await act(() => { - rerender( - - ); + describe('when rerender', () => { + beforeEach(() => { + mockedUseDataProvider + .mockImplementationOnce((args) => { + return { + data: [], + }; + }) + .mockImplementationOnce((args) => { + return { + data: [ + { asset: { id: 'a1' }, party: { id: 't1' } }, + { asset: { id: 'a2' }, party: { id: 't2' } }, + ], + }; + }); }); - expect( - (helpers.useDataProvider as jest.Mock).mock.calls[1][0].variables.partyId - ).toEqual('partyTwo'); - }); - it('update method should return proper result', async () => { - let rerenderer: (ui: React.ReactElement) => void; - await act(() => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('change partyId should reload data provider', async () => { const { rerender } = render( { isReadOnly={false} /> ); - rerenderer = rerender; + expect( + (helpers.useDataProvider as jest.Mock).mock.calls[0][0].variables + .partyId + ).toEqual('partyOne'); + await act(() => { + rerender( + + ); + }); + expect( + (helpers.useDataProvider as jest.Mock).mock.calls[1][0].variables + .partyId + ).toEqual('partyTwo'); }); - await waitFor(() => { - expect(screen.getByText('No accounts')).toBeInTheDocument(); + + it('update method should return proper result', async () => { + let rerenderer: (ui: React.ReactElement) => void; + await act(() => { + const { rerender } = render( + + ); + rerenderer = rerender; + }); + await waitFor(() => { + expect(screen.getByText('No accounts')).toBeInTheDocument(); + }); + await act(() => { + rerenderer( + + ); + }); + + const container = document.querySelector('.ag-center-cols-container'); + await waitFor(() => { + expect(container).toBeInTheDocument(); + }); + expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2); + }); + }); + + it('splash loading should be displayed', async () => { + mockedUseDataProvider.mockImplementation((args) => { + return { + loading: true, + data: null, + }; }); await act(() => { - rerenderer( + render( { /> ); }); - - const container = document.querySelector('.ag-center-cols-container'); await waitFor(() => { - expect(container).toBeInTheDocument(); + expect( + screen.getByText( + (content, element) => + Boolean( + element?.className.endsWith('flex items-center justify-center') + ) && content.startsWith('Loading') + ) + ).toBeInTheDocument(); }); - expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2); }); }); diff --git a/libs/accounts/src/lib/accounts-manager.tsx b/libs/accounts/src/lib/accounts-manager.tsx index 90f3f321c..019bd29d3 100644 --- a/libs/accounts/src/lib/accounts-manager.tsx +++ b/libs/accounts/src/lib/accounts-manager.tsx @@ -60,7 +60,8 @@ export const AccountManager = ({ onClickDeposit={onClickDeposit} onClickWithdraw={onClickWithdraw} isReadOnly={isReadOnly} - noRowsOverlayComponent={() => null} + suppressLoadingOverlay + suppressNoRowsOverlay pinnedAsset={pinnedAsset} getRowHeight={getRowHeight} {...bottomPlaceholderProps} diff --git a/libs/positions/src/lib/positions-manager.tsx b/libs/positions/src/lib/positions-manager.tsx index 206bb4ad5..834146699 100644 --- a/libs/positions/src/lib/positions-manager.tsx +++ b/libs/positions/src/lib/positions-manager.tsx @@ -1,7 +1,8 @@ -import { useCallback, useRef } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; import type { Position } from '../'; import { usePositionsData, PositionsTable } from '../'; +import type { FilterChangedEvent } from 'ag-grid-community'; import type { AgGridReact } from 'ag-grid-react'; import * as Schema from '@vegaprotocol/types'; import { useVegaTransactionStore } from '@vegaprotocol/wallet'; @@ -22,6 +23,7 @@ export const PositionsManager = ({ noBottomPlaceholder, }: PositionsManagerProps) => { const gridRef = useRef(null); + const [dataCount, setDataCount] = useState(0); const { data, error, loading, reload } = usePositionsData( partyId, gridRef, @@ -67,7 +69,12 @@ export const PositionsManager = ({ gridRef, setId, }); - + useEffect(() => { + setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0); + }, [data]); + const onFilterChanged = useCallback((event: FilterChangedEvent) => { + setDataCount(gridRef.current?.api?.getModel().getRowCount() ?? 0); + }, []); return (
null} + suppressLoadingOverlay + suppressNoRowsOverlay isReadOnly={isReadOnly} + onFilterChanged={onFilterChanged} {...(noBottomPlaceholder ? null : bottomPlaceholderProps)} />
@@ -85,7 +94,7 @@ export const PositionsManager = ({ error={error} data={data} noDataMessage={t('No positions')} - noDataCondition={(data) => !(data && data.length)} + noDataCondition={(data) => !dataCount} reload={reload} />