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 { Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
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 { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { PositionSubscribe_positions } from './__generated__/PositionSubscribe';
|
import { PositionsManager } from './positions-manager';
|
||||||
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';
|
|
||||||
|
|
||||||
export const PositionsContainer = () => {
|
export const PositionsContainer = () => {
|
||||||
const { pathname, push } = useRouter();
|
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
|
||||||
const { keypair } = useVegaWallet();
|
const { keypair } = useVegaWallet();
|
||||||
const variables = useMemo(() => ({ partyId: keypair?.pub }), [keypair]);
|
|
||||||
const update = useCallback(
|
if (!keypair) {
|
||||||
(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 (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<Splash>
|
||||||
{(data) => (
|
<p>Please connect Vega wallet</p>
|
||||||
<PositionsTable
|
</Splash>
|
||||||
ref={gridRef}
|
|
||||||
data={data}
|
|
||||||
onRowClicked={(id) =>
|
|
||||||
push(`${pathname}/${id}?portfolio=orders&trade=orderbook`)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</AsyncRenderer>
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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',
|
__typename: 'Position',
|
||||||
};
|
};
|
||||||
const singleRowData = [singleRow];
|
const singleRowData = [singleRow];
|
||||||
const onRowClicked = jest.fn;
|
|
||||||
|
|
||||||
test('should render successfully', async () => {
|
test('should render successfully', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
const { baseElement } = render(
|
const { baseElement } = render(<PositionsTable data={[]} />);
|
||||||
<PositionsTable data={[]} onRowClicked={onRowClicked} />
|
|
||||||
);
|
|
||||||
expect(baseElement).toBeTruthy();
|
expect(baseElement).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test('Render correct columns', async () => {
|
test('Render correct columns', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(<PositionsTable data={singleRowData} onRowClicked={onRowClicked} />);
|
render(<PositionsTable data={singleRowData} />);
|
||||||
});
|
});
|
||||||
|
|
||||||
const headers = screen.getAllByRole('columnheader');
|
const headers = screen.getAllByRole('columnheader');
|
||||||
@ -82,7 +79,7 @@ test('Render correct columns', async () => {
|
|||||||
|
|
||||||
test('Correct formatting applied', async () => {
|
test('Correct formatting applied', async () => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(<PositionsTable data={singleRowData} onRowClicked={onRowClicked} />);
|
render(<PositionsTable data={singleRowData} />);
|
||||||
});
|
});
|
||||||
const cells = screen.getAllByRole('gridcell');
|
const cells = screen.getAllByRole('gridcell');
|
||||||
const expectedValues = [
|
const expectedValues = [
|
||||||
|
@ -15,7 +15,6 @@ import { MarketTradingMode } from '@vegaprotocol/types';
|
|||||||
|
|
||||||
interface PositionsTableProps {
|
interface PositionsTableProps {
|
||||||
data: Positions_party_positions[] | null;
|
data: Positions_party_positions[] | null;
|
||||||
onRowClicked: (marketId: string) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRowNodeId = (data: { market: { id: string } }) =>
|
export const getRowNodeId = (data: { market: { id: string } }) =>
|
||||||
@ -47,7 +46,7 @@ interface PositionsTableValueFormatterParams extends ValueFormatterParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
|
export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
|
||||||
({ data, onRowClicked }, ref) => {
|
({ data }, ref) => {
|
||||||
const sortedData = useMemo(() => {
|
const sortedData = useMemo(() => {
|
||||||
return compact(data).sort(sortByName);
|
return compact(data).sort(sortByName);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
@ -62,9 +61,6 @@ export const PositionsTable = forwardRef<AgGridReact, PositionsTableProps>(
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
resizable: true,
|
resizable: true,
|
||||||
}}
|
}}
|
||||||
onRowClicked={({ data }: { data: Positions_party_positions }) =>
|
|
||||||
onRowClicked(getRowNodeId(data))
|
|
||||||
}
|
|
||||||
components={{ PriceCell }}
|
components={{ PriceCell }}
|
||||||
>
|
>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
|
@ -19,9 +19,13 @@ export function AsyncRenderer<T = any>({
|
|||||||
return <Splash>Something went wrong: {error.message}</Splash>;
|
return <Splash>Something went wrong: {error.message}</Splash>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading || !data) {
|
if (loading) {
|
||||||
return <Splash>Loading...</Splash>;
|
return <Splash>Loading...</Splash>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return <Splash>No data</Splash>;
|
||||||
|
}
|
||||||
|
|
||||||
return <>{children(data)}</>;
|
return <>{children(data)}</>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user