fix(trading): consolidate view as user mode (#2778)
This commit is contained in:
parent
01f0934da3
commit
b40358a723
@ -5,7 +5,7 @@ import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export const DepositsContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: depositsProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
@ -30,15 +30,17 @@ export const DepositsContainer = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => openDepositDialog()}
|
||||
data-testid="deposit-button"
|
||||
>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => openDepositDialog()}
|
||||
data-testid="deposit-button"
|
||||
>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
||||
|
||||
export const WithdrawalsContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { data, loading, error } = useDataProvider({
|
||||
dataProvider: withdrawalProvider,
|
||||
variables: { partyId: pubKey || '' },
|
||||
@ -36,15 +36,17 @@ export const WithdrawalsContainer = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => openWithdrawDialog()}
|
||||
data-testid="withdraw-dialog-button"
|
||||
>
|
||||
{t('Make withdrawal')}
|
||||
</Button>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
<div className="w-full dark:bg-black bg-white absolute bottom-0 h-auto flex justify-end px-[11px] py-2">
|
||||
<Button
|
||||
size="sm"
|
||||
onClick={() => openWithdrawDialog()}
|
||||
data-testid="withdraw-dialog-button"
|
||||
>
|
||||
{t('Make withdrawal')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</VegaWalletContainer>
|
||||
);
|
||||
|
@ -9,7 +9,7 @@ import { AccountManager } from '@vegaprotocol/accounts';
|
||||
import { useDepositDialog } from '@vegaprotocol/deposits';
|
||||
|
||||
export const AccountsContainer = () => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
const openWithdrawalDialog = useWithdrawalDialog((store) => store.open);
|
||||
const openDepositDialog = useDepositDialog((store) => store.open);
|
||||
@ -37,13 +37,16 @@ export const AccountsContainer = () => {
|
||||
onClickAsset={onClickAsset}
|
||||
onClickWithdraw={openWithdrawalDialog}
|
||||
onClickDeposit={openDepositDialog}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end p-2 px-[11px]">
|
||||
<Button size="sm" onClick={() => openDepositDialog()}>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
{!isReadOnly && (
|
||||
<div className="flex justify-end p-2 px-[11px]">
|
||||
<Button size="sm" onClick={() => openDepositDialog()}>
|
||||
{t('Deposit')}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -23,13 +23,23 @@ jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
describe('AccountManager', () => {
|
||||
it('change partyId should reload data provider', async () => {
|
||||
const { rerender } = render(
|
||||
<AccountManager partyId="partyOne" onClickAsset={jest.fn} />
|
||||
<AccountManager
|
||||
partyId="partyOne"
|
||||
onClickAsset={jest.fn}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
expect(
|
||||
(helpers.useDataProvider as jest.Mock).mock.calls[0][0].variables.partyId
|
||||
).toEqual('partyOne');
|
||||
await act(() => {
|
||||
rerender(<AccountManager partyId="partyTwo" onClickAsset={jest.fn} />);
|
||||
rerender(
|
||||
<AccountManager
|
||||
partyId="partyTwo"
|
||||
onClickAsset={jest.fn}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
expect(
|
||||
(helpers.useDataProvider as jest.Mock).mock.calls[1][0].variables.partyId
|
||||
@ -38,7 +48,13 @@ describe('AccountManager', () => {
|
||||
|
||||
it('update method should return proper result', async () => {
|
||||
await act(() => {
|
||||
render(<AccountManager partyId="partyOne" onClickAsset={jest.fn} />);
|
||||
render(
|
||||
<AccountManager
|
||||
partyId="partyOne"
|
||||
onClickAsset={jest.fn}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('No accounts')).toBeInTheDocument();
|
||||
|
@ -16,6 +16,7 @@ interface AccountManagerProps {
|
||||
onClickAsset: (assetId: string) => void;
|
||||
onClickWithdraw?: (assetId?: string) => void;
|
||||
onClickDeposit?: (assetId?: string) => void;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
export const AccountManager = ({
|
||||
@ -23,6 +24,7 @@ export const AccountManager = ({
|
||||
onClickWithdraw,
|
||||
onClickDeposit,
|
||||
partyId,
|
||||
isReadOnly,
|
||||
}: AccountManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const dataRef = useRef<AccountFields[] | null>(null);
|
||||
@ -58,6 +60,7 @@ export const AccountManager = ({
|
||||
onClickAsset={onClickAsset}
|
||||
onClickDeposit={onClickDeposit}
|
||||
onClickWithdraw={onClickWithdraw}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
|
@ -35,7 +35,11 @@ describe('AccountsTable', () => {
|
||||
it('should render correct columns', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<AccountTable rowData={singleRowData} onClickAsset={() => null} />
|
||||
<AccountTable
|
||||
rowData={singleRowData}
|
||||
onClickAsset={() => null}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const expectedHeaders = ['Asset', 'Total', 'Used', 'Available', ''];
|
||||
@ -49,7 +53,11 @@ describe('AccountsTable', () => {
|
||||
it('should apply correct formatting', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<AccountTable rowData={singleRowData} onClickAsset={() => null} />
|
||||
<AccountTable
|
||||
rowData={singleRowData}
|
||||
onClickAsset={() => null}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
const cells = await screen.findAllByRole('gridcell');
|
||||
|
@ -29,6 +29,7 @@ export interface AccountTableProps extends AgGridReactProps {
|
||||
onClickAsset: (assetId: string) => void;
|
||||
onClickWithdraw?: (assetId: string) => void;
|
||||
onClickDeposit?: (assetId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
@ -127,48 +128,50 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
}
|
||||
maxWidth={300}
|
||||
/>
|
||||
<AgGridColumn
|
||||
colId="breakdown"
|
||||
headerName=""
|
||||
sortable={false}
|
||||
minWidth={200}
|
||||
type="rightAligned"
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
return data ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
) : null;
|
||||
}}
|
||||
/>
|
||||
{!props.isReadOnly && (
|
||||
<AgGridColumn
|
||||
colId="breakdown"
|
||||
headerName=""
|
||||
sortable={false}
|
||||
minWidth={200}
|
||||
type="rightAligned"
|
||||
cellRenderer={({
|
||||
data,
|
||||
}: VegaICellRendererParams<AccountFields>) => {
|
||||
return data ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="breakdown"
|
||||
onClick={() => {
|
||||
setOpenBreakdown(!openBreakdown);
|
||||
setBreakdown(data.breakdown || null);
|
||||
}}
|
||||
>
|
||||
{t('Breakdown')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="deposit"
|
||||
onClick={() => {
|
||||
onClickDeposit && onClickDeposit(data.asset.id);
|
||||
}}
|
||||
>
|
||||
{t('Deposit')}
|
||||
</ButtonLink>
|
||||
<span className="mx-1" />
|
||||
<ButtonLink
|
||||
data-testid="withdraw"
|
||||
onClick={() =>
|
||||
onClickWithdraw && onClickWithdraw(data.asset.id)
|
||||
}
|
||||
>
|
||||
{t('Withdraw')}
|
||||
</ButtonLink>
|
||||
</>
|
||||
) : null;
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</AgGrid>
|
||||
<Dialog size="medium" open={openBreakdown} onChange={setOpenBreakdown}>
|
||||
<div className="h-[35vh] w-full m-auto flex flex-col">
|
||||
|
@ -45,7 +45,7 @@ export type DealTicketFormFields = OrderSubmissionBody['orderSubmission'] & {
|
||||
};
|
||||
|
||||
export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { getPersistedOrder, setPersistedOrder } = usePersistedOrderStore(
|
||||
(store) => ({
|
||||
getPersistedOrder: store.getOrder,
|
||||
@ -158,7 +158,11 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="p-4" noValidate>
|
||||
<form
|
||||
onSubmit={isReadOnly ? () => null : handleSubmit(onSubmit)}
|
||||
className="p-4"
|
||||
noValidate
|
||||
>
|
||||
<Controller
|
||||
name="type"
|
||||
control={control}
|
||||
@ -220,13 +224,14 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
||||
/>
|
||||
)}
|
||||
<DealTicketButton
|
||||
disabled={Object.keys(errors).length >= 1}
|
||||
disabled={Object.keys(errors).length >= 1 || isReadOnly}
|
||||
variant={order.side === Schema.Side.SIDE_BUY ? 'ternary' : 'secondary'}
|
||||
/>
|
||||
<SummaryMessage
|
||||
errorMessage={errors.summary?.message}
|
||||
market={market}
|
||||
order={order}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
<DealTicketFeeDetails order={order} market={market} />
|
||||
</form>
|
||||
@ -241,9 +246,10 @@ interface SummaryMessageProps {
|
||||
errorMessage?: string;
|
||||
market: MarketDealTicket;
|
||||
order: OrderSubmissionBody['orderSubmission'];
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
const SummaryMessage = memo(
|
||||
({ errorMessage, market, order }: SummaryMessageProps) => {
|
||||
({ errorMessage, market, order, isReadOnly }: SummaryMessageProps) => {
|
||||
// Specific error UI for if balance is so we can
|
||||
// render a deposit dialog
|
||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||
@ -251,6 +257,17 @@ const SummaryMessage = memo(
|
||||
market,
|
||||
order,
|
||||
});
|
||||
if (isReadOnly) {
|
||||
return (
|
||||
<div className="mb-4">
|
||||
<InputError data-testid="dealticket-error-message-summary">
|
||||
{
|
||||
'You need to connect your own wallet to start trading on this market'
|
||||
}
|
||||
</InputError>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (errorMessage === SummaryValidationType.NoCollateral) {
|
||||
return (
|
||||
<ZeroBalanceError
|
||||
|
@ -10,7 +10,7 @@ export const OrderListContainer = ({
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
}) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
|
||||
if (!pubKey) {
|
||||
return <Splash>{t('Please connect Vega wallet')}</Splash>;
|
||||
@ -21,6 +21,7 @@ export const OrderListContainer = ({
|
||||
partyId={pubKey}
|
||||
marketId={marketId}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -13,7 +13,7 @@ const generateJsx = () => {
|
||||
return (
|
||||
<MockedProvider>
|
||||
<VegaWalletContext.Provider value={{ pubKey } as VegaWalletContextShape}>
|
||||
<OrderListManager partyId={pubKey} />
|
||||
<OrderListManager partyId={pubKey} isReadOnly={false} />
|
||||
</VegaWalletContext.Provider>
|
||||
</MockedProvider>
|
||||
);
|
||||
|
@ -31,6 +31,7 @@ export interface OrderListManagerProps {
|
||||
partyId: string;
|
||||
marketId?: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
export const TransactionComplete = ({
|
||||
@ -72,6 +73,7 @@ export const OrderListManager = ({
|
||||
partyId,
|
||||
marketId,
|
||||
onMarketClick,
|
||||
isReadOnly,
|
||||
}: OrderListManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const scrolledToTop = useRef(true);
|
||||
@ -146,6 +148,7 @@ export const OrderListManager = ({
|
||||
}}
|
||||
setEditOrder={setEditOrder}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
|
@ -19,6 +19,7 @@ const defaultProps: OrderListTableProps = {
|
||||
rowData: [],
|
||||
setEditOrder: jest.fn(),
|
||||
cancel: jest.fn(),
|
||||
isReadOnly: false,
|
||||
};
|
||||
|
||||
const generateJsx = (
|
||||
@ -156,6 +157,29 @@ describe('OrderListTable', () => {
|
||||
expect(mockCancel).toHaveBeenCalledWith(order);
|
||||
});
|
||||
|
||||
it('does not allow cancelling and editing for permitted orders if read only', async () => {
|
||||
const mockEdit = jest.fn();
|
||||
const mockCancel = jest.fn();
|
||||
const order = generateOrder({
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||
liquidityProvision: null,
|
||||
peggedOrder: null,
|
||||
});
|
||||
await act(async () => {
|
||||
render(
|
||||
generateJsx({
|
||||
rowData: [order],
|
||||
setEditOrder: mockEdit,
|
||||
cancel: mockCancel,
|
||||
isReadOnly: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
const amendCell = getAmendCell();
|
||||
expect(amendCell.queryAllByRole('button')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows if an order is a liquidity provision order and does not show order actions', async () => {
|
||||
const order = generateOrder({
|
||||
type: Schema.OrderType.TYPE_LIMIT,
|
||||
|
@ -22,6 +22,7 @@ const Template: Story = (args) => {
|
||||
setEditOrder={() => {
|
||||
return;
|
||||
}}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -48,6 +49,7 @@ const Template2: Story = (args) => {
|
||||
rowData={args.data}
|
||||
cancel={cancel}
|
||||
setEditOrder={setEditOrder}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
</div>
|
||||
<VegaTransactionDialog
|
||||
|
@ -32,6 +32,7 @@ export type OrderListTableProps = OrderListProps & {
|
||||
cancel: (order: Order) => void;
|
||||
setEditOrder: (order: Order) => void;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
};
|
||||
|
||||
export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
@ -248,7 +249,7 @@ export const OrderListTable = forwardRef<AgGridReact, OrderListTableProps>(
|
||||
minWidth={100}
|
||||
type="rightAligned"
|
||||
cellRenderer={({ data, node }: VegaICellRendererParams<Order>) => {
|
||||
return data && isOrderAmendable(data) ? (
|
||||
return data && isOrderAmendable(data) && !props.isReadOnly ? (
|
||||
<>
|
||||
<ButtonLink
|
||||
data-testid="edit"
|
||||
|
@ -8,7 +8,7 @@ export const PositionsContainer = ({
|
||||
}: {
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
}) => {
|
||||
const { pubKey } = useVegaWallet();
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
|
||||
if (!pubKey) {
|
||||
return (
|
||||
@ -17,5 +17,11 @@ export const PositionsContainer = ({
|
||||
</Splash>
|
||||
);
|
||||
}
|
||||
return <PositionsManager partyId={pubKey} onMarketClick={onMarketClick} />;
|
||||
return (
|
||||
<PositionsManager
|
||||
partyId={pubKey}
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -9,16 +9,45 @@ import { t } from '@vegaprotocol/react-helpers';
|
||||
interface PositionsManagerProps {
|
||||
partyId: string;
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
export const PositionsManager = ({
|
||||
partyId,
|
||||
onMarketClick,
|
||||
isReadOnly,
|
||||
}: PositionsManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const { data, error, loading, getRows } = usePositionsData(partyId, gridRef);
|
||||
const create = useVegaTransactionStore((store) => store.create);
|
||||
|
||||
const onClose = ({
|
||||
marketId,
|
||||
openVolume,
|
||||
}: {
|
||||
marketId: string;
|
||||
openVolume: string;
|
||||
}) =>
|
||||
create({
|
||||
batchMarketInstructions: {
|
||||
cancellations: [
|
||||
{
|
||||
marketId,
|
||||
orderId: '', // omit order id to cancel all active orders
|
||||
},
|
||||
],
|
||||
submissions: [
|
||||
{
|
||||
marketId: marketId,
|
||||
type: Schema.OrderType.TYPE_MARKET as const,
|
||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_FOK as const,
|
||||
side: openVolume.startsWith('-')
|
||||
? Schema.Side.SIDE_BUY
|
||||
: Schema.Side.SIDE_SELL,
|
||||
size: openVolume.replace('-', ''),
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<PositionsTable
|
||||
@ -26,31 +55,9 @@ export const PositionsManager = ({
|
||||
ref={gridRef}
|
||||
datasource={{ getRows }}
|
||||
onMarketClick={onMarketClick}
|
||||
onClose={({ marketId, openVolume }) =>
|
||||
create({
|
||||
batchMarketInstructions: {
|
||||
cancellations: [
|
||||
{
|
||||
marketId,
|
||||
orderId: '', // omit order id to cancel all active orders
|
||||
},
|
||||
],
|
||||
submissions: [
|
||||
{
|
||||
marketId: marketId,
|
||||
type: Schema.OrderType.TYPE_MARKET as const,
|
||||
timeInForce: Schema.OrderTimeInForce
|
||||
.TIME_IN_FORCE_FOK as const,
|
||||
side: openVolume.startsWith('-')
|
||||
? Schema.Side.SIDE_BUY
|
||||
: Schema.Side.SIDE_SELL,
|
||||
size: openVolume.replace('-', ''),
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
}
|
||||
onClose={onClose}
|
||||
noRowsOverlayComponent={() => null}
|
||||
isReadOnly={isReadOnly}
|
||||
/>
|
||||
<div className="pointer-events-none absolute inset-0">
|
||||
<AsyncRenderer
|
||||
|
@ -32,14 +32,16 @@ const singleRowData = [singleRow];
|
||||
|
||||
it('should render successfully', async () => {
|
||||
await act(async () => {
|
||||
const { baseElement } = render(<PositionsTable rowData={[]} />);
|
||||
const { baseElement } = render(
|
||||
<PositionsTable rowData={[]} isReadOnly={false} />
|
||||
);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('Render correct columns', async () => {
|
||||
it('render correct columns', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={true} />);
|
||||
});
|
||||
|
||||
const headers = screen.getAllByRole('columnheader');
|
||||
@ -64,7 +66,7 @@ it('Render correct columns', async () => {
|
||||
|
||||
it('renders market name', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
});
|
||||
expect(screen.getByText('ETH/BTC (31 july 2022)')).toBeTruthy();
|
||||
});
|
||||
@ -75,7 +77,7 @@ it('Does not fail if the market name does not match the split pattern', async ()
|
||||
Object.assign({}, singleRow, { marketName: breakingMarketName }),
|
||||
];
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={row} />);
|
||||
render(<PositionsTable rowData={row} isReadOnly={false} />);
|
||||
});
|
||||
|
||||
expect(screen.getByText(breakingMarketName)).toBeTruthy();
|
||||
@ -84,7 +86,9 @@ it('Does not fail if the market name does not match the split pattern', async ()
|
||||
it('add color and sign to amount, displays positive notional value', async () => {
|
||||
let result: RenderResult;
|
||||
await act(async () => {
|
||||
result = render(<PositionsTable rowData={singleRowData} />);
|
||||
result = render(
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
);
|
||||
});
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
|
||||
@ -94,7 +98,10 @@ it('add color and sign to amount, displays positive notional value', async () =>
|
||||
expect(cells[1].textContent).toEqual('1,230.0');
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
<PositionsTable rowData={[{ ...singleRow, openVolume: '-100' }]} />
|
||||
<PositionsTable
|
||||
rowData={[{ ...singleRow, openVolume: '-100' }]}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
@ -107,7 +114,9 @@ it('add color and sign to amount, displays positive notional value', async () =>
|
||||
it('displays mark price', async () => {
|
||||
let result: RenderResult;
|
||||
await act(async () => {
|
||||
result = render(<PositionsTable rowData={singleRowData} />);
|
||||
result = render(
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
);
|
||||
});
|
||||
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
@ -123,6 +132,7 @@ it('displays mark price', async () => {
|
||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
},
|
||||
]}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -134,14 +144,19 @@ it('displays mark price', async () => {
|
||||
it("displays properly entry, liquidation price and liquidation bar and it's intent", async () => {
|
||||
let result: RenderResult;
|
||||
await act(async () => {
|
||||
result = render(<PositionsTable rowData={singleRowData} />);
|
||||
result = render(
|
||||
<PositionsTable rowData={singleRowData} isReadOnly={false} />
|
||||
);
|
||||
});
|
||||
let cells = screen.getAllByRole('gridcell');
|
||||
const entryPrice = cells[5].firstElementChild?.firstElementChild?.textContent;
|
||||
expect(entryPrice).toEqual('13.3');
|
||||
await act(async () => {
|
||||
result.rerender(
|
||||
<PositionsTable rowData={[{ ...singleRow, lowMarginLevel: true }]} />
|
||||
<PositionsTable
|
||||
rowData={[{ ...singleRow, lowMarginLevel: true }]}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
cells = screen.getAllByRole('gridcell');
|
||||
@ -149,7 +164,7 @@ it("displays properly entry, liquidation price and liquidation bar and it's inte
|
||||
|
||||
it('displays leverage', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[7].textContent).toEqual('1.1');
|
||||
@ -157,7 +172,7 @@ it('displays leverage', async () => {
|
||||
|
||||
it('displays allocated margin', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
const cell = cells[8];
|
||||
@ -166,7 +181,7 @@ it('displays allocated margin', async () => {
|
||||
|
||||
it('displays realised and unrealised PNL', async () => {
|
||||
await act(async () => {
|
||||
render(<PositionsTable rowData={singleRowData} />);
|
||||
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
|
||||
});
|
||||
const cells = screen.getAllByRole('gridcell');
|
||||
expect(cells[9].textContent).toEqual('1.23');
|
||||
@ -181,6 +196,7 @@ it('displays close button', async () => {
|
||||
onClose={() => {
|
||||
return;
|
||||
}}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -196,6 +212,7 @@ it('do not display close button if openVolume is zero', async () => {
|
||||
onClose={() => {
|
||||
return;
|
||||
}}
|
||||
isReadOnly={false}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
@ -33,6 +33,7 @@ interface Props extends TypedDataAgGrid<Position> {
|
||||
onClose?: (data: Position) => void;
|
||||
onMarketClick?: (id: string) => void;
|
||||
style?: CSSProperties;
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
export interface AmountCellProps {
|
||||
@ -378,7 +379,7 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
|
||||
return getDateTimeFormat().format(new Date(value));
|
||||
}}
|
||||
/>
|
||||
{onClose ? (
|
||||
{onClose && !props.isReadOnly ? (
|
||||
<AgGridColumn
|
||||
type="rightAligned"
|
||||
cellRenderer={({ data }: VegaICellRendererParams<Position>) =>
|
||||
|
Loading…
Reference in New Issue
Block a user