Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9533cf564d | ||
|
|
6a1ae35a8e | ||
|
|
ba7b574a07 | ||
|
|
afd8650657 | ||
|
|
78414b4429 | ||
|
|
e0a91b3850 | ||
|
|
80f7a08765 | ||
|
|
2002a3c5c1 | ||
|
|
3e627ff849 | ||
|
|
d2854b6e90 | ||
|
|
6d130c9cfc | ||
|
|
5905e607b0 | ||
|
|
dcb37689a9 |
@@ -29,37 +29,6 @@ fragment ExplorerPartyAssetsAccounts on AccountBalance {
|
||||
}
|
||||
}
|
||||
|
||||
fragment ExplorerPartyLinks on AccountBalance {
|
||||
asset {
|
||||
name
|
||||
id
|
||||
decimals
|
||||
symbol
|
||||
source {
|
||||
__typename
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
type
|
||||
balance
|
||||
market {
|
||||
id
|
||||
decimalPlaces
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
name
|
||||
product {
|
||||
... on Future {
|
||||
quoteName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query ExplorerPartyAssets($partyId: ID!) {
|
||||
partiesConnection(id: $partyId) {
|
||||
edges {
|
||||
|
||||
@@ -64,7 +64,7 @@ export const ExplorerPartyAssetsDocument = gql`
|
||||
}
|
||||
stakingSummary {
|
||||
currentStakeAvailable
|
||||
linkings(pagination: {first: 100}) {
|
||||
linkings(pagination: {last: 100}) {
|
||||
edges {
|
||||
node {
|
||||
type
|
||||
@@ -113,4 +113,4 @@ export function useExplorerPartyAssetsLazyQuery(baseOptions?: Apollo.LazyQueryHo
|
||||
}
|
||||
export type ExplorerPartyAssetsQueryHookResult = ReturnType<typeof useExplorerPartyAssetsQuery>;
|
||||
export type ExplorerPartyAssetsLazyQueryHookResult = ReturnType<typeof useExplorerPartyAssetsLazyQuery>;
|
||||
export type ExplorerPartyAssetsQueryResult = Apollo.QueryResult<ExplorerPartyAssetsQuery, ExplorerPartyAssetsQueryVariables>;
|
||||
export type ExplorerPartyAssetsQueryResult = Apollo.QueryResult<ExplorerPartyAssetsQuery, ExplorerPartyAssetsQueryVariables>;
|
||||
@@ -42,14 +42,14 @@ export const PartyBlockStake = ({
|
||||
linkedLength && linkedLength > 0
|
||||
? p?.stakingSummary?.linkings?.edges
|
||||
?.reduce((total, e) => {
|
||||
const accumulator = new BigNumber(total)
|
||||
const diff = new BigNumber(e?.node.amount || 0)
|
||||
const accumulator = new BigNumber(total);
|
||||
const diff = new BigNumber(e?.node.amount || 0);
|
||||
if (e?.node.type === 'TYPE_LINK') {
|
||||
return accumulator.plus(diff);
|
||||
} else if (e?.node.type === 'TYPE_UNLINK') {
|
||||
return accumulator.minus(diff);
|
||||
} else {
|
||||
return accumulator
|
||||
return accumulator;
|
||||
}
|
||||
}, new BigNumber(0))
|
||||
.toString()
|
||||
|
||||
@@ -361,6 +361,34 @@ describe(
|
||||
stakingPageDisassociateAllTokens();
|
||||
});
|
||||
|
||||
it('Error message should be displayed if error returned from wallet when voting', function () {
|
||||
const errorMsg =
|
||||
'Application error: party has already submitted the maximum number of transactions of this type per epoch (3)';
|
||||
|
||||
createRawProposal();
|
||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||
getProposalFromTitle(rawProposal.rationale.title).within(() =>
|
||||
cy.getByTestId(viewProposalButton).click()
|
||||
);
|
||||
cy.intercept('POST', '/api/v2/requests', {
|
||||
jsonrpc: '2.0',
|
||||
error: {
|
||||
code: 2001,
|
||||
message: 'Application error',
|
||||
data: 'party has already submitted the maximum number of transactions of this type per epoch (3)',
|
||||
},
|
||||
id: '-PK5EGmErnjLhAmzMeclC',
|
||||
});
|
||||
cy.contains('Vote breakdown').should('be.visible', { timeout: 10000 });
|
||||
cy.getByTestId('vote-buttons').contains('for').click();
|
||||
cy.getByTestId('dialog-title').should(
|
||||
'have.text',
|
||||
'Transaction failed'
|
||||
);
|
||||
cy.getByTestId('Error').should('have.text', errorMsg);
|
||||
});
|
||||
});
|
||||
|
||||
it('Able to see successor market details with new and updated values', function () {
|
||||
cy.createMarket();
|
||||
cy.reload();
|
||||
|
||||
@@ -119,6 +119,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
});
|
||||
});
|
||||
|
||||
// 0006-NETW-001 0006-NETW-002
|
||||
it('should display network data', function () {
|
||||
cy.getByTestId('git-network-data')
|
||||
.should('contain.text', 'Reading network data from')
|
||||
@@ -130,6 +131,37 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
});
|
||||
});
|
||||
|
||||
// 0006-NETW-003 0006-NETW-008 0006-NETW-009 0006-NETW-010 0006-NETW-012 0006-NETW-013 0006-NETW-017 0006-NETW-018 0006-NETW-019 0006-NETW-020
|
||||
it('should have option to switch to different network node', function () {
|
||||
cy.getByTestId('git-network-data').within(() => {
|
||||
cy.getByTestId('link').click();
|
||||
});
|
||||
cy.getByTestId('node-row').within(() => {
|
||||
cy.getByTestId('node-url-0')
|
||||
.parent()
|
||||
.should('have.text', 'http://localhost:3008/graphql');
|
||||
cy.getByTestId('response-time-cell')
|
||||
.invoke('text')
|
||||
.should('not.be.empty')
|
||||
.and('not.eq', 'Checking');
|
||||
cy.getByTestId('block-height-cell')
|
||||
.invoke('text')
|
||||
.should('not.be.empty')
|
||||
.then((currentBlockHeight) => {
|
||||
// Check that block height updates automatically
|
||||
cy.getByTestId('block-height-cell')
|
||||
.invoke('text')
|
||||
.should('not.eq', currentBlockHeight);
|
||||
});
|
||||
cy.getByTestId('subscription-cell').should('have.text', 'Yes');
|
||||
});
|
||||
cy.getByTestId('connect').should('be.disabled');
|
||||
cy.getByTestId('node-url-custom').click();
|
||||
cy.get('input').should('exist');
|
||||
cy.getByTestId('connect').should('be.disabled');
|
||||
cy.getByTestId('icon-cross').click();
|
||||
});
|
||||
|
||||
it('should display eth data', function () {
|
||||
cy.getByTestId('git-eth-data')
|
||||
.should('contain.text', 'Reading Ethereum data from')
|
||||
@@ -138,6 +170,7 @@ context('Home Page - verify elements on page', { tags: '@smoke' }, function () {
|
||||
});
|
||||
});
|
||||
|
||||
// 0006-NETW-011
|
||||
it('should contain link for known issues on Github', function () {
|
||||
cy.getByTestId('git-info').within(() => {
|
||||
cy.contains('Known issues and feedback on')
|
||||
|
||||
@@ -183,9 +183,8 @@ export function clickOnValidatorFromList(
|
||||
cy.get(`[row-id="${validatorNumber}"]`)
|
||||
.should('be.visible')
|
||||
.first()
|
||||
.within(() => {
|
||||
cy.get(stakeValidatorListName).click();
|
||||
});
|
||||
.as('validatorOnList');
|
||||
cy.get('@validatorOnList').click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,15 @@ describe('deal ticket basics', { tags: '@smoke' }, () => {
|
||||
cy.getByTestId(toggleLimit).next('input').should('be.checked');
|
||||
cy.getByTestId(orderPriceField).should('have.value', '101');
|
||||
});
|
||||
|
||||
it('sidebar should be open after reload', () => {
|
||||
cy.mockTradingPage();
|
||||
cy.getByTestId('deal-ticket-form').should('be.visible');
|
||||
cy.getByTestId('Order').click();
|
||||
cy.getByTestId('deal-ticket-form').should('not.exist');
|
||||
cy.reload();
|
||||
cy.getByTestId('deal-ticket-form').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
||||
describe(
|
||||
|
||||
@@ -94,7 +94,11 @@ const MainGrid = memo(
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-bottom">
|
||||
<Tab id="positions" name={t('Positions')}>
|
||||
<Tab
|
||||
id="positions"
|
||||
name={t('Positions')}
|
||||
menu={<TradingViews.positions.menu />}
|
||||
>
|
||||
<TradingViews.positions.component />
|
||||
</Tab>
|
||||
<Tab
|
||||
|
||||
@@ -17,6 +17,7 @@ import type { OrderContainerProps } from '../../components/orders-container';
|
||||
import { OrdersContainer } from '../../components/orders-container';
|
||||
import { StopOrdersContainer } from '../../components/stop-orders-container';
|
||||
import { AccountsMenu } from '../../components/accounts-menu';
|
||||
import { PositionsMenu } from '../../components/positions-menu';
|
||||
|
||||
type MarketDependantView =
|
||||
| typeof CandlesChartContainer
|
||||
@@ -57,7 +58,11 @@ export const TradingViews = {
|
||||
label: 'Trades',
|
||||
component: requiresMarket(TradesContainer),
|
||||
},
|
||||
positions: { label: 'Positions', component: PositionsContainer },
|
||||
positions: {
|
||||
label: 'Positions',
|
||||
component: PositionsContainer,
|
||||
menu: PositionsMenu,
|
||||
},
|
||||
activeOrders: {
|
||||
label: 'Active',
|
||||
component: (props: OrderContainerProps) => (
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import type { DataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import { createDataGridSlice } from '../../stores/datagrid-store-slice';
|
||||
import type { StateCreator } from 'zustand';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
@@ -13,6 +14,7 @@ export const PositionsContainer = ({ allKeys }: { allKeys?: boolean }) => {
|
||||
const onMarketClick = useMarketClickHandler(true);
|
||||
const { pubKey, pubKeys, isReadOnly } = useVegaWallet();
|
||||
|
||||
const showClosed = usePositionsStore((store) => store.showClosedMarkets);
|
||||
const gridStore = usePositionsStore((store) => store.gridStore);
|
||||
const updateGridStore = usePositionsStore((store) => store.updateGridStore);
|
||||
const gridStoreCallbacks = useDataGridEvents(gridStore, updateGridStore);
|
||||
@@ -40,12 +42,35 @@ export const PositionsContainer = ({ allKeys }: { allKeys?: boolean }) => {
|
||||
onMarketClick={onMarketClick}
|
||||
isReadOnly={isReadOnly}
|
||||
gridProps={gridStoreCallbacks}
|
||||
showClosed={showClosed}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const usePositionsStore = create<DataGridSlice>()(
|
||||
persist(createDataGridSlice, {
|
||||
name: 'vega_positions_store',
|
||||
})
|
||||
type PositionsStoreSlice = {
|
||||
showClosedMarkets: boolean;
|
||||
toggleClosedMarkets: () => void;
|
||||
};
|
||||
|
||||
const createPositionStoreSlice: StateCreator<PositionsStoreSlice> = (set) => ({
|
||||
showClosedMarkets: false,
|
||||
toggleClosedMarkets: () => {
|
||||
set((curr) => {
|
||||
return {
|
||||
showClosedMarkets: !curr.showClosedMarkets,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const usePositionsStore = create<PositionsStoreSlice & DataGridSlice>()(
|
||||
persist(
|
||||
(...args) => ({
|
||||
...createPositionStoreSlice(...args),
|
||||
...createDataGridSlice(...args),
|
||||
}),
|
||||
{
|
||||
name: 'vega_positions_store',
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './positions-menu';
|
||||
@@ -0,0 +1,18 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Intent, TradingButton } from '@vegaprotocol/ui-toolkit';
|
||||
import { usePositionsStore } from '../positions-container';
|
||||
|
||||
export const PositionsMenu = () => {
|
||||
const showClosed = usePositionsStore((store) => store.showClosedMarkets);
|
||||
const toggle = usePositionsStore((store) => store.toggleClosedMarkets);
|
||||
return (
|
||||
<TradingButton
|
||||
intent={Intent.Primary}
|
||||
size="extra-small"
|
||||
data-testid="open-transfer"
|
||||
onClick={toggle}
|
||||
>
|
||||
{showClosed ? t('Hide closed markets') : t('Show closed markets')}
|
||||
</TradingButton>
|
||||
);
|
||||
};
|
||||
@@ -14,12 +14,9 @@ import { Settings } from '../settings';
|
||||
import { Tooltip } from '../../components/tooltip';
|
||||
import { WithdrawContainer } from '../withdraw-container';
|
||||
import { Routes as AppRoutes } from '../../pages/client-router';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { GetStarted } from '../welcome-dialog';
|
||||
import { useVegaWallet, useViewAsDialog } from '@vegaprotocol/wallet';
|
||||
|
||||
const STORAGE_KEY = 'vega_sidebar_store';
|
||||
|
||||
export enum ViewType {
|
||||
Order = 'Order',
|
||||
Info = 'Info',
|
||||
@@ -302,22 +299,14 @@ export const useSidebar = create<{
|
||||
init: boolean;
|
||||
view: SidebarView | null;
|
||||
setView: (view: SidebarView | null) => void;
|
||||
}>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
init: true,
|
||||
view: null,
|
||||
setView: (x) =>
|
||||
set(() => {
|
||||
if (x == null) {
|
||||
return { view: null, init: false };
|
||||
}
|
||||
|
||||
return { view: x, init: false };
|
||||
}),
|
||||
}>()((set) => ({
|
||||
init: true,
|
||||
view: null,
|
||||
setView: (x) =>
|
||||
set(() => {
|
||||
if (x == null) {
|
||||
return { view: null, init: false };
|
||||
}
|
||||
return { view: x, init: false };
|
||||
}),
|
||||
{
|
||||
name: STORAGE_KEY,
|
||||
}
|
||||
)
|
||||
);
|
||||
}));
|
||||
|
||||
@@ -1,40 +1,10 @@
|
||||
import { Html, Head, Main, NextScript } from 'next/document';
|
||||
import { Head, Html, Main, NextScript } from 'next/document';
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<>
|
||||
<Head>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charSet="utf-8" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Console" />
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:url" content="https://console.vega.xyz/" />
|
||||
<meta name="og:title" content="Vega Protocol - Console" />
|
||||
<meta name="og:site_name" content="Vega Protocol - Console" />
|
||||
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
|
||||
<meta
|
||||
name="twitter:card"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:title" content="Vega Protocol - Console" />
|
||||
<meta name="twitter:description" content="Vega Protocol - Console" />
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:image:alt" content="VEGA logo" />
|
||||
<meta name="twitter:site" content="@vegaprotocol" />
|
||||
|
||||
<meta name="description" content="Vega Protocol - Console" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
@@ -45,8 +15,6 @@ export default function Document() {
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
/>
|
||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
<link rel="stylesheet" href="/preloader.css" media="all" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
@@ -54,10 +22,12 @@ export default function Document() {
|
||||
/>
|
||||
<script src="/theme-setter.js" type="text/javascript" async />
|
||||
</Head>
|
||||
<body className="bg-white dark:bg-vega-cdark-900 text-default font-alpha">
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
<Html>
|
||||
<body className="bg-white dark:bg-vega-cdark-900 text-default font-alpha">
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import Head from 'next/head';
|
||||
import { ClientRouter } from './client-router';
|
||||
|
||||
/**
|
||||
@@ -6,5 +7,60 @@ import { ClientRouter } from './client-router';
|
||||
* have to serve a static site via next export
|
||||
*/
|
||||
export default function Index() {
|
||||
return <ClientRouter />;
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<link rel="stylesheet" href="https://static.vega.xyz/fonts.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charSet="utf-8" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="description" content="Vega Protocol - VEGA Console" />
|
||||
<meta name="og:type" content="website" />
|
||||
<meta name="og:url" content="https://console.vega.xyz/" />
|
||||
<meta name="og:title" content="Vega Protocol - Console" />
|
||||
<meta name="og:site_name" content="Vega Protocol - Console" />
|
||||
<meta name="og:image" content="https://static.vega.xyz/favicon.ico" />
|
||||
|
||||
<meta
|
||||
name="twitter:card"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:title" content="Vega Protocol - Console" />
|
||||
<meta name="twitter:description" content="Vega Protocol - Console" />
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<meta name="twitter:image:alt" content="VEGA logo" />
|
||||
<meta name="twitter:site" content="@vegaprotocol" />
|
||||
|
||||
<meta name="description" content="Vega Protocol - Console" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
content="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<link
|
||||
rel="preload"
|
||||
href="https://static.vega.xyz/AlphaLyrae-Medium.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
/>
|
||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||
<link rel="stylesheet" href="/preloader.css" media="all" />
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/x-icon"
|
||||
href="https://static.vega.xyz/favicon.ico"
|
||||
/>
|
||||
<script src="/theme-setter.js" type="text/javascript" async />
|
||||
</Head>
|
||||
<ClientRouter />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"name": "@vegaprotocol/announcements",
|
||||
"version": "0.0.2"
|
||||
"version": "0.0.2",
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,12 @@ import * as Schema from '@vegaprotocol/types';
|
||||
import type { Account } from '@vegaprotocol/accounts';
|
||||
import type { MarketWithData } from '@vegaprotocol/markets';
|
||||
import type { PositionFieldsFragment } from './__generated__/Positions';
|
||||
import { getMetrics, rejoinPositionData } from './positions-data-providers';
|
||||
import type { Position } from './positions-data-providers';
|
||||
import {
|
||||
getMetrics,
|
||||
preparePositions,
|
||||
rejoinPositionData,
|
||||
} from './positions-data-providers';
|
||||
import { PositionStatus } from '@vegaprotocol/types';
|
||||
|
||||
const accounts = [
|
||||
@@ -223,4 +228,29 @@ describe('getMetrics && rejoinPositionData', () => {
|
||||
);
|
||||
expect(metrics[1].status).toEqual(positions[1].positionStatus);
|
||||
});
|
||||
|
||||
it('sorts and filters positions', () => {
|
||||
const createPosition = (override?: Partial<Position>) =>
|
||||
({
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
marketCode: 'a',
|
||||
...override,
|
||||
} as Position);
|
||||
|
||||
const data = [
|
||||
createPosition(),
|
||||
createPosition({
|
||||
marketCode: 'c',
|
||||
marketState: Schema.MarketState.STATE_CANCELLED,
|
||||
}),
|
||||
createPosition({ marketCode: 'd' }),
|
||||
createPosition({ marketCode: 'b' }),
|
||||
];
|
||||
|
||||
const withoutClosed = preparePositions(data, false);
|
||||
expect(withoutClosed.map((p) => p.marketCode)).toEqual(['a', 'b', 'd']);
|
||||
|
||||
const withClosed = preparePositions(data, true);
|
||||
expect(withClosed.map((p) => p.marketCode)).toEqual(['a', 'b', 'c', 'd']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,6 +41,7 @@ export interface Position {
|
||||
marketId: string;
|
||||
marketCode: string;
|
||||
marketTradingMode: Schema.MarketTradingMode;
|
||||
marketState: Schema.MarketState;
|
||||
markPrice: string | undefined;
|
||||
notional: string | undefined;
|
||||
openVolume: string;
|
||||
@@ -119,6 +120,7 @@ export const getMetrics = (
|
||||
marketId: market.id,
|
||||
marketCode: market.tradableInstrument.instrument.code,
|
||||
marketTradingMode: market.tradingMode,
|
||||
marketState: market.state,
|
||||
markPrice: marketData ? marketData.markPrice : undefined,
|
||||
notional: notional
|
||||
? notional.multipliedBy(10 ** marketDecimalPlaces).toFixed(0)
|
||||
@@ -248,6 +250,26 @@ export const rejoinPositionData = (
|
||||
return null;
|
||||
};
|
||||
|
||||
export const preparePositions = (metrics: Position[], showClosed: boolean) => {
|
||||
return sortBy(metrics, 'marketCode').filter((p) => {
|
||||
if (showClosed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
[
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketState.STATE_PENDING,
|
||||
Schema.MarketState.STATE_SUSPENDED,
|
||||
].includes(p.marketState)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
export const positionsMarketsProvider = makeDerivedDataProvider<
|
||||
string[],
|
||||
never,
|
||||
@@ -265,7 +287,7 @@ export const positionsMarketsProvider = makeDerivedDataProvider<
|
||||
export const positionsMetricsProvider = makeDerivedDataProvider<
|
||||
Position[],
|
||||
Position[],
|
||||
PositionsQueryVariables & { marketIds: string[] }
|
||||
PositionsQueryVariables & { marketIds: string[]; showClosed: boolean }
|
||||
>(
|
||||
[
|
||||
(callback, client, variables) =>
|
||||
@@ -281,10 +303,10 @@ export const positionsMetricsProvider = makeDerivedDataProvider<
|
||||
marketIds: variables.marketIds,
|
||||
}),
|
||||
],
|
||||
([positions, accounts, marketsData]) => {
|
||||
([positions, accounts, marketsData], variables) => {
|
||||
const positionsData = rejoinPositionData(positions, marketsData);
|
||||
const metrics = getMetrics(positionsData, accounts as Account[] | null);
|
||||
return sortBy(metrics, 'marketCode');
|
||||
return preparePositions(metrics, variables.showClosed);
|
||||
},
|
||||
(data, delta, previousData) =>
|
||||
data.filter((row) => {
|
||||
|
||||
@@ -16,6 +16,7 @@ interface PositionsManagerProps {
|
||||
onMarketClick?: (marketId: string) => void;
|
||||
isReadOnly: boolean;
|
||||
gridProps?: ReturnType<typeof useDataGridEvents>;
|
||||
showClosed?: boolean;
|
||||
}
|
||||
|
||||
export const PositionsManager = ({
|
||||
@@ -23,6 +24,7 @@ export const PositionsManager = ({
|
||||
onMarketClick,
|
||||
isReadOnly,
|
||||
gridProps,
|
||||
showClosed = false,
|
||||
}: PositionsManagerProps) => {
|
||||
const { pubKeys, pubKey } = useVegaWallet();
|
||||
const create = useVegaTransactionStore((store) => store.create);
|
||||
@@ -60,7 +62,7 @@ export const PositionsManager = ({
|
||||
|
||||
const { data, error } = useDataProvider({
|
||||
dataProvider: positionsMetricsProvider,
|
||||
variables: { partyIds, marketIds: marketIds || [] },
|
||||
variables: { partyIds, marketIds: marketIds || [], showClosed },
|
||||
skip: !marketIds,
|
||||
});
|
||||
|
||||
@@ -68,7 +70,7 @@ export const PositionsManager = ({
|
||||
<PositionsTable
|
||||
pubKey={pubKey}
|
||||
pubKeys={pubKeys}
|
||||
rowData={error ? [] : data}
|
||||
rowData={data}
|
||||
onMarketClick={onMarketClick}
|
||||
onClose={onClose}
|
||||
isReadOnly={isReadOnly}
|
||||
|
||||
@@ -27,6 +27,7 @@ const singleRow: Position = {
|
||||
marketId: 'string',
|
||||
marketCode: 'ETHBTC.QM21',
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||
markPrice: '123',
|
||||
notional: '12300',
|
||||
openVolume: '100',
|
||||
|
||||
@@ -473,8 +473,8 @@ export const PositionsTable = ({
|
||||
</div>
|
||||
);
|
||||
},
|
||||
minWidth: 75,
|
||||
maxWidth: 75,
|
||||
minWidth: 55,
|
||||
maxWidth: 55,
|
||||
}
|
||||
: null,
|
||||
];
|
||||
|
||||
@@ -17,4 +17,17 @@ export const proposalsDataProvider = makeDataProvider<
|
||||
never,
|
||||
never,
|
||||
ProposalsListQueryVariables
|
||||
>({ query: ProposalsListDocument, getData });
|
||||
>({
|
||||
query: ProposalsListDocument,
|
||||
getData,
|
||||
/**
|
||||
* Ignores errors for not found settlement asset for NewMarket proposals.
|
||||
*
|
||||
* It can happen that a NewMarket proposal is incomplete and does not contain
|
||||
* `futureProduct` details. This guard protects against that.
|
||||
*
|
||||
* GQL Path: `terms.change.instrument.futureProduct.settlementAsset`
|
||||
*/
|
||||
errorPolicyGuard: (errors) =>
|
||||
errors.every((e) => e.message.match(/failed to get asset for ID/)),
|
||||
});
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"name": "@vegaprotocol/react-helpers",
|
||||
"version": "0.2.5"
|
||||
"version": "0.2.5",
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"name": "@vegaprotocol/types",
|
||||
"version": "0.0.4"
|
||||
"version": "0.0.5"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"name": "@vegaprotocol/ui-toolkit",
|
||||
"version": "0.12.7"
|
||||
"version": "0.12.8",
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@vegaprotocol/utils",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.8",
|
||||
"type": "commonjs"
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ for the a given Ethereum wallet/address/key:
|
||||
- **must** see how many tokens in each tranche are locked <a name="1005-VEST-025" href="#1005-VEST-025">1005-VEST-025</a>
|
||||
- **must** see how many tokens in each tranche are redeemable <a name="1005-VEST-026" href="#1005-VEST-026">1005-VEST-026</a>
|
||||
- **must** see an option to redeem from tranche <a name="1005-VEST-027" href="#1005-VEST-027">1005-VEST-027</a>
|
||||
- **must** be warned if amount that can be redeemed from that tranche is greater than the un-associated balance for that Eth key (because this will cause the redeem function to fail) <a name="1005-VEST-028" href="#1005-VEST-028">1005-VEST-028</a>
|
||||
- **should** see how many tokens I'd need to disassociate to be able to run the redeem function (this should be rounded up to avoid the transaction failing due to more tokens having unlocked since the user looked at the form)
|
||||
- **should** see link to [disassociate](1004-ASSO-associate.md)
|
||||
|
||||
|
||||
@@ -51,4 +51,8 @@
|
||||
|
||||
- **Must** be able to see if your realised PnL was affected by loss socialisation (<a name="7004-POSI-018" href="#7004-POSI-018">7004-POSI-018</a>)
|
||||
|
||||
- **Must** Must be able to see what type of product the position was opened on (<a name="7004-POSI-019" href="#7004-POSI-019">7004-POSI-019</a>)
|
||||
- **Must** be able to see what type of product the position was opened on (<a name="7004-POSI-019" href="#7004-POSI-019">7004-POSI-019</a>)
|
||||
|
||||
- **Must** not see positions on markets which are closed (<a name="7004-POSI-020" href="#7004-POSI-020">7004-POSI-020</a>)
|
||||
|
||||
- **Must** be able to show closed markets (<a name="7004-POSI-021" href="#7004-POSI-021">7004-POSI-021</a>)
|
||||
|
||||
Reference in New Issue
Block a user