chore(orders): 4970 add no rows and error info (#5076)

This commit is contained in:
Maciek 2023-10-19 15:45:55 +02:00 committed by GitHub
parent a98ab775c3
commit 2dfcb02d1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 102 additions and 27 deletions

View File

@ -10,6 +10,19 @@ import type { DataGridStore } from '../../stores/datagrid-store-slice';
import { OrderStatus } from '@vegaprotocol/types';
import { Links } from '../../lib/links';
const resolveNoRowsMessage = (filter?: Filter) => {
switch (filter) {
case Filter.Open:
return t('No open orders');
case Filter.Closed:
return t('No closed orders');
case Filter.Rejected:
return t('No rejected orders');
default:
return t('No orders');
}
};
export const FilterStatusValue = {
[Filter.Open]: [OrderStatus.STATUS_ACTIVE, OrderStatus.STATUS_PARKED],
[Filter.Closed]: [
@ -43,6 +56,7 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
if (!pubKey) {
return <Splash>{t('Please connect Vega wallet')}</Splash>;
}
const noRowsMessage = resolveNoRowsMessage(filter);
return (
<OrderListManager
@ -56,6 +70,7 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
}
isReadOnly={isReadOnly}
gridProps={gridStoreCallbacks}
noRowsMessage={noRowsMessage}
/>
);
};

View File

@ -63,7 +63,9 @@ export const CandlesChartContainer = ({
overlays,
studies,
notEnoughDataText: (
<span className="text-xs text-center">{t('No data')}</span>
<span className="text-xs text-center">
{t('No open orders')}
</span>
),
initialNumCandlesToDisplay: candlesCount,
studySize: STUDY_SIZE,

View File

@ -238,7 +238,7 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
volumeFormat={volumeFormat}
priceFormat={priceFormat}
notEnoughDataText={
<span className="text-xs text-center">{t('No data')}</span>
<span className="text-xs text-center">{t('No open orders')}</span>
}
/>
)}

View File

@ -11,14 +11,8 @@ import type {
MarketDepthQuery,
MarketDepthQueryVariables,
MarketDepthUpdateSubscription,
PriceLevelFieldsFragment,
} from './__generated__/MarketDepth';
export type OrderbookData = {
asks: PriceLevelFieldsFragment[];
bids: PriceLevelFieldsFragment[];
};
interface OrderbookManagerProps {
marketId: string;
onClick: (args: { price?: string; size?: string }) => void;

View File

@ -238,7 +238,7 @@ export const Orderbook = ({
</>
) : (
<div className="absolute inset-0">
<Splash>{t('No data')}</Splash>
<Splash>{t('No open orders')}</Splash>
</div>
)}
</div>

View File

@ -1,23 +1,18 @@
import { render, screen, act } from '@testing-library/react';
import { OrderListManager } from './order-list-manager';
import { render, screen } from '@testing-library/react';
import type { OrderListManagerProps } from './order-list-manager';
import { OrderListManager, Filter } from './order-list-manager';
import * as useDataProviderHook from '@vegaprotocol/data-provider';
import type { OrderFieldsFragment } from '../';
import * as orderListMock from '../order-list/order-list';
import { forwardRef } from 'react';
import type { VegaWalletContextShape } from '@vegaprotocol/wallet';
import { VegaWalletContext } from '@vegaprotocol/wallet';
import { MockedProvider } from '@apollo/client/testing';
// @ts-ignore OrderList is read only but we need to override with the forwardRef to
// avoid warnings about padding refs
orderListMock.OrderListTable = forwardRef(() => <div>OrderList</div>);
const generateJsx = () => {
const generateJsx = (props: Partial<OrderListManagerProps> | null = null) => {
const pubKey = '0x123';
return (
<MockedProvider>
<VegaWalletContext.Provider value={{ pubKey } as VegaWalletContextShape}>
<OrderListManager partyId={pubKey} isReadOnly={false} />
<OrderListManager partyId={pubKey} isReadOnly={false} {...props} />
</VegaWalletContext.Provider>
</MockedProvider>
);
@ -33,9 +28,46 @@ describe('OrderListManager', () => {
reload: jest.fn(),
load: jest.fn(),
});
await act(async () => {
render(generateJsx());
render(generateJsx());
expect(
await screen.getByRole('treegrid', {
name: (_, element) => element.classList.contains('ag-root'),
})
).toBeInTheDocument();
});
it('should display order info', async () => {
jest.spyOn(useDataProviderHook, 'useDataProvider').mockReturnValue({
data: [{ id: '1' } as OrderFieldsFragment],
loading: false,
error: new Error('Query error'),
flush: jest.fn(),
reload: jest.fn(),
load: jest.fn(),
});
expect(await screen.findByText('OrderList')).toBeInTheDocument();
render(generateJsx());
expect(
await screen.getByText('Something went wrong: Query error')
).toBeInTheDocument();
});
it('should display no rows overlay', async () => {
jest.spyOn(useDataProviderHook, 'useDataProvider').mockReturnValue({
data: [],
loading: false,
error: undefined,
flush: jest.fn(),
reload: jest.fn(),
load: jest.fn(),
});
render(
generateJsx({ filter: Filter.Closed, noRowsMessage: 'no rows message' })
);
expect(screen.getByText('no rows message')).toBeInTheDocument();
});
});

View File

@ -1,7 +1,8 @@
import { t } from '@vegaprotocol/i18n';
import { useCallback, useRef, useState } from 'react';
import { useCallback, useRef, useState, useEffect } from 'react';
import type { AgGridReact } from 'ag-grid-react';
import { OrderListTable } from '../order-list/order-list';
import type { FilterChangedEvent } from 'ag-grid-community';
import { OrderListTable } from '../order-list';
import type { useDataGridEvents } from '@vegaprotocol/datagrid';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { ordersWithMarketProvider } from '../order-data-provider/order-data-provider';
@ -11,6 +12,7 @@ import type { OrderTxUpdateFieldsFragment } from '@vegaprotocol/web3';
import { OrderEditDialog } from '../order-list/order-edit-dialog';
import type { Order } from '../order-data-provider';
import { OrderViewDialog } from '../order-list/order-view-dialog';
import { Splash } from '@vegaprotocol/ui-toolkit';
export enum Filter {
'Open' = 'Open',
@ -25,6 +27,7 @@ export interface OrderListManagerProps {
isReadOnly: boolean;
filter?: Filter;
gridProps?: ReturnType<typeof useDataGridEvents>;
noRowsMessage?: string;
}
export const OrderListManager = ({
@ -34,6 +37,7 @@ export const OrderListManager = ({
isReadOnly,
filter,
gridProps,
noRowsMessage,
}: OrderListManagerProps) => {
const gridRef = useRef<AgGridReact | null>(null);
const [editOrder, setEditOrder] = useState<Order | null>(null);
@ -56,6 +60,29 @@ export const OrderListManager = ({
},
});
const onFilterChanged = useCallback(
(event: FilterChangedEvent) => {
gridProps?.onFilterChanged?.(event);
if (event.api) {
const isEmpty = event.api.getDisplayedRowCount() === 0;
if (isEmpty) {
event.api.showNoRowsOverlay();
} else {
event.api.hideOverlay();
}
}
},
[gridProps]
);
useEffect(() => {
if (!data || !data.length) {
gridRef.current?.api?.showNoRowsOverlay();
} else {
gridRef.current?.api?.hideOverlay();
}
}, [data]);
const cancel = useCallback(
(order: Order) => {
if (!order.market) return;
@ -69,6 +96,10 @@ export const OrderListManager = ({
[create]
);
if (error) {
return <Splash>{t(`Something went wrong: ${error.message}`)}</Splash>;
}
return (
<>
<div className="h-full relative">
@ -82,8 +113,9 @@ export const OrderListManager = ({
onMarketClick={onMarketClick}
onOrderTypeClick={onOrderTypeClick}
isReadOnly={isReadOnly}
overlayNoRowsTemplate={error ? error.message : t('No orders')}
overlayNoRowsTemplate={noRowsMessage || t('No orders')}
{...gridProps}
onFilterChanged={onFilterChanged}
/>
</div>
{editOrder && (

View File

@ -34,7 +34,7 @@ import type {
} from '@vegaprotocol/datagrid';
import type { AgGridReact } from 'ag-grid-react';
import type { Order } from '../order-data-provider';
import { Filter } from '../order-list-manager';
import { Filter } from '../order-list-manager/order-list-manager';
import type { ColDef } from 'ag-grid-community';
const defaultColDef = {

View File

@ -58,7 +58,7 @@ type ThemeStore = {
setTheme: (theme?: Theme) => void;
};
const useThemeStore = create<ThemeStore>((set) => ({
const useThemeStore = create<ThemeStore>()((set) => ({
theme: getCurrentTheme(),
setTheme: (newTheme) => {
set((state) => {