prevent positions table if not party id provided, handle no data in async renderer
This commit is contained in:
parent
3394050f76
commit
858bd372d2
@ -1,69 +1,17 @@
|
||||
import { useRef, useCallback, useMemo } from 'react';
|
||||
import { produce } from 'immer';
|
||||
import merge from 'lodash/merge';
|
||||
import { useRouter } from 'next/router';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { PositionSubscribe_positions } from './__generated__/PositionSubscribe';
|
||||
import { Positions_party_positions } from './__generated__/Positions';
|
||||
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import PositionsTable, { getRowNodeId } from './positions-table';
|
||||
import { positionsDataProvider } from './positions-data-provider';
|
||||
import { PositionsManager } from './positions-manager';
|
||||
|
||||
export const PositionsContainer = () => {
|
||||
const { pathname, push } = useRouter();
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const { keypair } = useVegaWallet();
|
||||
const variables = useMemo(() => ({ partyId: keypair?.pub }), [keypair]);
|
||||
const update = useCallback(
|
||||
(delta: PositionSubscribe_positions) => {
|
||||
const update: Positions_party_positions[] = [];
|
||||
const add: Positions_party_positions[] = [];
|
||||
if (!gridRef.current) {
|
||||
return false;
|
||||
}
|
||||
const rowNode = gridRef.current.api.getRowNode(getRowNodeId(delta));
|
||||
if (rowNode) {
|
||||
const updatedData = produce<Positions_party_positions>(
|
||||
rowNode.data,
|
||||
(draft: Positions_party_positions) => {
|
||||
merge(draft, delta);
|
||||
}
|
||||
);
|
||||
if (updatedData !== rowNode.data) {
|
||||
update.push(updatedData);
|
||||
}
|
||||
} else {
|
||||
add.push(delta);
|
||||
}
|
||||
if (update.length || add.length) {
|
||||
gridRef.current.api.applyTransactionAsync({
|
||||
update,
|
||||
add,
|
||||
addIndex: 0,
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[gridRef]
|
||||
);
|
||||
const { data, error, loading } = useDataProvider<
|
||||
Positions_party_positions,
|
||||
PositionSubscribe_positions
|
||||
>(positionsDataProvider, update, variables);
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
{(data) => (
|
||||
<PositionsTable
|
||||
ref={gridRef}
|
||||
data={data}
|
||||
onRowClicked={(id) =>
|
||||
push(`${pathname}/${id}?portfolio=orders&trade=orderbook`)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
|
||||
if (!keypair) {
|
||||
return (
|
||||
<Splash>
|
||||
<p>Please connect Vega wallet</p>
|
||||
</Splash>
|
||||
);
|
||||
}
|
||||
|
||||
return <PositionsManager partyId={keypair.pub} />;
|
||||
};
|
||||
|
61
libs/positions/src/lib/positions-manager.tsx
Normal file
61
libs/positions/src/lib/positions-manager.tsx
Normal file
@ -0,0 +1,61 @@
|
||||
import { useRef, useCallback, useMemo } from 'react';
|
||||
import { produce } from 'immer';
|
||||
import merge from 'lodash/merge';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { PositionSubscribe_positions } from './__generated__/PositionSubscribe';
|
||||
import { Positions_party_positions } from './__generated__/Positions';
|
||||
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import PositionsTable, { getRowNodeId } from './positions-table';
|
||||
import { positionsDataProvider } from './positions-data-provider';
|
||||
|
||||
interface PositionsManagerProps {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
export const PositionsManager = ({ partyId }: PositionsManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
const update = useCallback(
|
||||
(delta: PositionSubscribe_positions) => {
|
||||
const update: Positions_party_positions[] = [];
|
||||
const add: Positions_party_positions[] = [];
|
||||
if (!gridRef.current) {
|
||||
return false;
|
||||
}
|
||||
const rowNode = gridRef.current.api.getRowNode(getRowNodeId(delta));
|
||||
if (rowNode) {
|
||||
const updatedData = produce<Positions_party_positions>(
|
||||
rowNode.data,
|
||||
(draft: Positions_party_positions) => {
|
||||
merge(draft, delta);
|
||||
}
|
||||
);
|
||||
if (updatedData !== rowNode.data) {
|
||||
update.push(updatedData);
|
||||
}
|
||||
} else {
|
||||
add.push(delta);
|
||||
}
|
||||
if (update.length || add.length) {
|
||||
gridRef.current.api.applyTransactionAsync({
|
||||
update,
|
||||
add,
|
||||
addIndex: 0,
|
||||
});
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[gridRef]
|
||||
);
|
||||
const { data, error, loading } = useDataProvider<
|
||||
Positions_party_positions,
|
||||
PositionSubscribe_positions
|
||||
>(positionsDataProvider, update, variables);
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
{(data) => <PositionsTable ref={gridRef} data={data} />}
|
||||
</AsyncRenderer>
|
||||
);
|
||||
};
|
@ -54,19 +54,16 @@ const singleRow: Positions_party_positions = {
|
||||
__typename: 'Position',
|
||||
};
|
||||
const singleRowData = [singleRow];
|
||||
const onRowClicked = jest.fn;
|
||||
|
||||
test('should render successfully', async () => {
|
||||
await act(async () => {
|
||||
const { baseElement } = render(
|
||||
<PositionsTable data={[]} onRowClicked={onRowClicked} />
|
||||
);
|
||||
const { baseElement } = render(<PositionsTable data={[]} />);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
});
|
||||
test('Render correct columns', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable data={singleRowData} onRowClicked={onRowClicked} />);
|
||||
render(<PositionsTable data={singleRowData} />);
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
@ -82,7 +79,7 @@ test('Render correct columns', async () => {
|
||||
|
||||
test('Correct formatting applied', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable data={singleRowData} onRowClicked={onRowClicked} />);
|
||||
render(<PositionsTable data={singleRowData} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const expectedValues = [
|
||||
|
@ -15,7 +15,6 @@ import { MarketTradingMode } from '@vegaprotocol/types';
|
||||
|
||||
interface PositionsTableProps {
|
||||
data: Positions_party_positions[] | null;
|
||||
onRowClicked: (marketId: string) => void;
|
||||
}
|
||||
|
||||
export const getRowNodeId = (data: { market: { id: string } }) =>
|
||||
@ -47,7 +46,7 @@ interface PositionsTableValueFormatterParams extends ValueFormatterParams {
|
||||
}
|
||||
|
||||
export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
|
||||
({ data, onRowClicked }, ref) => {
|
||||
({ data }, ref) => {
|
||||
const sortedData = useMemo(() => {
|
||||
return compact(data).sort(sortByName);
|
||||
}, [data]);
|
||||
@ -62,9 +61,6 @@ export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
|
||||
flex: 1,
|
||||
resizable: true,
|
||||
}}
|
||||
onRowClicked={({ data }: { data: Positions_party_positions }) =>
|
||||
onRowClicked(getRowNodeId(data))
|
||||
}
|
||||
components={{ PriceCell }}
|
||||
>
|
||||
<AgGridColumn
|
||||
|
@ -19,9 +19,13 @@ export function AsyncRenderer<T = any>({
|
||||
return <Splash>Something went wrong: {error.message}</Splash>;
|
||||
}
|
||||
|
||||
if (loading || !data) {
|
||||
if (loading) {
|
||||
return <Splash>Loading...</Splash>;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return <Splash>No data</Splash>;
|
||||
}
|
||||
|
||||
return <>{children(data)}</>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user