Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2c3308695 |
@@ -78,7 +78,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.54.0
|
||||
ref: develop
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
|
||||
@@ -130,11 +130,9 @@ jobs:
|
||||
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
working-directory: frontend-monorepo
|
||||
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.54.0
|
||||
ref: develop
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
|
||||
@@ -114,11 +114,9 @@ jobs:
|
||||
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: yarn nx run-many --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
working-directory: frontend-monorepo
|
||||
run: yarn nx run-many --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
|
||||
|
||||
@@ -69,7 +69,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.54.0
|
||||
ref: develop
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
|
||||
@@ -130,7 +130,7 @@ jobs:
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --browser chrome
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
|
||||
@@ -6,3 +6,7 @@ yarn commitlint --edit "${1}"
|
||||
|
||||
# Lint all staged files
|
||||
yarn lint-staged
|
||||
|
||||
# Build & test affected apps
|
||||
yarn nx affected:build --uncommitted
|
||||
yarn nx affected:test --uncommitted
|
||||
|
||||
@@ -72,7 +72,7 @@ Run `nx serve my-app` for a dev server. Navigate to the port specified in `app/<
|
||||
In order to generate the schemas for your GraphQL queries, you can run `GRAPHQL_SCHEMA_PATH=[YOUR SCHEMA FILE / API URL HERE] nx run types:generate`.
|
||||
|
||||
```bash
|
||||
export GRAPHQL_SCHEMA_PATH=https://api.n11.testnet.vega.xyz/graphql
|
||||
export NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
|
||||
yarn nx run types:generate
|
||||
```
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('market selector', () => {
|
||||
connectVegaWallet();
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
markets[0].tradableInstrument.instrument.name
|
||||
markets[0].name
|
||||
);
|
||||
cy.getByTestId('arrow-button').click();
|
||||
cy.getByTestId('market-pane').should('be.visible');
|
||||
@@ -47,7 +47,7 @@ describe('market selector', () => {
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
.first()
|
||||
.should('contain.text', markets[0].tradableInstrument.instrument.name);
|
||||
.should('contain.text', markets[0].name);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
.find('[role="button"]')
|
||||
@@ -69,9 +69,7 @@ describe('market selector', () => {
|
||||
cy.get('input[placeholder="Search"]').clear();
|
||||
cy.get('input[placeholder="Search"]').type('aa');
|
||||
const filtered = markets.filter(
|
||||
(market) =>
|
||||
market.state === 'STATE_ACTIVE' &&
|
||||
market.tradableInstrument.instrument.name.match(/aa/i)
|
||||
(market) => market.state === 'STATE_ACTIVE' && market.name.match(/aa/i)
|
||||
);
|
||||
cy.getByTestId('market-pane')
|
||||
.children()
|
||||
@@ -88,7 +86,7 @@ describe('market selector', () => {
|
||||
);
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
filtered[filtered.length - 1].tradableInstrument.instrument.name
|
||||
filtered[filtered.length - 1].name
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -131,7 +129,7 @@ describe('market selector', () => {
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.get('input[placeholder="Search"]').should(
|
||||
'have.value',
|
||||
markets[0].tradableInstrument.instrument.name
|
||||
markets[0].name
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -170,50 +170,7 @@ describe('Market trade', () => {
|
||||
.find('button')
|
||||
.should('have.text', '2');
|
||||
cy.get('button').contains('Max').click();
|
||||
}
|
||||
});
|
||||
|
||||
it('slippage value should be displayed', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.02%');
|
||||
}
|
||||
});
|
||||
|
||||
it('allow slippage value to be adjusted', () => {
|
||||
if (markets?.length) {
|
||||
cy.visit(`/trading/${markets[1].id}`);
|
||||
connectVegaWallet();
|
||||
cy.get('#step-1-control [aria-label^="Selected value"]').click();
|
||||
cy.get('button[aria-label="Open short position"]').click();
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('button').contains('Max').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '0.02%');
|
||||
cy.get('#step-2-panel').find('dl').eq(2).find('button').click();
|
||||
cy.get('#input-order-slippage')
|
||||
.focus()
|
||||
.type('{backspace}{backspace}{backspace}1');
|
||||
|
||||
cy.getByTestId('slippage-dialog').find('button').click();
|
||||
|
||||
cy.get('#step-2-panel')
|
||||
.find('dl')
|
||||
.eq(2)
|
||||
.find('dd')
|
||||
.should('have.text', '1%');
|
||||
cy.getByTestId('price-slippage-value').should('have.text', '0.02%');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -238,9 +195,9 @@ describe('Market trade', () => {
|
||||
cy.get('#step-2-panel').find('dd').eq(0).find('button').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(2)
|
||||
.eq(3)
|
||||
.should('have.text', 'Est. Position Size (tDAI)');
|
||||
cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012');
|
||||
cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '197.86012');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -253,11 +210,11 @@ describe('Market trade', () => {
|
||||
cy.get('#step-2-control').click();
|
||||
cy.get('#step-2-panel')
|
||||
.find('dt')
|
||||
.eq(3)
|
||||
.eq(4)
|
||||
.should('have.text', 'Est. Fees (tDAI)');
|
||||
cy.get('#step-2-panel')
|
||||
.find('dd')
|
||||
.eq(3)
|
||||
.eq(4)
|
||||
.should('have.text', '3.00000 (3.03%)');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -75,11 +75,11 @@ const protoCandles = [
|
||||
|
||||
export const protoMarket = {
|
||||
id: 'first-btcusd-id',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
state: 'STATE_ACTIVE',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'AAVEDAI.MF21',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:2839D9B2329C9E70',
|
||||
|
||||
@@ -2,13 +2,13 @@ export const generateDealTicket = () => {
|
||||
return {
|
||||
market: {
|
||||
id: 'first-btcusd-id',
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
decimalPlaces: 5,
|
||||
positionDecimalPlaces: 0,
|
||||
state: 'STATE_ACTIVE',
|
||||
tradingMode: 'Continuous',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||
product: {
|
||||
quoteName: 'DAI',
|
||||
settlementAsset: {
|
||||
|
||||
@@ -6,11 +6,11 @@ export const generateMarketNames = () => {
|
||||
{ ...protoMarket },
|
||||
{
|
||||
id: '1d7ddf67dac4924db03f5bf58571a7bcb1908d70c66580467717aabc5345b68a',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'AAPL.MF21',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:4899E01009F1A721',
|
||||
@@ -32,11 +32,11 @@ export const generateMarketNames = () => {
|
||||
},
|
||||
{
|
||||
id: '87ae87cd3244fc1fab4b0e2dad2437879864192bb969f3109b69293421644c8b',
|
||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'TSLA.QM21',
|
||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:5A86B190C384997F',
|
||||
@@ -58,11 +58,11 @@ export const generateMarketNames = () => {
|
||||
},
|
||||
{
|
||||
id: '69205712a854f1bbfb69fa3d11b60e01a1e249bafb5ece88115e7451e8ef07b3',
|
||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
||||
state: 'STATE_SUSPENDED',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
@@ -83,11 +83,11 @@ export const generateMarketNames = () => {
|
||||
},
|
||||
{
|
||||
id: 'ethbtc-quaterly',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
state: 'STATE_ACTIVE',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'ETHBTC.QM21',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:1F0BB6EB5703B099',
|
||||
@@ -108,11 +108,11 @@ export const generateMarketNames = () => {
|
||||
},
|
||||
{
|
||||
id: '3c62b2714c4332d1a689a5352bff090e6aabccfd6bd87ce018936b38372530c9',
|
||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
||||
state: 'STATE_ACTIVE',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'UNIDAI.MF21',
|
||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:3C58ED2A4A6C5D7E',
|
||||
|
||||
@@ -6,11 +6,11 @@ export const generateSimpleMarkets = () => {
|
||||
{ ...protoMarket },
|
||||
{
|
||||
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
||||
name: 'CELUSD (June 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'CELUSD',
|
||||
name: 'CELUSD (June 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'base:CEL',
|
||||
@@ -35,11 +35,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: 'ccf2f04865e5951ac3405da6e16b7cbdb535a0ad32df4df2dbed4262cf473255',
|
||||
name: 'XMRUSD market',
|
||||
state: 'Suspended',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'XMRUSD',
|
||||
name: 'XMRUSD market',
|
||||
metadata: {
|
||||
tags: [
|
||||
'base:monero',
|
||||
@@ -64,11 +64,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '6030e5b4e0ca3297a26081e5af4d453f97f96baab2d74bf56f84efcffc4c382f',
|
||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'UNIDAI.MF21',
|
||||
name: 'UNIDAI Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:3C58ED2A4A6C5D7E',
|
||||
@@ -167,11 +167,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: 'de74a5572045b300e8ec50d136896912ec76e7d7ec135bc305dfd4854d9363a4',
|
||||
name: 'XMRUSD market',
|
||||
state: 'Pending',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'XMRUSD',
|
||||
name: 'XMRUSD market',
|
||||
metadata: {
|
||||
tags: [
|
||||
'base:monero',
|
||||
@@ -269,11 +269,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '31ea96284611771e486c820acb26a325a99664f9854b5a7e7ad99023efa8f9e6',
|
||||
name: 'ApeCoin (18 Jul 2022)',
|
||||
state: 'Closed',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'APE/USD',
|
||||
name: 'ApeCoin (18 Jul 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'quote:USD',
|
||||
@@ -297,11 +297,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '34cff959cdc2ffdb0f167820d701fe8b51cc6b8588e650d93369aaa22d6f8b74',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
state: 'Settled',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
@@ -327,11 +327,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '87b0bbb3c171baa5d97dfc3852332829c91e5c5dc9f7c8fb584c6d8ac75aaaf2',
|
||||
name: 'Builders Club x ETHcc',
|
||||
state: 'Settled',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'LTCUSD',
|
||||
name: 'Builders Club x ETHcc',
|
||||
metadata: {
|
||||
tags: [
|
||||
'base:litecoin',
|
||||
@@ -417,11 +417,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '45266143c6e9b58f4cff9b8906e971c531bb29ea7af01066973f9b77e8134823',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
state: 'Pending',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
@@ -447,11 +447,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '65663ebdc96161162769c4d5c5508137416748178d7cb28e2cb0d07a151a2bc6',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'ETHBTC.QM21',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:1F0BB6EB5703B099',
|
||||
@@ -550,11 +550,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '234afabd27e3bce1a879039c041f9f00f915d98459935ddafd0169d38dd13850',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'AAPL.MF21',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:4899E01009F1A721',
|
||||
@@ -654,11 +654,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '9f2a3c1caa67bb0773ec18d908d32b55b129b9ec2d106a8e9a87f6aa5c0375a6',
|
||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'TSLA.QM21',
|
||||
name: 'Tesla Quarterly (30 Jun 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:5A86B190C384997F',
|
||||
@@ -758,11 +758,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '8a45ee934d3ddac4b036f9884df1064a5353c620a56f775ba36597d0edef9a7a',
|
||||
name: 'Go big or Go home',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'LTCUSD',
|
||||
name: 'Go big or Go home',
|
||||
metadata: {
|
||||
tags: [
|
||||
'base:litecoin',
|
||||
@@ -801,11 +801,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: 'aede7b9ac0c3b225004929c5455160a00f59864aad32ec366e8a2bff1b30fd0f',
|
||||
name: 'BTCUSD Monthly (08 Jul 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (08 Jul 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
@@ -831,11 +831,11 @@ export const generateSimpleMarkets = () => {
|
||||
},
|
||||
{
|
||||
id: '9398707e01daa1a1f1ca6ff87cf8d6c03fe7373ce31121ce81b99a129e6bda47',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
state: 'Active',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'BTCUSD.MF21',
|
||||
name: 'BTCUSD Monthly (18 Jul 2022)',
|
||||
metadata: {
|
||||
tags: [
|
||||
'formerly:076BB86A5AA41E3E',
|
||||
@@ -866,16 +866,11 @@ export const generateSimpleMarkets = () => {
|
||||
export const generateLongListMarkets = (count: number) => {
|
||||
const markets = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const { id, name } = protoMarket;
|
||||
markets.push({
|
||||
...protoMarket,
|
||||
id: protoMarket.id + i,
|
||||
tradableInstrument: {
|
||||
...protoMarket.tradableInstrument,
|
||||
instrument: {
|
||||
...protoMarket.tradableInstrument.instrument,
|
||||
name: protoMarket.tradableInstrument.instrument.name + i,
|
||||
},
|
||||
},
|
||||
id: id + i,
|
||||
name: name + i,
|
||||
});
|
||||
}
|
||||
return { markets };
|
||||
|
||||
@@ -1,29 +1,7 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import { defaultFallbackInView } from 'react-intersection-observer';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
defaultFallbackInView(true);
|
||||
global.ResizeObserver = ResizeObserver;
|
||||
|
||||
global.DOMRect = class DOMRect {
|
||||
bottom = 0;
|
||||
left = 0;
|
||||
right = 0;
|
||||
top = 0;
|
||||
|
||||
constructor(
|
||||
public x = 0,
|
||||
public y = 0,
|
||||
public width = 0,
|
||||
public height = 0
|
||||
) {}
|
||||
static fromRect(other?: DOMRectInit): DOMRect {
|
||||
return new DOMRect(other?.x, other?.y, other?.width, other?.height);
|
||||
}
|
||||
toJSON() {
|
||||
return JSON.stringify(this);
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -4,7 +4,6 @@ import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import * as constants from './constants';
|
||||
import { TrafficLight } from '../traffic-light';
|
||||
|
||||
interface DealTicketEstimatesProps {
|
||||
quoteName?: string;
|
||||
@@ -14,7 +13,6 @@ interface DealTicketEstimatesProps {
|
||||
fees?: string;
|
||||
notionalSize?: string;
|
||||
size?: string;
|
||||
slippage?: string;
|
||||
}
|
||||
|
||||
interface DataTitleProps {
|
||||
@@ -22,7 +20,7 @@ interface DataTitleProps {
|
||||
quoteName?: string;
|
||||
}
|
||||
|
||||
export const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
|
||||
const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
|
||||
<dt>
|
||||
{children}
|
||||
{quoteName && <small> ({quoteName})</small>}
|
||||
@@ -30,20 +28,14 @@ export const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => (
|
||||
);
|
||||
|
||||
interface ValueTooltipProps {
|
||||
value?: string;
|
||||
children?: ReactNode;
|
||||
value: string;
|
||||
description: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export const ValueTooltipRow = ({
|
||||
value,
|
||||
children,
|
||||
description,
|
||||
id,
|
||||
}: ValueTooltipProps) => (
|
||||
const ValueTooltipRow = ({ value, description, id }: ValueTooltipProps) => (
|
||||
<dd className="flex gap-x-2 items-center">
|
||||
{value || children}
|
||||
{value}
|
||||
<Tooltip align="center" description={description}>
|
||||
<div className="cursor-help" id={id || ''} tabIndex={-1}>
|
||||
<Icon
|
||||
@@ -64,7 +56,6 @@ export const DealTicketEstimates = ({
|
||||
fees,
|
||||
notionalSize,
|
||||
size,
|
||||
slippage,
|
||||
}: DealTicketEstimatesProps) => (
|
||||
<dl className="text-black dark:text-white">
|
||||
{size && (
|
||||
@@ -102,7 +93,7 @@ export const DealTicketEstimates = ({
|
||||
</div>
|
||||
)}
|
||||
{estMargin && (
|
||||
<div className="flex justify-between mb-2">
|
||||
<div className="flex justify-between mb-8">
|
||||
<DataTitle quoteName={quoteName}>{t('Est. Margin')}</DataTitle>
|
||||
<ValueTooltipRow
|
||||
value={estMargin}
|
||||
@@ -111,23 +102,17 @@ export const DealTicketEstimates = ({
|
||||
</div>
|
||||
)}
|
||||
{estCloseOut && (
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle quoteName={quoteName}>{t('Est. Close out')}</DataTitle>
|
||||
<div className="flex justify-between">
|
||||
<dt>
|
||||
<span>{t('Est. Close out')}</span>
|
||||
|
||||
<small>({quoteName})</small>
|
||||
</dt>
|
||||
<ValueTooltipRow
|
||||
value={estCloseOut}
|
||||
description={constants.EST_CLOSEOUT_TOOLTIP_TEXT}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{slippage && (
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
|
||||
<ValueTooltipRow description={constants.EST_SLIPPAGE}>
|
||||
<TrafficLight value={parseFloat(slippage)} q1={1} q2={5}>
|
||||
{slippage}%
|
||||
</TrafficLight>
|
||||
</ValueTooltipRow>
|
||||
</div>
|
||||
)}
|
||||
</dl>
|
||||
);
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
SliderRoot,
|
||||
SliderThumb,
|
||||
SliderTrack,
|
||||
SliderRange,
|
||||
FormGroup,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { InputSetter } from '../input-setter';
|
||||
|
||||
interface DealTicketSizeInputProps {
|
||||
step: number;
|
||||
min: number;
|
||||
max: number;
|
||||
value: number;
|
||||
onValueChange: (value: number) => void;
|
||||
positionDecimalPlaces: number;
|
||||
}
|
||||
|
||||
const getSizeLabel = (value: number): string => {
|
||||
const MIN_LABEL = 'Min';
|
||||
const MAX_LABEL = 'Max';
|
||||
if (value === 0) {
|
||||
return MIN_LABEL;
|
||||
} else if (value === 100) {
|
||||
return MAX_LABEL;
|
||||
}
|
||||
|
||||
return `${value}%`;
|
||||
};
|
||||
|
||||
export const DealTicketSizeInput = ({
|
||||
value,
|
||||
step,
|
||||
min,
|
||||
max,
|
||||
onValueChange,
|
||||
positionDecimalPlaces,
|
||||
}: DealTicketSizeInputProps) => {
|
||||
const sizeRatios = [0, 25, 50, 75, 100];
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
|
||||
const onInputValueChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
let value = parseFloat(event.target.value);
|
||||
const isLessThanMin = value < min;
|
||||
const isMoreThanMax = value > max;
|
||||
if (isLessThanMin) {
|
||||
value = min;
|
||||
} else if (isMoreThanMax) {
|
||||
value = max;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
onValueChange(value);
|
||||
}
|
||||
|
||||
setInputValue(value);
|
||||
},
|
||||
[min, max, onValueChange, setInputValue]
|
||||
);
|
||||
|
||||
const onButtonValueChange = (size: number) => {
|
||||
const newVal = new BigNumber(size)
|
||||
.decimalPlaces(positionDecimalPlaces)
|
||||
.toNumber();
|
||||
onValueChange(newVal);
|
||||
setInputValue(newVal);
|
||||
};
|
||||
|
||||
const onSliderValueChange = useCallback(
|
||||
(value: number[]) => {
|
||||
const val = value[0];
|
||||
setInputValue(val);
|
||||
onValueChange(val);
|
||||
},
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex justify-between text-black dark:text-white mb-2">
|
||||
<span data-testid="min-label">{min}</span>
|
||||
<span data-testid="max-label">{max}</span>
|
||||
</div>
|
||||
<SliderRoot
|
||||
className="mb-2"
|
||||
value={[value]}
|
||||
onValueChange={onSliderValueChange}
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
>
|
||||
<SliderTrack className="bg-lightGrey dark:bg-offBlack">
|
||||
<SliderRange className="!bg-black dark:!bg-white" />
|
||||
</SliderTrack>
|
||||
<SliderThumb />
|
||||
</SliderRoot>
|
||||
|
||||
<div
|
||||
data-testid="percentage-selector"
|
||||
className="flex w-full justify-between text-black dark:text-white mb-6"
|
||||
>
|
||||
{sizeRatios.map((size, index) => {
|
||||
const proportionalSize = size ? (size / 100) * max : min;
|
||||
return (
|
||||
<button
|
||||
className="no-underline hover:underline text-blue"
|
||||
onClick={() => onButtonValueChange(proportionalSize)}
|
||||
type="button"
|
||||
key={index}
|
||||
>
|
||||
{getSizeLabel(size)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<dl className="text-black dark:text-white">
|
||||
<div className="flex items-center justify-between">
|
||||
<dt>{t('Contracts')}</dt>
|
||||
<dd className="flex justify-end w-full">
|
||||
<FormGroup
|
||||
hideLabel={true}
|
||||
label="Enter Size"
|
||||
labelFor="trade-size-input"
|
||||
className="mb-1"
|
||||
>
|
||||
<InputSetter
|
||||
id="input-order-size-market"
|
||||
type="number"
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
className="w-full"
|
||||
value={inputValue}
|
||||
onChange={onInputValueChange}
|
||||
>
|
||||
{inputValue}
|
||||
</InputSetter>
|
||||
</FormGroup>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,13 +1,27 @@
|
||||
import React from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
SliderRoot,
|
||||
SliderThumb,
|
||||
SliderTrack,
|
||||
SliderRange,
|
||||
FormGroup,
|
||||
Icon,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { DealTicketEstimates } from './deal-ticket-estimates';
|
||||
import { DealTicketSizeInput } from './deal-ticket-size-input';
|
||||
import { InputSetter } from '../input-setter';
|
||||
import * as constants from './constants';
|
||||
|
||||
interface DealTicketSizeProps {
|
||||
step: number;
|
||||
min: number;
|
||||
max: number;
|
||||
size: number;
|
||||
onSizeChange: (value: number) => void;
|
||||
value: number;
|
||||
onValueChange: (value: number[]) => void;
|
||||
name: string;
|
||||
quoteName: string;
|
||||
price: string;
|
||||
@@ -16,33 +30,173 @@ interface DealTicketSizeProps {
|
||||
fees: string;
|
||||
positionDecimalPlaces: number;
|
||||
notionalSize: string;
|
||||
slippage: string | null;
|
||||
}
|
||||
|
||||
const getSizeLabel = (value: number): string => {
|
||||
const MIN_LABEL = 'Min';
|
||||
const MAX_LABEL = 'Max';
|
||||
if (value === 0) {
|
||||
return MIN_LABEL;
|
||||
} else if (value === 100) {
|
||||
return MAX_LABEL;
|
||||
}
|
||||
|
||||
return `${value}%`;
|
||||
};
|
||||
|
||||
export const DealTicketSize = ({
|
||||
value,
|
||||
step,
|
||||
min,
|
||||
max,
|
||||
price,
|
||||
quoteName,
|
||||
size,
|
||||
onSizeChange,
|
||||
onValueChange,
|
||||
estCloseOut,
|
||||
positionDecimalPlaces,
|
||||
fees,
|
||||
notionalSize,
|
||||
slippage,
|
||||
}: DealTicketSizeProps) => {
|
||||
const sizeRatios = [0, 25, 50, 75, 100];
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
|
||||
const onInputValueChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = parseFloat(event.target.value);
|
||||
const isLessThanMin = value < min;
|
||||
const isMoreThanMax = value > max;
|
||||
if (value) {
|
||||
if (isLessThanMin) {
|
||||
onValueChange([min]);
|
||||
} else if (isMoreThanMax) {
|
||||
onValueChange([max]);
|
||||
} else {
|
||||
onValueChange([value]);
|
||||
}
|
||||
}
|
||||
setInputValue(value);
|
||||
},
|
||||
[min, max, onValueChange, setInputValue]
|
||||
);
|
||||
|
||||
const onButtonValueChange = useCallback(
|
||||
(size: number) => {
|
||||
const newVal = new BigNumber(size)
|
||||
.decimalPlaces(positionDecimalPlaces)
|
||||
.toNumber();
|
||||
onValueChange([newVal]);
|
||||
setInputValue(newVal);
|
||||
},
|
||||
[onValueChange, positionDecimalPlaces]
|
||||
);
|
||||
|
||||
const onSliderValueChange = useCallback(
|
||||
(value: number[]) => {
|
||||
setInputValue(value[0]);
|
||||
onValueChange(value);
|
||||
},
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
return max === 0 ? (
|
||||
<p>Not enough balance to trade</p>
|
||||
) : (
|
||||
<div>
|
||||
<DealTicketSizeInput
|
||||
<div className="flex justify-between text-black dark:text-white mb-2">
|
||||
<span data-testid="min-label">{min}</span>
|
||||
<span data-testid="max-label">{max}</span>
|
||||
</div>
|
||||
<SliderRoot
|
||||
className="mb-2"
|
||||
value={[value]}
|
||||
onValueChange={onSliderValueChange}
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
value={size}
|
||||
onValueChange={onSizeChange}
|
||||
positionDecimalPlaces={positionDecimalPlaces}
|
||||
/>
|
||||
>
|
||||
<SliderTrack className="bg-lightGrey dark:bg-offBlack">
|
||||
<SliderRange className="!bg-black dark:!bg-white" />
|
||||
</SliderTrack>
|
||||
<SliderThumb />
|
||||
</SliderRoot>
|
||||
|
||||
<div
|
||||
data-testid="percentage-selector"
|
||||
className="flex w-full justify-between text-black dark:text-white mb-6"
|
||||
>
|
||||
{sizeRatios.map((size, index) => {
|
||||
const proportionalSize = size ? (size / 100) * max : min;
|
||||
return (
|
||||
<button
|
||||
className="no-underline hover:underline text-blue"
|
||||
onClick={() => onButtonValueChange(proportionalSize)}
|
||||
type="button"
|
||||
key={index}
|
||||
>
|
||||
{getSizeLabel(size)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<dl className="text-black dark:text-white">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<dt>{t('Contracts')}</dt>
|
||||
<dd className="flex justify-end w-full">
|
||||
<FormGroup
|
||||
hideLabel={true}
|
||||
label="Enter Size"
|
||||
labelFor="trade-size-input"
|
||||
>
|
||||
<InputSetter
|
||||
id="input-order-size-market"
|
||||
type="number"
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
className="w-full"
|
||||
value={inputValue}
|
||||
onChange={onInputValueChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
{slippage && (
|
||||
<dl className="text-black dark:text-white">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<dt>{t('Est. Price Impact / Slippage')}</dt>
|
||||
<dd
|
||||
className="flex justify-end gap-x-5"
|
||||
data-testid="price-slippage-value"
|
||||
aria-label={t('Est. Price Impact / Slippage')}
|
||||
>
|
||||
<span
|
||||
className={classNames({
|
||||
'text-darkerGreen dark:text-lightGreen':
|
||||
parseFloat(slippage) < 1,
|
||||
'text-amber':
|
||||
parseFloat(slippage) >= 1 && parseFloat(slippage) < 5,
|
||||
'text-vega-red': parseFloat(slippage) >= 5,
|
||||
})}
|
||||
>
|
||||
{slippage}%
|
||||
</span>
|
||||
<Tooltip align="center" description={constants.EST_SLIPPAGE}>
|
||||
<div className="cursor-help" tabIndex={-1}>
|
||||
<Icon
|
||||
name={IconNames.ISSUE}
|
||||
className="block rotate-180"
|
||||
ariaLabel={constants.EST_SLIPPAGE}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
)}
|
||||
<DealTicketEstimates
|
||||
quoteName={quoteName}
|
||||
fees={fees}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import * as constants from './constants';
|
||||
import { TrafficLight } from '../traffic-light';
|
||||
import { Dialog, Icon, Intent, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { InputSetter } from '../../components/input-setter';
|
||||
import { IconNames } from '@blueprintjs/icons';
|
||||
import { DataTitle, ValueTooltipRow } from './deal-ticket-estimates';
|
||||
|
||||
interface DealTicketSlippageProps {
|
||||
step?: number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
value: number;
|
||||
onValueChange(value: number): void;
|
||||
}
|
||||
|
||||
export const DealTicketSlippage = ({
|
||||
value,
|
||||
step = 0.01,
|
||||
min = 0,
|
||||
max = 50,
|
||||
onValueChange,
|
||||
}: DealTicketSlippageProps) => {
|
||||
const [isDialogVisible, setIsDialogVisible] = useState(false);
|
||||
|
||||
const onChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = event.target.value;
|
||||
const numericValue = parseFloat(value);
|
||||
onValueChange(numericValue);
|
||||
},
|
||||
[onValueChange]
|
||||
);
|
||||
|
||||
const toggleDialog = useCallback(() => {
|
||||
setIsDialogVisible(!isDialogVisible);
|
||||
}, [isDialogVisible]);
|
||||
|
||||
const formLabel = (
|
||||
<label className="flex items-center mb-1">
|
||||
<span className="mr-1">{t('Adjust slippage tolerance')}</span>
|
||||
<Tooltip align="center" description={constants.EST_SLIPPAGE}>
|
||||
<div className="cursor-help" tabIndex={-1}>
|
||||
<Icon
|
||||
name={IconNames.ISSUE}
|
||||
className="block rotate-180"
|
||||
ariaLabel={constants.EST_SLIPPAGE}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
</label>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dialog
|
||||
open={isDialogVisible}
|
||||
onChange={toggleDialog}
|
||||
intent={Intent.None}
|
||||
title={t('Transaction Settings')}
|
||||
>
|
||||
<div data-testid="slippage-dialog">
|
||||
{formLabel}
|
||||
<InputSetter
|
||||
id="input-order-slippage"
|
||||
isInputVisible
|
||||
hasError={!value}
|
||||
type="number"
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
className="w-full"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
>
|
||||
{value}%
|
||||
</InputSetter>
|
||||
</div>
|
||||
</Dialog>
|
||||
<dl className="text-black dark:text-white">
|
||||
<div className="flex justify-between mb-2">
|
||||
<DataTitle>{t('Est. Price Impact / Slippage')}</DataTitle>
|
||||
<div className="flex">
|
||||
<div className="mr-1">
|
||||
<ValueTooltipRow description={constants.EST_SLIPPAGE}>
|
||||
<TrafficLight value={value} q1={1} q2={5}>
|
||||
{value}%
|
||||
</TrafficLight>
|
||||
</ValueTooltipRow>
|
||||
</div>
|
||||
<button type="button" onClick={toggleDialog}>
|
||||
<Icon
|
||||
name={IconNames.COG}
|
||||
className="block rotate-180"
|
||||
ariaLabel={t('Override slippage value')}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { Stepper } from '../stepper';
|
||||
@@ -10,7 +10,7 @@ import type { Order } from '@vegaprotocol/orders';
|
||||
import { useVegaWallet, VegaTxStatus } from '@vegaprotocol/wallet';
|
||||
import {
|
||||
t,
|
||||
addDecimalsFormatNumber,
|
||||
addDecimal,
|
||||
toDecimal,
|
||||
removeDecimal,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
@@ -33,8 +33,6 @@ import useOrderCloseOut from '../../hooks/use-order-closeout';
|
||||
import useOrderMargin from '../../hooks/use-order-margin';
|
||||
import useMaximumPositionSize from '../../hooks/use-maximum-position-size';
|
||||
import useCalculateSlippage from '../../hooks/use-calculate-slippage';
|
||||
import { Side, OrderType } from '@vegaprotocol/types';
|
||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
market: DealTicketQuery_market;
|
||||
@@ -64,26 +62,28 @@ export const DealTicketSteps = ({
|
||||
defaultValues: getDefaultOrder(market),
|
||||
});
|
||||
|
||||
const emptyString = ' - ';
|
||||
const [max, setMax] = useState<number | null>(null);
|
||||
const step = toDecimal(market.positionDecimalPlaces);
|
||||
const orderType = watch('type');
|
||||
const orderTimeInForce = watch('timeInForce');
|
||||
const orderSide = watch('side');
|
||||
const orderSize = watch('size');
|
||||
const order = watch();
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
market,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
fieldErrors: errors,
|
||||
});
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
const estCloseOut = useOrderCloseOut({ order, market, partyData });
|
||||
const { keypair } = useVegaWallet();
|
||||
const estMargin = useOrderMargin({
|
||||
order,
|
||||
market,
|
||||
partyId: keypair?.pub || '',
|
||||
});
|
||||
const value = new BigNumber(orderSize).toNumber();
|
||||
const price =
|
||||
market.depth.lastTrade &&
|
||||
addDecimal(market.depth.lastTrade.price, market.decimalPlaces);
|
||||
const emptyString = ' - ';
|
||||
|
||||
const [notionalSize, setNotionalSize] = useState<string | null>(null);
|
||||
const [fees, setFees] = useState<string | null>(null);
|
||||
|
||||
const maxTrade = useMaximumPositionSize({
|
||||
partyId: keypair?.pub || '',
|
||||
@@ -94,48 +94,45 @@ export const DealTicketSteps = ({
|
||||
price: market?.depth?.lastTrade?.price,
|
||||
order,
|
||||
});
|
||||
|
||||
const estCloseOut = useOrderCloseOut({ order, market, partyData });
|
||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
||||
const [slippageValue, setSlippageValue] = useState(
|
||||
slippage ? parseFloat(slippage) : 0
|
||||
);
|
||||
const transactionStatus =
|
||||
transaction.status === VegaTxStatus.Requested ||
|
||||
transaction.status === VegaTxStatus.Pending
|
||||
? 'pending'
|
||||
: 'default';
|
||||
useEffect(() => {
|
||||
setMax(
|
||||
new BigNumber(maxTrade)
|
||||
.decimalPlaces(market.positionDecimalPlaces)
|
||||
.toNumber()
|
||||
);
|
||||
}, [maxTrade, market.positionDecimalPlaces]);
|
||||
|
||||
const { message: invalidText, isDisabled } = useOrderValidation({
|
||||
market,
|
||||
orderType,
|
||||
orderTimeInForce,
|
||||
fieldErrors: errors,
|
||||
});
|
||||
|
||||
const { submit, transaction, finalizedOrder, Dialog } = useOrderSubmit();
|
||||
|
||||
const onSizeChange = (value: number[]) => {
|
||||
const newVal = new BigNumber(value[0])
|
||||
.decimalPlaces(market.positionDecimalPlaces)
|
||||
.toString();
|
||||
const isValid = validateSize(step)(newVal);
|
||||
if (isValid !== 'step') {
|
||||
setValue('size', newVal);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setSlippageValue(slippage ? parseFloat(slippage) : 0);
|
||||
}, [slippage]);
|
||||
|
||||
const price = useMemo(() => {
|
||||
if (slippage && market?.depth?.lastTrade?.price) {
|
||||
const isLong = order.side === Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
parseFloat(slippage) / 100
|
||||
);
|
||||
return new BigNumber(market?.depth?.lastTrade?.price)
|
||||
.multipliedBy(multiplier)
|
||||
if (market?.depth?.lastTrade?.price) {
|
||||
const size = new BigNumber(market.depth.lastTrade.price)
|
||||
.multipliedBy(value)
|
||||
.toNumber();
|
||||
|
||||
setNotionalSize(addDecimal(size, market.decimalPlaces));
|
||||
}
|
||||
return null;
|
||||
}, [market?.depth?.lastTrade?.price, order.side, slippage]);
|
||||
}, [market, value]);
|
||||
|
||||
const formattedPrice =
|
||||
price && addDecimalsFormatNumber(price, market.decimalPlaces);
|
||||
|
||||
const notionalSize = useMemo(() => {
|
||||
if (price) {
|
||||
const size = new BigNumber(price).multipliedBy(orderSize).toNumber();
|
||||
|
||||
return addDecimalsFormatNumber(size, market.decimalPlaces);
|
||||
}
|
||||
return null;
|
||||
}, [market.decimalPlaces, orderSize, price]);
|
||||
|
||||
const fees = useMemo(() => {
|
||||
useEffect(() => {
|
||||
if (estMargin?.fees && notionalSize) {
|
||||
const percentage = new BigNumber(estMargin?.fees)
|
||||
.dividedBy(notionalSize)
|
||||
@@ -143,66 +140,17 @@ export const DealTicketSteps = ({
|
||||
.decimalPlaces(2)
|
||||
.toString();
|
||||
|
||||
return `${estMargin.fees} (${percentage}%)`;
|
||||
setFees(`${estMargin.fees} (${percentage}%)`);
|
||||
}
|
||||
}, [estMargin, notionalSize]);
|
||||
|
||||
return null;
|
||||
}, [estMargin?.fees, notionalSize]);
|
||||
const transactionStatus =
|
||||
transaction.status === VegaTxStatus.Requested ||
|
||||
transaction.status === VegaTxStatus.Pending
|
||||
? 'pending'
|
||||
: 'default';
|
||||
|
||||
const max = useMemo(() => {
|
||||
return new BigNumber(maxTrade)
|
||||
.decimalPlaces(market.positionDecimalPlaces)
|
||||
.toNumber();
|
||||
}, [market.positionDecimalPlaces, maxTrade]);
|
||||
|
||||
const onSizeChange = useCallback(
|
||||
(value: number) => {
|
||||
const newVal = new BigNumber(value)
|
||||
.decimalPlaces(market.positionDecimalPlaces)
|
||||
.toString();
|
||||
const isValid = validateSize(step)(newVal);
|
||||
if (isValid !== 'step') {
|
||||
setValue('size', newVal);
|
||||
}
|
||||
},
|
||||
[market.positionDecimalPlaces, setValue, step]
|
||||
);
|
||||
|
||||
const onSlippageChange = useCallback(
|
||||
(value: number) => {
|
||||
if (market?.depth?.lastTrade?.price) {
|
||||
if (value) {
|
||||
const isLong = order.side === Side.SIDE_BUY;
|
||||
const multiplier = new BigNumber(1)[isLong ? 'plus' : 'minus'](
|
||||
value / 100
|
||||
);
|
||||
const bestAskPrice = new BigNumber(market?.depth?.lastTrade?.price)
|
||||
.multipliedBy(multiplier)
|
||||
.decimalPlaces(market.decimalPlaces)
|
||||
.toString();
|
||||
|
||||
setValue('price', bestAskPrice);
|
||||
|
||||
if (orderType === OrderType.TYPE_MARKET) {
|
||||
setValue('type', OrderType.TYPE_LIMIT);
|
||||
}
|
||||
} else {
|
||||
setValue('type', OrderType.TYPE_MARKET);
|
||||
setValue('price', market?.depth?.lastTrade?.price);
|
||||
}
|
||||
}
|
||||
setSlippageValue(value);
|
||||
},
|
||||
[
|
||||
market.decimalPlaces,
|
||||
market?.depth?.lastTrade?.price,
|
||||
order.side,
|
||||
orderType,
|
||||
setValue,
|
||||
]
|
||||
);
|
||||
|
||||
const onSubmit = useCallback(
|
||||
const onSubmit = React.useCallback(
|
||||
(order: Order) => {
|
||||
if (transactionStatus !== 'pending') {
|
||||
submit({
|
||||
@@ -231,7 +179,7 @@ export const DealTicketSteps = ({
|
||||
ItemRenderer={MarketNameRenderer}
|
||||
/>
|
||||
),
|
||||
value: market.tradableInstrument.instrument.name,
|
||||
value: market.name,
|
||||
},
|
||||
{
|
||||
label: t('Select Direction'),
|
||||
@@ -250,30 +198,25 @@ export const DealTicketSteps = ({
|
||||
label: t('Choose Position Size'),
|
||||
component:
|
||||
max !== null ? (
|
||||
<>
|
||||
<DealTicketSize
|
||||
step={step}
|
||||
min={step}
|
||||
max={max}
|
||||
onSizeChange={onSizeChange}
|
||||
size={new BigNumber(orderSize).toNumber()}
|
||||
name="size"
|
||||
price={formattedPrice || emptyString}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
quoteName={
|
||||
market.tradableInstrument.instrument.product.settlementAsset
|
||||
.symbol
|
||||
}
|
||||
notionalSize={notionalSize || emptyString}
|
||||
estCloseOut={estCloseOut}
|
||||
fees={fees || emptyString}
|
||||
estMargin={estMargin?.margin || emptyString}
|
||||
/>
|
||||
<DealTicketSlippage
|
||||
value={slippageValue}
|
||||
onValueChange={onSlippageChange}
|
||||
/>
|
||||
</>
|
||||
<DealTicketSize
|
||||
step={step}
|
||||
min={step}
|
||||
max={max}
|
||||
onValueChange={onSizeChange}
|
||||
value={new BigNumber(orderSize).toNumber()}
|
||||
name="size"
|
||||
price={price || emptyString}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
quoteName={
|
||||
market.tradableInstrument.instrument.product.settlementAsset
|
||||
.symbol
|
||||
}
|
||||
notionalSize={notionalSize || emptyString}
|
||||
estCloseOut={estCloseOut}
|
||||
fees={fees || emptyString}
|
||||
estMargin={estMargin?.margin || emptyString}
|
||||
slippage={slippage}
|
||||
/>
|
||||
) : (
|
||||
'loading...'
|
||||
),
|
||||
@@ -297,14 +240,13 @@ export const DealTicketSteps = ({
|
||||
order={order}
|
||||
estCloseOut={estCloseOut}
|
||||
estMargin={estMargin?.margin || emptyString}
|
||||
price={formattedPrice || emptyString}
|
||||
price={price || emptyString}
|
||||
quoteName={
|
||||
market.tradableInstrument.instrument.product.settlementAsset
|
||||
.symbol
|
||||
}
|
||||
notionalSize={notionalSize || emptyString}
|
||||
fees={fees || emptyString}
|
||||
slippage={slippageValue}
|
||||
/>
|
||||
<Dialog
|
||||
title={getOrderDialogTitle(finalizedOrder?.status)}
|
||||
|
||||
@@ -43,7 +43,6 @@ interface Props {
|
||||
price: string;
|
||||
fees: string;
|
||||
notionalSize: string;
|
||||
slippage: number;
|
||||
}
|
||||
|
||||
export default ({
|
||||
@@ -56,7 +55,6 @@ export default ({
|
||||
fees,
|
||||
price,
|
||||
notionalSize,
|
||||
slippage,
|
||||
}: Props) => {
|
||||
const { data: tagsData } = useQuery<MarketTags, MarketTagsVariables>(
|
||||
MARKET_TAGS_QUERY,
|
||||
@@ -107,7 +105,6 @@ export default ({
|
||||
fees={fees}
|
||||
estCloseOut={estCloseOut}
|
||||
notionalSize={notionalSize}
|
||||
slippage={slippage.toString()}
|
||||
/>
|
||||
|
||||
<div className="mt-12 max-w-sm">
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { AssetStatus } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: Deposits
|
||||
// ====================================================
|
||||
@@ -41,10 +39,6 @@ export interface Deposits_assetsConnection_edges_node {
|
||||
* The precision of the asset. Should match the decimal precision of the asset on its native chain, e.g: for ERC20 assets, it is often 18
|
||||
*/
|
||||
decimals: number;
|
||||
/**
|
||||
* The status of the asset in the Vega network
|
||||
*/
|
||||
status: AssetStatus;
|
||||
/**
|
||||
* The origin source of the asset (e.g: an ERC20 asset)
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { DepositManager } from '@vegaprotocol/deposits';
|
||||
import { getEnabledAssets, t } from '@vegaprotocol/react-helpers';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { Web3Container } from '@vegaprotocol/web3';
|
||||
import { assetsConnectionToAssets } from '@vegaprotocol/react-helpers';
|
||||
import type { Deposits } from './__generated__/Deposits';
|
||||
|
||||
const DEPOSITS_QUERY = gql`
|
||||
@@ -16,7 +17,6 @@ const DEPOSITS_QUERY = gql`
|
||||
name
|
||||
symbol
|
||||
decimals
|
||||
status
|
||||
source {
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
@@ -40,7 +40,7 @@ export const DepositContainer = () => {
|
||||
skip: !keypair?.pub,
|
||||
});
|
||||
|
||||
const assets = getEnabledAssets(data);
|
||||
const assets = assetsConnectionToAssets(data?.assetsConnection);
|
||||
|
||||
return (
|
||||
<AsyncRenderer<Deposits> data={data} loading={loading} error={error}>
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { Input } from '@vegaprotocol/ui-toolkit';
|
||||
import type { InputProps } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
interface InputSetterProps {
|
||||
buttonLabel?: string;
|
||||
value: string | number;
|
||||
isInputVisible?: boolean;
|
||||
children?: ReactNode;
|
||||
onValueChange?: () => string;
|
||||
}
|
||||
|
||||
export const InputSetter = ({
|
||||
buttonLabel = t('set'),
|
||||
value = '',
|
||||
isInputVisible = false,
|
||||
children,
|
||||
onValueChange,
|
||||
...props
|
||||
}: InputSetterProps & InputProps) => {
|
||||
const [isInputToggled, setIsInputToggled] = useState(isInputVisible);
|
||||
@@ -34,7 +35,7 @@ export const InputSetter = ({
|
||||
|
||||
return isInputToggled ? (
|
||||
<div className="flex items-center">
|
||||
<Input {...props} onKeyDown={onInputEnter} />
|
||||
<Input {...props} value={value} onKeyDown={onInputEnter} />
|
||||
<button
|
||||
type="button"
|
||||
className="no-underline hover:underline text-blue ml-2"
|
||||
@@ -46,10 +47,10 @@ export const InputSetter = ({
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="no-underline hover:underline text-blue py-1.5"
|
||||
className="no-underline hover:underline text-blue"
|
||||
onClick={toggleInput}
|
||||
>
|
||||
{children || props.value}
|
||||
{value}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ interface TabBarProps {
|
||||
export const TabBar = ({ className }: TabBarProps) => (
|
||||
<div role="group" aria-label="Tab Bar Navigation Menu" className={className}>
|
||||
<div role="presentation" className="py-[42px]" />
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-600">
|
||||
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-700">
|
||||
<Nav tabs className="flex justify-evenly items-center" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+4
-4
@@ -43,10 +43,6 @@ export interface SimpleMarkets_markets_tradableInstrument_instrument {
|
||||
* A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string)
|
||||
*/
|
||||
code: string;
|
||||
/**
|
||||
* Full and fairly descriptive name for the instrument
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Metadata for this instrument
|
||||
*/
|
||||
@@ -83,6 +79,10 @@ export interface SimpleMarkets_markets {
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Market full name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Current state of the market
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -14,11 +14,11 @@ export const MARKETS_QUERY = gql`
|
||||
query SimpleMarkets($CandleSince: String!) {
|
||||
markets {
|
||||
id
|
||||
name
|
||||
state
|
||||
tradableInstrument {
|
||||
instrument {
|
||||
code
|
||||
name
|
||||
metadata {
|
||||
tags
|
||||
}
|
||||
|
||||
+71
-161
@@ -6,19 +6,17 @@ import {
|
||||
waitFor,
|
||||
cleanup,
|
||||
getAllByRole,
|
||||
fireEvent,
|
||||
} from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import type { MockedResponse } from '@apollo/client/testing';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import SimpleMarketList from './simple-market-list';
|
||||
import { MARKETS_QUERY } from './data-provider';
|
||||
import type {
|
||||
SimpleMarkets_markets,
|
||||
SimpleMarkets,
|
||||
} from './__generated__/SimpleMarkets';
|
||||
import type { SimpleMarketDataSub_marketData } from './__generated__/SimpleMarketDataSub';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
|
||||
const mockedNavigate = jest.fn();
|
||||
|
||||
@@ -32,85 +30,85 @@ jest.mock('date-fns', () => ({
|
||||
subDays: () => new Date('2022-06-02T11:11:21.721Z'),
|
||||
}));
|
||||
|
||||
let updateMock: ({
|
||||
delta,
|
||||
}: {
|
||||
delta: SimpleMarketDataSub_marketData;
|
||||
}) => boolean;
|
||||
|
||||
let mockData = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Market 1',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
symbol: 'tUSD',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Market 2',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
symbol: 'ETH',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
] as unknown as SimpleMarkets_markets[];
|
||||
|
||||
const mockUseDataProvider = ({ update }: { update: () => boolean }) => {
|
||||
updateMock = update;
|
||||
return { data: mockData, loading: false, error: false };
|
||||
};
|
||||
|
||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||
useDataProvider: jest.fn((args) => mockUseDataProvider(args)),
|
||||
}));
|
||||
|
||||
const mockIsTradable = jest.fn((_arg) => true);
|
||||
|
||||
jest.mock('../../constants', () => ({
|
||||
...jest.requireActual('../../constants'),
|
||||
IS_MARKET_TRADABLE: jest.fn((arg) => mockIsTradable(arg)),
|
||||
}));
|
||||
|
||||
describe('SimpleMarketList', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
cleanup();
|
||||
});
|
||||
|
||||
const mocks: MockedResponse<SimpleMarkets> = {
|
||||
request: {
|
||||
query: MARKETS_QUERY,
|
||||
variables: {
|
||||
CandleSince: '2022-06-02T11:11:21.721Z',
|
||||
it('should be properly renderer as empty', async () => {
|
||||
const mocks: MockedResponse<SimpleMarkets> = {
|
||||
request: {
|
||||
query: MARKETS_QUERY,
|
||||
variables: {
|
||||
CandleSince: '2022-06-02T11:11:21.721Z',
|
||||
},
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: { markets: mockData },
|
||||
},
|
||||
};
|
||||
result: {
|
||||
data: { markets: [] },
|
||||
},
|
||||
};
|
||||
await act(async () => {
|
||||
render(
|
||||
<MockedProvider mocks={[mocks]}>
|
||||
<SimpleMarketList />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('No data to display')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('should be properly rendered with some data', async () => {
|
||||
const data = [
|
||||
{
|
||||
id: '1',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
symbol: 'tUSD',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
symbol: 'ETH',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
] as unknown as SimpleMarkets_markets[];
|
||||
|
||||
const mocks: MockedResponse<SimpleMarkets> = {
|
||||
request: {
|
||||
query: MARKETS_QUERY,
|
||||
variables: {
|
||||
CandleSince: '2022-06-02T11:11:21.721Z',
|
||||
},
|
||||
},
|
||||
result: {
|
||||
data: { markets: data },
|
||||
},
|
||||
};
|
||||
await act(async () => {
|
||||
render(
|
||||
<MockedProvider mocks={[mocks]}>
|
||||
@@ -130,92 +128,4 @@ describe('SimpleMarketList', () => {
|
||||
expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('update should return proper boolean value', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<MockedProvider mocks={[mocks]}>
|
||||
<SimpleMarketList />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
document.querySelector('.ag-center-cols-container')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await expect(
|
||||
updateMock({
|
||||
delta: {
|
||||
__typename: 'MarketData',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '2',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toEqual(true);
|
||||
|
||||
await expect(
|
||||
updateMock({
|
||||
delta: {
|
||||
__typename: 'MarketData',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '2',
|
||||
state: MarketState.STATE_SUSPENDED,
|
||||
},
|
||||
},
|
||||
})
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('click on row should be properly handled', async () => {
|
||||
await act(async () => {
|
||||
render(
|
||||
<MockedProvider mocks={[mocks]}>
|
||||
<SimpleMarketList />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
document.querySelector('.ag-center-cols-container')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
mockIsTradable.mockClear();
|
||||
const container = document.querySelector('.ag-center-cols-container');
|
||||
const firstRow = getAllByRole(container as HTMLDivElement, 'row')[0];
|
||||
expect(firstRow).toHaveAttribute('row-id', '1');
|
||||
fireEvent.click(firstRow);
|
||||
await waitFor(() => {
|
||||
expect(mockIsTradable).toHaveBeenCalledWith({
|
||||
...mockData[0],
|
||||
percentChange: '-',
|
||||
});
|
||||
expect(mockedNavigate).toHaveBeenCalledWith(`/trading/${mockData[0].id}`);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be properly renderer as empty', async () => {
|
||||
mockData = [];
|
||||
await act(async () => {
|
||||
render(
|
||||
<MockedProvider mocks={[mocks]}>
|
||||
<SimpleMarketList />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('No data to display')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import type { MarketNames_markets } from '@vegaprotocol/deal-ticket';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import MarketNameRenderer from './simple-market-renderer';
|
||||
|
||||
describe('SimpleMarketRenderer', () => {
|
||||
const market = {
|
||||
id: 'marketId',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'Market code',
|
||||
name: 'Market Name',
|
||||
product: {
|
||||
quoteName: 'Quote name',
|
||||
},
|
||||
metadata: {
|
||||
tags: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as MarketNames_markets;
|
||||
|
||||
it('should properly render not mobile', () => {
|
||||
render(<MarketNameRenderer market={market} isMobile={false} />);
|
||||
expect(screen.getByText('Market Name')).toBeInTheDocument();
|
||||
expect(screen.getByText('Quote name')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should properly render mobile', () => {
|
||||
render(<MarketNameRenderer market={market} isMobile={true} />);
|
||||
expect(screen.getByText('Market code')).toBeInTheDocument();
|
||||
expect(screen.getByText('Quote name')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -17,9 +17,7 @@ const MarketNameRenderer = ({ market, isMobile }: Props) => {
|
||||
)}
|
||||
/>
|
||||
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-ui-small md:text-market self-end">
|
||||
{isMobile
|
||||
? market.tradableInstrument.instrument.code
|
||||
: market.tradableInstrument.instrument.name}{' '}
|
||||
{isMobile ? market.tradableInstrument.instrument.code : market.name}{' '}
|
||||
<SimpleMarketExpires
|
||||
tags={market.tradableInstrument.instrument.metadata.tags}
|
||||
/>
|
||||
|
||||
+11
-108
@@ -1,35 +1,11 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
useLocation,
|
||||
useRoutes,
|
||||
BrowserRouter,
|
||||
useParams,
|
||||
} from 'react-router-dom';
|
||||
import {
|
||||
render,
|
||||
screen,
|
||||
fireEvent,
|
||||
waitFor,
|
||||
act,
|
||||
getAllByText,
|
||||
} from '@testing-library/react';
|
||||
import { useLocation, useRoutes, BrowserRouter } from 'react-router-dom';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/react-testing';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import SimpleMarketToolbar from './simple-market-toolbar';
|
||||
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
||||
import { markets as filterData } from './mocks/market-filters.json';
|
||||
|
||||
const mockedNavigate = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => {
|
||||
const actualRouter = jest.requireActual('react-router-dom');
|
||||
return {
|
||||
...actualRouter,
|
||||
useNavigate: () => mockedNavigate,
|
||||
useParams: jest.fn(() => actualRouter.useParams()),
|
||||
};
|
||||
});
|
||||
|
||||
describe('SimpleMarketToolbar', () => {
|
||||
const WrappedCompForTest = () => {
|
||||
const routes = useRoutes([
|
||||
@@ -84,8 +60,9 @@ describe('SimpleMarketToolbar', () => {
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should be properly rendered', async () => {
|
||||
@@ -106,7 +83,7 @@ describe('SimpleMarketToolbar', () => {
|
||||
expect(screen.getByTestId('market-assets-menu').children).toHaveLength(6);
|
||||
});
|
||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||
await waitFor(() => {
|
||||
waitFor(() => {
|
||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||
expect(screen.getByRole('menu').children).toHaveLength(10);
|
||||
});
|
||||
@@ -127,7 +104,7 @@ describe('SimpleMarketToolbar', () => {
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||
`/markets/${MarketState.STATE_ACTIVE}/Future`
|
||||
'/markets/STATE_ACTIVE/Future'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -138,91 +115,17 @@ describe('SimpleMarketToolbar', () => {
|
||||
);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||
`/markets/${MarketState.STATE_ACTIVE}/Future/tEURO`
|
||||
'/markets/STATE_ACTIVE/Future/tEURO'
|
||||
);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||
await waitFor(() => {
|
||||
waitFor(() => {
|
||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||
});
|
||||
const menu = screen.getByRole('menu');
|
||||
const pending = getAllByText(menu, 'Pending')[0];
|
||||
await act(() => {
|
||||
fireEvent.click(pending);
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(mockedNavigate).toHaveBeenCalledWith(
|
||||
`/markets/${MarketState.STATE_PENDING}/Future/tEURO`
|
||||
fireEvent.click(screen.getByText('Pending'));
|
||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||
'/markets/Pending/Future/tEURO'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('stateChange callback should work well', async () => {
|
||||
(useParams as jest.Mock).mockImplementation(() => ({
|
||||
asset: 'asset1',
|
||||
product: 'product1',
|
||||
state: 'state1',
|
||||
}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||
});
|
||||
const menu = screen.getByRole('menu');
|
||||
const suspended = getAllByText(menu, 'Suspended')[0];
|
||||
fireEvent.click(suspended);
|
||||
|
||||
expect(mockedNavigate).toHaveBeenCalledWith(
|
||||
`/markets/${MarketState.STATE_SUSPENDED}/product1/asset1`
|
||||
);
|
||||
});
|
||||
|
||||
it('stateChange callback should call navigate with url with state only', async () => {
|
||||
(useParams as jest.Mock).mockImplementation(() => ({}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||
});
|
||||
const menu = screen.getByRole('menu');
|
||||
const closed = getAllByText(menu, 'Closed')[0];
|
||||
fireEvent.click(closed);
|
||||
|
||||
expect(mockedNavigate).toHaveBeenCalledWith(
|
||||
`/markets/${MarketState.STATE_CLOSED}`
|
||||
);
|
||||
});
|
||||
|
||||
it('stateChange callback should call navigate with no asset', async () => {
|
||||
(useParams as jest.Mock).mockImplementation(() => ({
|
||||
asset: 'all',
|
||||
state: 'state1',
|
||||
}));
|
||||
render(
|
||||
<MockedProvider mocks={[]} addTypename={false}>
|
||||
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||
</MockedProvider>,
|
||||
{ wrapper: BrowserRouter }
|
||||
);
|
||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||
await waitFor(() => {
|
||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const menu = screen.getByRole('menu');
|
||||
const active = getAllByText(menu, 'Active')[0];
|
||||
fireEvent.click(active);
|
||||
expect(mockedNavigate).toHaveBeenCalledWith('/markets');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -123,11 +123,10 @@ const SimpleMarketToolbar = ({ data }: Props) => {
|
||||
</ul>
|
||||
<div className="grid gap-4 pb-2 mt-2 md:mt-6 md:grid-cols-[min-content,min-content,1fr]">
|
||||
<div className="pb-2">
|
||||
<DropdownMenu open={isOpen} onOpenChange={(open) => setOpen(open)}>
|
||||
<DropdownMenu onOpenChange={(open) => setOpen(open)}>
|
||||
<DropdownMenuTrigger
|
||||
className="mr-2 w-auto text-capMenu text-black dark:text-white"
|
||||
data-testid="state-trigger"
|
||||
onClick={() => setOpen(!isOpen)}
|
||||
>
|
||||
<div className="w-full justify-between uppercase inline-flex items-center justify-center box-border">
|
||||
{STATES_FILTER.find(
|
||||
|
||||
@@ -88,7 +88,7 @@ export const Stepper = ({ steps }: StepperProps) => {
|
||||
'md:mt-0 font-alpha uppercase text-black dark:text-white',
|
||||
{
|
||||
'mt-2 text-md md:text-2xl': isActive,
|
||||
'mt-4 text-sm md:text-lg md:ml-2': !isActive,
|
||||
'mt-4 text-sm md:text-lg md:ml-8': !isActive,
|
||||
}
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * from './traffic-light';
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
interface TrafficLightProps {
|
||||
value: number;
|
||||
q1: number;
|
||||
q2: number;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const TrafficLight = ({
|
||||
value,
|
||||
q1,
|
||||
q2,
|
||||
children,
|
||||
}: TrafficLightProps) => {
|
||||
const slippageClassName = classNames({
|
||||
'text-darkerGreen dark:text-lightGreen': value < q1,
|
||||
'text-amber': value >= q1 && value < q2,
|
||||
'text-vega-red': value >= q2,
|
||||
});
|
||||
|
||||
return <div className={slippageClassName}>{children || value}</div>;
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -22,7 +22,7 @@ const useColumnDefinitions = ({ isMobile }: Props) => {
|
||||
headerName: t('Markets'),
|
||||
headerClass: 'uppercase',
|
||||
minWidth: isMobile ? 160 : 350,
|
||||
field: 'tradableInstrument.instrument.name',
|
||||
field: 'name',
|
||||
cellClass: 'overflow-visible',
|
||||
cellRenderer: ({ data }: { data: SimpleMarketsType }) => (
|
||||
<MarketNameRenderer market={data} isMobile={isMobile} />
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { getAssets, t } from '@vegaprotocol/react-helpers';
|
||||
import { assetsConnectionToAssets, t } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
import { SubHeading } from '../../components/sub-heading';
|
||||
@@ -39,7 +39,7 @@ export const ASSETS_QUERY = gql`
|
||||
const Assets = () => {
|
||||
const { data } = useQuery<AssetsQuery>(ASSETS_QUERY);
|
||||
|
||||
const assets = getAssets(data);
|
||||
const assets = assetsConnectionToAssets(data?.assetsConnection);
|
||||
|
||||
return (
|
||||
<section>
|
||||
|
||||
@@ -9,23 +9,7 @@ import { ProposalState, ProposalRejectionReason, VoteValue } from "@vegaprotocol
|
||||
// GraphQL query operation: ProposalsQuery
|
||||
// ====================================================
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_rationale {
|
||||
__typename: "ProposalRationale";
|
||||
/**
|
||||
* Title to be used to give a short description of the proposal in lists.
|
||||
* This is to be between 0 and 100 unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Description to show a short title / something in case the link goes offline.
|
||||
* This is to be between 0 and 20k unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_party {
|
||||
export interface ProposalsQuery_proposals_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -33,11 +17,11 @@ export interface ProposalsQuery_proposalsConnection_edges_node_party {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateAsset {
|
||||
export interface ProposalsQuery_proposals_terms_change_UpdateAsset {
|
||||
__typename: "UpdateAsset" | "NewFreeform";
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket_instrument {
|
||||
export interface ProposalsQuery_proposals_terms_change_NewMarket_instrument {
|
||||
__typename: "InstrumentConfiguration";
|
||||
/**
|
||||
* Full and fairly descriptive name for the instrument
|
||||
@@ -45,20 +29,20 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewM
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket {
|
||||
export interface ProposalsQuery_proposals_terms_change_NewMarket {
|
||||
__typename: "NewMarket";
|
||||
/**
|
||||
* New market instrument configuration
|
||||
*/
|
||||
instrument: ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket_instrument;
|
||||
instrument: ProposalsQuery_proposals_terms_change_NewMarket_instrument;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateMarket {
|
||||
export interface ProposalsQuery_proposals_terms_change_UpdateMarket {
|
||||
__typename: "UpdateMarket";
|
||||
marketId: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset {
|
||||
export interface ProposalsQuery_proposals_terms_change_NewAsset_source_BuiltinAsset {
|
||||
__typename: "BuiltinAsset";
|
||||
/**
|
||||
* Maximum amount that can be requested by a party through the built-in asset faucet at a time
|
||||
@@ -66,7 +50,7 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewA
|
||||
maxFaucetAmountMint: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20 {
|
||||
export interface ProposalsQuery_proposals_terms_change_NewAsset_source_ERC20 {
|
||||
__typename: "ERC20";
|
||||
/**
|
||||
* The address of the ERC20 contract
|
||||
@@ -74,9 +58,9 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewA
|
||||
contractAddress: string;
|
||||
}
|
||||
|
||||
export type ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source = ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20;
|
||||
export type ProposalsQuery_proposals_terms_change_NewAsset_source = ProposalsQuery_proposals_terms_change_NewAsset_source_BuiltinAsset | ProposalsQuery_proposals_terms_change_NewAsset_source_ERC20;
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset {
|
||||
export interface ProposalsQuery_proposals_terms_change_NewAsset {
|
||||
__typename: "NewAsset";
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
@@ -85,10 +69,10 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_NewA
|
||||
/**
|
||||
* The source of the new asset
|
||||
*/
|
||||
source: ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset_source;
|
||||
source: ProposalsQuery_proposals_terms_change_NewAsset_source;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter {
|
||||
export interface ProposalsQuery_proposals_terms_change_UpdateNetworkParameter_networkParameter {
|
||||
__typename: "NetworkParameter";
|
||||
/**
|
||||
* The name of the network parameter
|
||||
@@ -100,14 +84,14 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_Upda
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter {
|
||||
export interface ProposalsQuery_proposals_terms_change_UpdateNetworkParameter {
|
||||
__typename: "UpdateNetworkParameter";
|
||||
networkParameter: ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter;
|
||||
networkParameter: ProposalsQuery_proposals_terms_change_UpdateNetworkParameter_networkParameter;
|
||||
}
|
||||
|
||||
export type ProposalsQuery_proposalsConnection_edges_node_terms_change = ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewMarket | ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateMarket | ProposalsQuery_proposalsConnection_edges_node_terms_change_NewAsset | ProposalsQuery_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter;
|
||||
export type ProposalsQuery_proposals_terms_change = ProposalsQuery_proposals_terms_change_UpdateAsset | ProposalsQuery_proposals_terms_change_NewMarket | ProposalsQuery_proposals_terms_change_UpdateMarket | ProposalsQuery_proposals_terms_change_NewAsset | ProposalsQuery_proposals_terms_change_UpdateNetworkParameter;
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_terms {
|
||||
export interface ProposalsQuery_proposals_terms {
|
||||
__typename: "ProposalTerms";
|
||||
/**
|
||||
* RFC3339Nano time and date when voting closes for this proposal.
|
||||
@@ -123,18 +107,18 @@ export interface ProposalsQuery_proposalsConnection_edges_node_terms {
|
||||
/**
|
||||
* Actual change being introduced by the proposal - action the proposal triggers if passed and enacted.
|
||||
*/
|
||||
change: ProposalsQuery_proposalsConnection_edges_node_terms_change;
|
||||
change: ProposalsQuery_proposals_terms_change;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface ProposalsQuery_proposals_votes_yes_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
currentStakeAvailable: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party {
|
||||
export interface ProposalsQuery_proposals_votes_yes_votes_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -143,10 +127,10 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_p
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary;
|
||||
stake: ProposalsQuery_proposals_votes_yes_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes {
|
||||
export interface ProposalsQuery_proposals_votes_yes_votes {
|
||||
__typename: "Vote";
|
||||
/**
|
||||
* The vote value cast
|
||||
@@ -155,14 +139,14 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes {
|
||||
/**
|
||||
* The party casting the vote
|
||||
*/
|
||||
party: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes_party;
|
||||
party: ProposalsQuery_proposals_votes_yes_votes_party;
|
||||
/**
|
||||
* RFC3339Nano time and date when the vote reached Vega network
|
||||
*/
|
||||
datetime: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes {
|
||||
export interface ProposalsQuery_proposals_votes_yes {
|
||||
__typename: "ProposalVoteSide";
|
||||
/**
|
||||
* Total number of governance tokens from the votes cast for this side
|
||||
@@ -175,18 +159,18 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_yes {
|
||||
/**
|
||||
* All votes cast for this side
|
||||
*/
|
||||
votes: ProposalsQuery_proposalsConnection_edges_node_votes_yes_votes[] | null;
|
||||
votes: ProposalsQuery_proposals_votes_yes_votes[] | null;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface ProposalsQuery_proposals_votes_no_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
currentStakeAvailable: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party {
|
||||
export interface ProposalsQuery_proposals_votes_no_votes_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -195,10 +179,10 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_pa
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary;
|
||||
stake: ProposalsQuery_proposals_votes_no_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes {
|
||||
export interface ProposalsQuery_proposals_votes_no_votes {
|
||||
__typename: "Vote";
|
||||
/**
|
||||
* The vote value cast
|
||||
@@ -207,14 +191,14 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_no_votes {
|
||||
/**
|
||||
* The party casting the vote
|
||||
*/
|
||||
party: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes_party;
|
||||
party: ProposalsQuery_proposals_votes_no_votes_party;
|
||||
/**
|
||||
* RFC3339Nano time and date when the vote reached Vega network
|
||||
*/
|
||||
datetime: string;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes_no {
|
||||
export interface ProposalsQuery_proposals_votes_no {
|
||||
__typename: "ProposalVoteSide";
|
||||
/**
|
||||
* Total number of governance tokens from the votes cast for this side
|
||||
@@ -227,31 +211,27 @@ export interface ProposalsQuery_proposalsConnection_edges_node_votes_no {
|
||||
/**
|
||||
* All votes cast for this side
|
||||
*/
|
||||
votes: ProposalsQuery_proposalsConnection_edges_node_votes_no_votes[] | null;
|
||||
votes: ProposalsQuery_proposals_votes_no_votes[] | null;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node_votes {
|
||||
export interface ProposalsQuery_proposals_votes {
|
||||
__typename: "ProposalVotes";
|
||||
/**
|
||||
* Yes votes cast for this proposal
|
||||
*/
|
||||
yes: ProposalsQuery_proposalsConnection_edges_node_votes_yes;
|
||||
yes: ProposalsQuery_proposals_votes_yes;
|
||||
/**
|
||||
* No votes cast for this proposal
|
||||
*/
|
||||
no: ProposalsQuery_proposalsConnection_edges_node_votes_no;
|
||||
no: ProposalsQuery_proposals_votes_no;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges_node {
|
||||
export interface ProposalsQuery_proposals {
|
||||
__typename: "Proposal";
|
||||
/**
|
||||
* Proposal ID that is filled by Vega once proposal reaches the network
|
||||
*/
|
||||
id: string | null;
|
||||
/**
|
||||
* Rationale behind the proposal
|
||||
*/
|
||||
rationale: ProposalsQuery_proposalsConnection_edges_node_rationale;
|
||||
/**
|
||||
* A UUID reference to aid tracking proposals on Vega
|
||||
*/
|
||||
@@ -271,36 +251,20 @@ export interface ProposalsQuery_proposalsConnection_edges_node {
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: ProposalsQuery_proposalsConnection_edges_node_party;
|
||||
party: ProposalsQuery_proposals_party;
|
||||
/**
|
||||
* Terms of the proposal
|
||||
*/
|
||||
terms: ProposalsQuery_proposalsConnection_edges_node_terms;
|
||||
terms: ProposalsQuery_proposals_terms;
|
||||
/**
|
||||
* Votes cast for this proposal
|
||||
*/
|
||||
votes: ProposalsQuery_proposalsConnection_edges_node_votes;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection_edges {
|
||||
__typename: "ProposalEdge";
|
||||
/**
|
||||
* The proposal data
|
||||
*/
|
||||
node: ProposalsQuery_proposalsConnection_edges_node;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery_proposalsConnection {
|
||||
__typename: "ProposalsConnection";
|
||||
/**
|
||||
* List of proposals available for the connection
|
||||
*/
|
||||
edges: (ProposalsQuery_proposalsConnection_edges | null)[] | null;
|
||||
votes: ProposalsQuery_proposals_votes;
|
||||
}
|
||||
|
||||
export interface ProposalsQuery {
|
||||
/**
|
||||
* All governance proposals in the Vega network
|
||||
*/
|
||||
proposalsConnection: ProposalsQuery_proposalsConnection;
|
||||
proposals: ProposalsQuery_proposals[] | null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -4,90 +4,95 @@ import React from 'react';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
import { SubHeading } from '../../components/sub-heading';
|
||||
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||
import { getProposals } from '@vegaprotocol/governance';
|
||||
import type {
|
||||
ProposalsQuery,
|
||||
ProposalsQuery_proposalsConnection_edges_node,
|
||||
ProposalsQuery_proposals_terms_change,
|
||||
} from './__generated__/ProposalsQuery';
|
||||
|
||||
const PROPOSALS_QUERY = gql`
|
||||
export function getProposalName(change: ProposalsQuery_proposals_terms_change) {
|
||||
if (change.__typename === 'NewAsset') {
|
||||
return t(`New asset: ${change.symbol}`);
|
||||
} else if (change.__typename === 'NewMarket') {
|
||||
return t(`New market: ${change.instrument.name}`);
|
||||
} else if (change.__typename === 'UpdateMarket') {
|
||||
return t(`Update market: ${change.marketId}`);
|
||||
} else if (change.__typename === 'UpdateNetworkParameter') {
|
||||
return t(`Update network: ${change.networkParameter.key}`);
|
||||
}
|
||||
|
||||
return t('Unknown proposal');
|
||||
}
|
||||
|
||||
const PROPOSAL_QUERY = gql`
|
||||
query ProposalsQuery {
|
||||
proposalsConnection {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
rationale {
|
||||
title
|
||||
description
|
||||
proposals {
|
||||
id
|
||||
reference
|
||||
state
|
||||
datetime
|
||||
rejectionReason
|
||||
party {
|
||||
id
|
||||
}
|
||||
terms {
|
||||
closingDatetime
|
||||
enactmentDatetime
|
||||
change {
|
||||
... on NewMarket {
|
||||
instrument {
|
||||
name
|
||||
}
|
||||
}
|
||||
reference
|
||||
state
|
||||
datetime
|
||||
rejectionReason
|
||||
party {
|
||||
id
|
||||
... on UpdateMarket {
|
||||
marketId
|
||||
}
|
||||
terms {
|
||||
closingDatetime
|
||||
enactmentDatetime
|
||||
change {
|
||||
... on NewMarket {
|
||||
instrument {
|
||||
name
|
||||
}
|
||||
... on NewAsset {
|
||||
__typename
|
||||
symbol
|
||||
source {
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
... on UpdateMarket {
|
||||
marketId
|
||||
}
|
||||
... on NewAsset {
|
||||
__typename
|
||||
symbol
|
||||
source {
|
||||
... on BuiltinAsset {
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
... on UpdateNetworkParameter {
|
||||
networkParameter {
|
||||
key
|
||||
value
|
||||
}
|
||||
... on ERC20 {
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
... on UpdateNetworkParameter {
|
||||
networkParameter {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
votes {
|
||||
yes {
|
||||
totalTokens
|
||||
totalNumber
|
||||
votes {
|
||||
yes {
|
||||
totalTokens
|
||||
totalNumber
|
||||
votes {
|
||||
value
|
||||
party {
|
||||
id
|
||||
stakingSummary {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
datetime
|
||||
value
|
||||
party {
|
||||
id
|
||||
stake {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
no {
|
||||
totalTokens
|
||||
totalNumber
|
||||
votes {
|
||||
value
|
||||
party {
|
||||
id
|
||||
stakingSummary {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
datetime
|
||||
datetime
|
||||
}
|
||||
}
|
||||
no {
|
||||
totalTokens
|
||||
totalNumber
|
||||
votes {
|
||||
value
|
||||
party {
|
||||
id
|
||||
stake {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
datetime
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,12 +101,9 @@ const PROPOSALS_QUERY = gql`
|
||||
`;
|
||||
|
||||
const Governance = () => {
|
||||
const { data } = useQuery<ProposalsQuery>(PROPOSALS_QUERY, {
|
||||
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY, {
|
||||
errorPolicy: 'ignore',
|
||||
});
|
||||
const proposals = getProposals(
|
||||
data
|
||||
) as ProposalsQuery_proposalsConnection_edges_node[];
|
||||
|
||||
if (!data) return null;
|
||||
return (
|
||||
@@ -109,11 +111,9 @@ const Governance = () => {
|
||||
<RouteTitle data-testid="governance-header">
|
||||
{t('Governance Proposals')}
|
||||
</RouteTitle>
|
||||
{proposals.map((p) => (
|
||||
{data.proposals?.map((p) => (
|
||||
<React.Fragment key={p.id}>
|
||||
<SubHeading>
|
||||
{p.rationale.title || p.rationale.description}
|
||||
</SubHeading>
|
||||
<SubHeading>{getProposalName(p.terms.change)}</SubHeading>
|
||||
<SyntaxHighlighter data={p} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
||||
@@ -465,6 +465,10 @@ export interface MarketsQuery_markets {
|
||||
* Market ID
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Market full name
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Fees related data
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -11,6 +11,7 @@ const MARKETS_QUERY = gql`
|
||||
query MarketsQuery {
|
||||
markets {
|
||||
id
|
||||
name
|
||||
fees {
|
||||
factors {
|
||||
makerFee
|
||||
@@ -153,9 +154,7 @@ const Markets = () => {
|
||||
{data?.markets
|
||||
? data.markets.map((m) => (
|
||||
<React.Fragment key={m.id}>
|
||||
<SubHeading data-testid="markets-header">
|
||||
{m.tradableInstrument.instrument.name}
|
||||
</SubHeading>
|
||||
<SubHeading data-testid="markets-header">{m.name}</SubHeading>
|
||||
<SyntaxHighlighter data={m} />
|
||||
</React.Fragment>
|
||||
))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -89,7 +89,7 @@
|
||||
"tranche_end": "2022-10-12T00:53:20.000Z",
|
||||
"total_added": "1010.000000000000000001",
|
||||
"total_removed": "668.4622323651",
|
||||
"locked_amount": "79.60645389396243020007881827118214102",
|
||||
"locked_amount": "98.32505010147130990009735153475393199",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1000",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"rationale": {
|
||||
"title": "An example freeform proposal with unique number of: ",
|
||||
"title": "An example freeform proposal",
|
||||
"description": "I propose that everyone evaluate the following IPFS document and vote Yes if they agree. [bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si](https://dweb.link/ipfs/bafybeigwwctpv37xdcwacqxvekr6e4kaemqsrv34em6glkbiceo3fcy4si)"
|
||||
},
|
||||
"terms": {
|
||||
|
||||
@@ -196,7 +196,11 @@ context('Governance flow - with eth and vega wallets connected', function () {
|
||||
.then((proposalId) => {
|
||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||
cy.get('[data-testid="filter-input"]').type(proposalId);
|
||||
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||
cy.get(`#${proposalId}`).should(
|
||||
'contain',
|
||||
`Freeform proposal: ${proposalId}`,
|
||||
txTimeout
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -226,7 +230,11 @@ context('Governance flow - with eth and vega wallets connected', function () {
|
||||
let proposalId = proposal.response.body.data.busEvents[0].event.id;
|
||||
cy.get('[data-testid="set-proposals-filter-visible"]').click();
|
||||
cy.get('[data-testid="filter-input"]').type(proposerId);
|
||||
cy.get(`#${proposalId}`).should('contain', proposalId);
|
||||
cy.get(`#${proposalId}`).should(
|
||||
'contain',
|
||||
`Freeform proposal: ${proposalId}`,
|
||||
txTimeout
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -256,7 +264,7 @@ context('Governance flow - with eth and vega wallets connected', function () {
|
||||
.then((proposalId) => {
|
||||
cy.get(openProposals).within(() => {
|
||||
cy.get(`#${proposalId}`)
|
||||
.should('contain', proposalId)
|
||||
.should('contain', `Freeform proposal: ${proposalId}`, txTimeout)
|
||||
.and('contain', 'Open')
|
||||
.and('be.visible')
|
||||
.within(() => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
||||
const restConnectorForm = '[data-testid="rest-connector-form"]';
|
||||
const vegaWalletNameElement = '[data-testid="wallet-name"]';
|
||||
const vegaWalletName = Cypress.env('vegaWalletName');
|
||||
const vegaWalletLocation = Cypress.env('vegaWalletLocation');
|
||||
const vegaWalletPassphrase = Cypress.env('vegaWalletPassphrase');
|
||||
@@ -15,11 +14,6 @@ Cypress.Commands.add('vega_wallet_import', () => {
|
||||
cy.exec(
|
||||
`vegawallet service run --network DV --automatic-consent --home ${vegaWalletLocation}`
|
||||
);
|
||||
cy.exec(`vegawallet version`)
|
||||
.its('stdout')
|
||||
.then((output) => {
|
||||
cy.log(output);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('vega_wallet_connect', () => {
|
||||
@@ -37,5 +31,5 @@ Cypress.Commands.add('vega_wallet_connect', () => {
|
||||
cy.get('#passphrase').click().type(vegaWalletPassphrase);
|
||||
cy.get('button').contains('Connect').click();
|
||||
});
|
||||
cy.get(vegaWalletNameElement).should('be.visible');
|
||||
cy.contains(`${vegaWalletName} key`, { timeout: 20000 }).should('be.visible');
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||
NX_FAIRGROUND=false
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
import type { NetworkParams } from './__generated__/NetworkParams';
|
||||
|
||||
export const NETWORK_PARAMS_QUERY = gql`
|
||||
query NetworkParams {
|
||||
networkParameters {
|
||||
key
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function useNetworkParam(params: string[]) {
|
||||
const { data, loading, error } = useQuery<NetworkParams, never>(
|
||||
NETWORK_PARAMS_QUERY
|
||||
);
|
||||
const foundParams = data?.networkParameters
|
||||
?.filter((p) => params.includes(p.key))
|
||||
.sort((a, b) => params.indexOf(a.key) - params.indexOf(b.key));
|
||||
return {
|
||||
data: foundParams ? foundParams.map((f) => f.value) : null,
|
||||
loading,
|
||||
error,
|
||||
};
|
||||
}
|
||||
+18
-30
@@ -9,22 +9,6 @@ import { ProposalState, ProposalRejectionReason, VoteValue } from "@vegaprotocol
|
||||
// GraphQL fragment: ProposalFields
|
||||
// ====================================================
|
||||
|
||||
export interface ProposalFields_rationale {
|
||||
__typename: "ProposalRationale";
|
||||
/**
|
||||
* Title to be used to give a short description of the proposal in lists.
|
||||
* This is to be between 0 and 100 unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Description to show a short title / something in case the link goes offline.
|
||||
* This is to be between 0 and 20k unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface ProposalFields_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
@@ -71,6 +55,14 @@ export interface ProposalFields_terms_change_NewMarket_instrument {
|
||||
|
||||
export interface ProposalFields_terms_change_NewMarket {
|
||||
__typename: "NewMarket";
|
||||
/**
|
||||
* Decimal places used for the new market, sets the smallest price increment on the book
|
||||
*/
|
||||
decimalPlaces: number;
|
||||
/**
|
||||
* Metadata for this instrument, tags
|
||||
*/
|
||||
metadata: string[] | null;
|
||||
/**
|
||||
* New market instrument configuration
|
||||
*/
|
||||
@@ -154,8 +146,8 @@ export interface ProposalFields_terms {
|
||||
change: ProposalFields_terms_change;
|
||||
}
|
||||
|
||||
export interface ProposalFields_votes_yes_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface ProposalFields_votes_yes_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
@@ -171,7 +163,7 @@ export interface ProposalFields_votes_yes_votes_party {
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: ProposalFields_votes_yes_votes_party_stakingSummary;
|
||||
stake: ProposalFields_votes_yes_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface ProposalFields_votes_yes_votes {
|
||||
@@ -206,8 +198,8 @@ export interface ProposalFields_votes_yes {
|
||||
votes: ProposalFields_votes_yes_votes[] | null;
|
||||
}
|
||||
|
||||
export interface ProposalFields_votes_no_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface ProposalFields_votes_no_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
@@ -223,7 +215,7 @@ export interface ProposalFields_votes_no_votes_party {
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: ProposalFields_votes_no_votes_party_stakingSummary;
|
||||
stake: ProposalFields_votes_no_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface ProposalFields_votes_no_votes {
|
||||
@@ -276,10 +268,6 @@ export interface ProposalFields {
|
||||
* Proposal ID that is filled by Vega once proposal reaches the network
|
||||
*/
|
||||
id: string | null;
|
||||
/**
|
||||
* Rationale behind the proposal
|
||||
*/
|
||||
rationale: ProposalFields_rationale;
|
||||
/**
|
||||
* A UUID reference to aid tracking proposals on Vega
|
||||
*/
|
||||
@@ -296,14 +284,14 @@ export interface ProposalFields {
|
||||
* Reason for the proposal to be rejected by the core
|
||||
*/
|
||||
rejectionReason: ProposalRejectionReason | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: ProposalFields_party;
|
||||
/**
|
||||
* Error details of the rejectionReason
|
||||
*/
|
||||
errorDetails: string | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: ProposalFields_party;
|
||||
/**
|
||||
* Terms of the proposal
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
export const CurrentProposalState = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const { state } = proposal;
|
||||
let className = 'text-white';
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
export const StatusPass = ({ children }: { children: React.ReactNode }) => (
|
||||
<span className="text-vega-green">{children}</span>
|
||||
@@ -17,7 +17,7 @@ export const StatusFail = ({ children }: { children: React.ReactNode }) => (
|
||||
export const CurrentProposalStatus = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const { willPass, majorityMet, participationMet } = useVoteInformation({
|
||||
proposal,
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { KeyValueTable, KeyValueTableRow } from '@vegaprotocol/ui-toolkit';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
import { CurrentProposalState } from '../current-proposal-state';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
|
||||
interface ProposalChangeTableProps {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}
|
||||
|
||||
export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
|
||||
|
||||
+66
-76
@@ -1,9 +1,9 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { generateProposal } from '../../test-helpers/generate-proposals';
|
||||
import { ProposalHeader } from './proposal-header';
|
||||
import type { Proposal_proposal } from '@vegaprotocol/governance';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
const renderComponent = (proposal: Proposal_proposal) => (
|
||||
const renderComponent = (proposal: Proposals_proposals) => (
|
||||
<ProposalHeader proposal={proposal} />
|
||||
);
|
||||
|
||||
@@ -12,13 +12,10 @@ describe('Proposal header', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
rationale: {
|
||||
title: 'New some market',
|
||||
description: 'A new some market',
|
||||
},
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewMarket',
|
||||
decimalPlaces: 1,
|
||||
instrument: {
|
||||
__typename: 'InstrumentConfiguration',
|
||||
name: 'Some market',
|
||||
@@ -31,18 +28,16 @@ describe('Proposal header', () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
metadata: [],
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
'New some market'
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'New market: Some market'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-description')).toHaveTextContent(
|
||||
'A new some market'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'tGBP settled future.'
|
||||
);
|
||||
});
|
||||
@@ -51,9 +46,6 @@ describe('Proposal header', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
rationale: {
|
||||
title: 'New market id',
|
||||
},
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateMarket',
|
||||
@@ -63,13 +55,7 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
'New market id'
|
||||
);
|
||||
expect(
|
||||
screen.queryByTestId('proposal-description')
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Market change: MarketId'
|
||||
);
|
||||
});
|
||||
@@ -78,10 +64,6 @@ describe('Proposal header', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
rationale: {
|
||||
title: 'New asset: Fake currency',
|
||||
description: '',
|
||||
},
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewAsset',
|
||||
@@ -96,10 +78,10 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'New asset: Fake currency'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'Symbol: FAKE. ERC20 0x0'
|
||||
);
|
||||
});
|
||||
@@ -122,10 +104,10 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
'Unknown proposal'
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'New asset: Fake currency'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'Symbol: BIA. Max faucet amount mint: 300'
|
||||
);
|
||||
});
|
||||
@@ -134,9 +116,6 @@ describe('Proposal header', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
rationale: {
|
||||
title: 'Network parameter',
|
||||
},
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateNetworkParameter',
|
||||
@@ -150,22 +129,25 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Network parameter'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'Network key to Network value'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders Freeform network - short rationale', () => {
|
||||
// Skipped until proposals have rationale - https://github.com/vegaprotocol/frontend-monorepo/issues/824
|
||||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
it.skip('Renders Freeform network - short rationale', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
id: 'short',
|
||||
rationale: {
|
||||
title: '0x0',
|
||||
},
|
||||
// rationale: {
|
||||
// hash: '0x0',
|
||||
// description: 'freeform description',
|
||||
// },
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewFreeform',
|
||||
@@ -174,23 +156,27 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent('0x0');
|
||||
expect(
|
||||
screen.queryByTestId('proposal-description')
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent('short');
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'freeform description'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details-one')).toBeEmptyDOMElement();
|
||||
expect(screen.getByTestId('proposal-details-two')).toHaveTextContent(
|
||||
'short'
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders Freeform proposal - long rationale (105 chars)', () => {
|
||||
// Skipped until proposals have rationale
|
||||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
it.skip('Renders Freeform proposal - long rationale (105 chars)', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
id: 'long',
|
||||
rationale: {
|
||||
title: '0x0',
|
||||
description:
|
||||
'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
|
||||
},
|
||||
// rationale: {
|
||||
// hash: '0x0',
|
||||
// description:
|
||||
// 'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean dolor.',
|
||||
// },
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewFreeform',
|
||||
@@ -201,24 +187,29 @@ describe('Proposal header', () => {
|
||||
);
|
||||
// For a rationale over 100 chars, we expect the header to be truncated at
|
||||
// 100 chars with ellipsis and the details-one element to contain the rest.
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent('0x0');
|
||||
expect(screen.getByTestId('proposal-description')).toHaveTextContent(
|
||||
'Class aptent taciti sociosqu ad litora torquent per conubia'
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean…'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'dolor'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details-two')).toHaveTextContent(
|
||||
'long'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent('long');
|
||||
});
|
||||
|
||||
it('Renders Freeform proposal - extra long rationale (165 chars)', () => {
|
||||
// Skipped until proposals have rationale
|
||||
// eslint-disable-next-line jest/no-disabled-tests
|
||||
it.skip('Renders Freeform proposal - extra long rationale (165 chars)', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
id: 'extraLong',
|
||||
rationale: {
|
||||
title:
|
||||
'Aenean sem odio, eleifend non sodales vitae, porttitor eu ex. Aliquam erat volutpat. Fusce pharetra libero quis risus lobortis, sed ornare leo efficitur turpis duis.',
|
||||
description:
|
||||
'Aenean sem odio, eleifend non sodales vitae, porttitor eu ex. Aliquam erat volutpat. Fusce pharetra libero quis risus lobortis, sed ornare leo efficitur turpis duis.',
|
||||
},
|
||||
// rationale: {
|
||||
// hash: '0x0',
|
||||
// description:
|
||||
// 'Aenean sem odio, eleifend non sodales vitae, porttitor eu ex. Aliquam erat volutpat. Fusce pharetra libero quis risus lobortis, sed ornare leo efficitur turpis duis.',
|
||||
// },
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewFreeform',
|
||||
@@ -230,13 +221,13 @@ describe('Proposal header', () => {
|
||||
// For a rationale over 160 chars, we expect the header to be truncated at 100
|
||||
// chars with ellipsis and the details-one element to contain 60 chars and also
|
||||
// be truncated with an ellipsis.
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Aenean sem odio, eleifend non sodales vitae, porttitor eu ex. Aliquam erat volutpat. Fusce pharetra…'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-description')).toHaveTextContent(
|
||||
'Aenean sem odio, eleifend non sodales vitae, porttitor eu e…'
|
||||
expect(screen.getByTestId('proposal-details-one')).toHaveTextContent(
|
||||
'libero quis risus lobortis, sed ornare leo efficitur turpis…'
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-details-two')).toHaveTextContent(
|
||||
'extraLong'
|
||||
);
|
||||
});
|
||||
@@ -247,9 +238,6 @@ describe('Proposal header', () => {
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
id: 'freeform id',
|
||||
rationale: {
|
||||
title: 'freeform',
|
||||
},
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'NewFreeform',
|
||||
@@ -258,13 +246,15 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent('freeform');
|
||||
expect(
|
||||
screen.queryByTestId('proposal-description')
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId('proposal-details')).toHaveTextContent(
|
||||
'freeform id'
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Freeform proposal: freeform id'
|
||||
);
|
||||
expect(
|
||||
screen.queryByTestId('proposal-details-one')
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByTestId('proposal-details-two')
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("Renders unknown proposal if it's a different proposal type", () => {
|
||||
@@ -280,7 +270,7 @@ describe('Proposal header', () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-title')).toHaveTextContent(
|
||||
expect(screen.getByTestId('proposal-header')).toHaveTextContent(
|
||||
'Unknown proposal'
|
||||
);
|
||||
});
|
||||
|
||||
+46
-38
@@ -1,28 +1,24 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ReactNode } from 'react';
|
||||
import { shorten } from '@vegaprotocol/react-helpers';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
export const ProposalHeader = ({ proposal }: { proposal: ProposalFields }) => {
|
||||
export const ProposalHeader = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { change } = proposal.terms;
|
||||
|
||||
let details: ReactNode;
|
||||
|
||||
let title = proposal.rationale.title.trim();
|
||||
let description = proposal.rationale.description.trim();
|
||||
if (title.length === 0 && description.length > 0) {
|
||||
title = description;
|
||||
description = '';
|
||||
}
|
||||
|
||||
const titleContent = shorten(title, 100);
|
||||
const descriptionContent = shorten(description, 60);
|
||||
let headerText: string;
|
||||
let detailsOne: ReactNode;
|
||||
let detailsTwo: ReactNode;
|
||||
|
||||
switch (change.__typename) {
|
||||
case 'NewMarket': {
|
||||
details = (
|
||||
headerText = `${t('New market')}: ${change.instrument.name}`;
|
||||
detailsOne = (
|
||||
<>
|
||||
{t('Code')}: {change.instrument.code}.{' '}
|
||||
{change.instrument.futureProduct?.settlementAsset.symbol ? (
|
||||
@@ -40,11 +36,12 @@ export const ProposalHeader = ({ proposal }: { proposal: ProposalFields }) => {
|
||||
break;
|
||||
}
|
||||
case 'UpdateMarket': {
|
||||
details = `${t('Market change')}: ${change.marketId}`;
|
||||
headerText = `${t('Market change')}: ${change.marketId}`;
|
||||
break;
|
||||
}
|
||||
case 'NewAsset': {
|
||||
details = (
|
||||
headerText = `${t('New asset')}: ${change.name}`;
|
||||
detailsOne = (
|
||||
<>
|
||||
{t('Symbol')}: {change.symbol}.{' '}
|
||||
<Lozenge>
|
||||
@@ -60,7 +57,8 @@ export const ProposalHeader = ({ proposal }: { proposal: ProposalFields }) => {
|
||||
}
|
||||
case 'UpdateNetworkParameter': {
|
||||
const parametersClasses = 'font-mono leading-none';
|
||||
details = (
|
||||
headerText = `${t('Network parameter')}`;
|
||||
detailsOne = (
|
||||
<>
|
||||
<span className={`${parametersClasses} mr-2`}>
|
||||
{change.networkParameter.key}
|
||||
@@ -74,34 +72,44 @@ export const ProposalHeader = ({ proposal }: { proposal: ProposalFields }) => {
|
||||
break;
|
||||
}
|
||||
case 'NewFreeform': {
|
||||
details = `${proposal.id}`;
|
||||
// When rationale exists (https://github.com/vegaprotocol/frontend-monorepo/issues/824):
|
||||
// const description = proposal.rationale.description.trim();
|
||||
// const headerMaxLength = 100;
|
||||
// const descriptionOneMaxLength = 60;
|
||||
// const headerOverflow = description.length > headerMaxLength;
|
||||
// const descriptionOneOverflow =
|
||||
// description.length > headerMaxLength + descriptionOneMaxLength;
|
||||
//
|
||||
// headerText = `${description.substring(0, headerMaxLength - 1).trim()}${
|
||||
// headerOverflow ? '…' : ''
|
||||
// }`;
|
||||
// detailsOne = headerOverflow
|
||||
// ? `${description
|
||||
// .substring(
|
||||
// headerMaxLength - 1,
|
||||
// headerMaxLength + descriptionOneMaxLength - 1
|
||||
// )
|
||||
// .trim()}${descriptionOneOverflow ? '…' : ''}`
|
||||
// : '';
|
||||
// detailsTwo = `${proposal.id}`;
|
||||
headerText = proposal.id
|
||||
? `${t('Freeform proposal')}: ${proposal.id.trim()}`
|
||||
: `${t('Unknown proposal')}`;
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
headerText = `${t('Unknown proposal')}`;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="text-sm mb-2">
|
||||
<header data-testid="proposal-title">
|
||||
<h2
|
||||
{...(title && title.length > titleContent.length && { title: title })}
|
||||
className="text-lg mx-0 mt-0 mb-1 font-semibold"
|
||||
>
|
||||
{titleContent || t('Unknown proposal')}
|
||||
</h2>
|
||||
<header data-testid="proposal-header">
|
||||
<h2 className="text-lg mx-0 mt-0 mb-1 font-semibold">{headerText}</h2>
|
||||
</header>
|
||||
{descriptionContent && (
|
||||
<div
|
||||
className="mb-4"
|
||||
{...(description.length > descriptionContent.length && {
|
||||
title: description,
|
||||
})}
|
||||
data-testid="proposal-description"
|
||||
>
|
||||
{descriptionContent}
|
||||
</div>
|
||||
)}
|
||||
{details && <div data-testid="proposal-details">{details}</div>}
|
||||
{detailsOne && <div data-testid="proposal-details-one">{detailsOne}</div>}
|
||||
{detailsTwo && <div data-testid="proposal-details-two">{detailsTwo}</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||
import type { ProposalFields_terms } from '../../__generated__/ProposalFields';
|
||||
import type { Proposal_proposal_terms } from '../../proposal/__generated__/Proposal';
|
||||
|
||||
export const ProposalTermsJson = ({
|
||||
terms,
|
||||
}: {
|
||||
terms: ProposalFields_terms;
|
||||
terms: Proposal_proposal_terms;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@ import {
|
||||
formatNumberPercentage,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
import { useAppState } from '../../../../contexts/app-state/app-state-context';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
|
||||
interface ProposalVotesTableProps {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}
|
||||
|
||||
export const ProposalVotesTable = ({ proposal }: ProposalVotesTableProps) => {
|
||||
|
||||
+6
-6
@@ -26,10 +26,10 @@ import {
|
||||
lastWeek,
|
||||
nextWeek,
|
||||
} from '../../test-helpers/mocks';
|
||||
import type { ProposalsConnection_proposalsConnection_edges_node as ProposalNode } from '@vegaprotocol/governance';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
const renderComponent = (
|
||||
proposal: ProposalNode,
|
||||
proposal: Proposals_proposals,
|
||||
mock = networkParamsQueryMock
|
||||
) => (
|
||||
<Router>
|
||||
@@ -173,8 +173,8 @@ describe('Proposals list item details', () => {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: mockPubkey,
|
||||
stakingSummary: {
|
||||
__typename: 'StakingSummary',
|
||||
stake: {
|
||||
__typename: 'PartyStake',
|
||||
currentStakeAvailable: '1000',
|
||||
},
|
||||
},
|
||||
@@ -211,8 +211,8 @@ describe('Proposals list item details', () => {
|
||||
party: {
|
||||
__typename: 'Party',
|
||||
id: mockPubkey,
|
||||
stakingSummary: {
|
||||
__typename: 'StakingSummary',
|
||||
stake: {
|
||||
__typename: 'PartyStake',
|
||||
currentStakeAvailable: '1000',
|
||||
},
|
||||
},
|
||||
|
||||
+2
-2
@@ -10,12 +10,12 @@ import { format, formatDistanceToNowStrict } from 'date-fns';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
import {
|
||||
ProposalRejectionReasonMapping,
|
||||
ProposalState,
|
||||
} from '@vegaprotocol/types';
|
||||
import Routes from '../../../routes';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
|
||||
const MajorityNotReached = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -37,7 +37,7 @@ const ParticipationNotReached = () => {
|
||||
export const ProposalsListItemDetails = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const { state } = proposal;
|
||||
const { willPass, majorityMet, participationMet } = useVoteInformation({
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
import { ProposalHeader } from '../proposal-detail-header/proposal-header';
|
||||
import { ProposalsListItemDetails } from './proposals-list-item-details';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
interface ProposalsListItemProps {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}
|
||||
|
||||
export const ProposalsListItem = ({ proposal }: ProposalsListItemProps) => {
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
lastMonth,
|
||||
nextMonth,
|
||||
} from '../../test-helpers/mocks';
|
||||
import type { ProposalsConnection_proposalsConnection_edges_node as ProposalNode } from '@vegaprotocol/governance';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
const openProposalClosesNextMonth = generateProposal({
|
||||
id: 'proposal1',
|
||||
@@ -58,7 +58,7 @@ const failedProposalClosedLastMonth = generateProposal({
|
||||
},
|
||||
});
|
||||
|
||||
const renderComponent = (proposals: ProposalNode[]) => (
|
||||
const renderComponent = (proposals: Proposals_proposals[]) => (
|
||||
<Router>
|
||||
<MockedProvider mocks={[networkParamsQueryMock]}>
|
||||
<AppStateProvider>
|
||||
|
||||
@@ -4,20 +4,20 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Heading } from '../../../../components/heading';
|
||||
import { ProposalsListItem } from '../proposals-list-item';
|
||||
import { ProposalsListFilter } from '../proposals-list-filter';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
import Routes from '../../../routes';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import { Link } from 'react-router-dom';
|
||||
import type { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
import { Links } from '../../../../config';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
interface ProposalsListProps {
|
||||
proposals: ProposalFields[];
|
||||
proposals: Proposals_proposals[];
|
||||
}
|
||||
|
||||
interface SortedProposalsProps {
|
||||
open: ProposalFields[];
|
||||
closed: ProposalFields[];
|
||||
open: Proposals_proposals[];
|
||||
closed: Proposals_proposals[];
|
||||
}
|
||||
|
||||
export const ProposalsList = ({ proposals }: ProposalsListProps) => {
|
||||
@@ -39,7 +39,7 @@ export const ProposalsList = ({ proposals }: ProposalsListProps) => {
|
||||
}
|
||||
);
|
||||
|
||||
const filterPredicate = (p: ProposalFields) =>
|
||||
const filterPredicate = (p: Proposals_proposals) =>
|
||||
p.id?.includes(filterString) ||
|
||||
p.party?.id?.toString().includes(filterString);
|
||||
|
||||
|
||||
+4
-4
@@ -12,11 +12,11 @@ import {
|
||||
nextWeek,
|
||||
lastMonth,
|
||||
} from '../../test-helpers/mocks';
|
||||
import type { ProposalsConnection_proposalsConnection_edges_node as ProposalNode } from '@vegaprotocol/governance';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
const rejectedProposalClosesNextWeek = generateProposal({
|
||||
id: 'rejected1',
|
||||
state: ProposalState.STATE_OPEN,
|
||||
state: ProposalState.Open,
|
||||
party: {
|
||||
id: 'bvcx',
|
||||
},
|
||||
@@ -28,14 +28,14 @@ const rejectedProposalClosesNextWeek = generateProposal({
|
||||
|
||||
const rejectedProposalClosedLastMonth = generateProposal({
|
||||
id: 'rejected2',
|
||||
state: ProposalState.STATE_REJECTED,
|
||||
state: ProposalState.Rejected,
|
||||
terms: {
|
||||
closingDatetime: lastMonth.toString(),
|
||||
enactmentDatetime: lastMonth.toString(),
|
||||
},
|
||||
});
|
||||
|
||||
const renderComponent = (proposals: ProposalNode[]) => (
|
||||
const renderComponent = (proposals: Proposals_proposals[]) => (
|
||||
<Router>
|
||||
<MockedProvider mocks={[networkParamsQueryMock]}>
|
||||
<AppStateProvider>
|
||||
|
||||
+3
-3
@@ -3,17 +3,17 @@ import { useTranslation } from 'react-i18next';
|
||||
import { Heading } from '../../../../components/heading';
|
||||
import { ProposalsListItem } from '../proposals-list-item';
|
||||
import { ProposalsListFilter } from '../proposals-list-filter';
|
||||
import type { Proposals_proposalsConnection_edges_node } from '../../proposals/__generated__/Proposals';
|
||||
import type { Proposals_proposals } from '../../proposals/__generated__/Proposals';
|
||||
|
||||
interface ProposalsListProps {
|
||||
proposals: Proposals_proposalsConnection_edges_node[];
|
||||
proposals: Proposals_proposals[];
|
||||
}
|
||||
|
||||
export const RejectedProposalsList = ({ proposals }: ProposalsListProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [filterString, setFilterString] = useState('');
|
||||
|
||||
const filterPredicate = (p: Proposals_proposalsConnection_edges_node) =>
|
||||
const filterPredicate = (p: Proposals_proposals) =>
|
||||
p.id?.includes(filterString) ||
|
||||
p.party?.id?.toString().includes(filterString);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -4,13 +4,13 @@ import { useTranslation } from 'react-i18next';
|
||||
import { formatNumber } from '../../../../lib/format-number';
|
||||
import { ConnectToVega } from '../../../staking/connect-to-vega';
|
||||
import { useVoteInformation } from '../../hooks';
|
||||
import type { Proposal_proposal } from '../../proposal/__generated__/Proposal';
|
||||
import { CurrentProposalStatus } from '../current-proposal-status';
|
||||
import { useUserVote } from './use-user-vote';
|
||||
import { VoteButtonsContainer } from './vote-buttons';
|
||||
import { VoteProgress } from './vote-progress';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import type { Proposal_proposal } from '../../proposal/__generated__/Proposal';
|
||||
|
||||
interface VoteDetailsProps {
|
||||
proposal: Proposal_proposal;
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
import { useNetworkParams } from '@vegaprotocol/react-helpers';
|
||||
import React from 'react';
|
||||
|
||||
import { NetworkParams } from '../../../config';
|
||||
import { useAppState } from '../../../contexts/app-state/app-state-context';
|
||||
import { useNetworkParam } from '../../../hooks/use-network-param';
|
||||
import { BigNumber } from '../../../lib/bignumber';
|
||||
import { addDecimal } from '../../../lib/decimals';
|
||||
import type {
|
||||
ProposalFields,
|
||||
ProposalFields_votes_no_votes,
|
||||
ProposalFields_votes_yes_votes,
|
||||
} from '../__generated__/ProposalFields';
|
||||
Proposal_proposal_votes_no_votes,
|
||||
Proposal_proposal_votes_yes_votes,
|
||||
} from '../proposal/__generated__/Proposal';
|
||||
import type { Proposals_proposals } from '../proposals/__generated__/Proposals';
|
||||
|
||||
const useProposalNetworkParams = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const { data, loading } = useNetworkParams([
|
||||
const { data, loading } = useNetworkParam([
|
||||
NetworkParams.GOV_UPDATE_MARKET_REQUIRED_MAJORITY,
|
||||
NetworkParams.GOV_UPDATE_MARKET_REQUIRED_PARTICIPATION,
|
||||
NetworkParams.GOV_NEW_MARKET_REQUIRED_MAJORITY,
|
||||
@@ -82,7 +82,7 @@ const useProposalNetworkParams = ({
|
||||
export const useVoteInformation = ({
|
||||
proposal,
|
||||
}: {
|
||||
proposal: ProposalFields;
|
||||
proposal: Proposals_proposals;
|
||||
}) => {
|
||||
const {
|
||||
appState: { totalSupply },
|
||||
@@ -105,10 +105,10 @@ export const useVoteInformation = ({
|
||||
return new BigNumber(0);
|
||||
}
|
||||
const totalNoVotes = proposal.votes.no.votes.reduce(
|
||||
(prevValue: BigNumber, newValue: ProposalFields_votes_no_votes) => {
|
||||
return new BigNumber(
|
||||
newValue.party.stakingSummary.currentStakeAvailable
|
||||
).plus(prevValue);
|
||||
(prevValue: BigNumber, newValue: Proposal_proposal_votes_no_votes) => {
|
||||
return new BigNumber(newValue.party.stake.currentStakeAvailable).plus(
|
||||
prevValue
|
||||
);
|
||||
},
|
||||
new BigNumber(0)
|
||||
);
|
||||
@@ -120,10 +120,10 @@ export const useVoteInformation = ({
|
||||
return new BigNumber(0);
|
||||
}
|
||||
const totalYesVotes = proposal.votes.yes.votes.reduce(
|
||||
(prevValue: BigNumber, newValue: ProposalFields_votes_yes_votes) => {
|
||||
return new BigNumber(
|
||||
newValue.party.stakingSummary.currentStakeAvailable
|
||||
).plus(prevValue);
|
||||
(prevValue: BigNumber, newValue: Proposal_proposal_votes_yes_votes) => {
|
||||
return new BigNumber(newValue.party.stake.currentStakeAvailable).plus(
|
||||
prevValue
|
||||
);
|
||||
},
|
||||
new BigNumber(0)
|
||||
);
|
||||
|
||||
@@ -1,25 +1,23 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const PROPOSAL_FRAGMENT = gql`
|
||||
export const PROPOSALS_FRAGMENT = gql`
|
||||
fragment ProposalFields on Proposal {
|
||||
id
|
||||
rationale {
|
||||
title
|
||||
description
|
||||
}
|
||||
reference
|
||||
state
|
||||
datetime
|
||||
rejectionReason
|
||||
errorDetails
|
||||
party {
|
||||
id
|
||||
}
|
||||
errorDetails
|
||||
terms {
|
||||
closingDatetime
|
||||
enactmentDatetime
|
||||
change {
|
||||
... on NewMarket {
|
||||
decimalPlaces
|
||||
metadata
|
||||
instrument {
|
||||
name
|
||||
code
|
||||
@@ -39,9 +37,11 @@ export const PROPOSAL_FRAGMENT = gql`
|
||||
symbol
|
||||
source {
|
||||
... on BuiltinAsset {
|
||||
__typename
|
||||
maxFaucetAmountMint
|
||||
}
|
||||
... on ERC20 {
|
||||
__typename
|
||||
contractAddress
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ export const PROPOSAL_FRAGMENT = gql`
|
||||
value
|
||||
party {
|
||||
id
|
||||
stakingSummary {
|
||||
stake {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ export const PROPOSAL_FRAGMENT = gql`
|
||||
value
|
||||
party {
|
||||
id
|
||||
stakingSummary {
|
||||
stake {
|
||||
currentStakeAvailable
|
||||
}
|
||||
}
|
||||
|
||||
+18
-30
@@ -9,22 +9,6 @@ import { ProposalState, ProposalRejectionReason, VoteValue } from "@vegaprotocol
|
||||
// GraphQL query operation: Proposal
|
||||
// ====================================================
|
||||
|
||||
export interface Proposal_proposal_rationale {
|
||||
__typename: "ProposalRationale";
|
||||
/**
|
||||
* Title to be used to give a short description of the proposal in lists.
|
||||
* This is to be between 0 and 100 unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Description to show a short title / something in case the link goes offline.
|
||||
* This is to be between 0 and 20k unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Proposal_proposal_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
@@ -71,6 +55,14 @@ export interface Proposal_proposal_terms_change_NewMarket_instrument {
|
||||
|
||||
export interface Proposal_proposal_terms_change_NewMarket {
|
||||
__typename: "NewMarket";
|
||||
/**
|
||||
* Decimal places used for the new market, sets the smallest price increment on the book
|
||||
*/
|
||||
decimalPlaces: number;
|
||||
/**
|
||||
* Metadata for this instrument, tags
|
||||
*/
|
||||
metadata: string[] | null;
|
||||
/**
|
||||
* New market instrument configuration
|
||||
*/
|
||||
@@ -154,8 +146,8 @@ export interface Proposal_proposal_terms {
|
||||
change: Proposal_proposal_terms_change;
|
||||
}
|
||||
|
||||
export interface Proposal_proposal_votes_yes_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface Proposal_proposal_votes_yes_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
@@ -171,7 +163,7 @@ export interface Proposal_proposal_votes_yes_votes_party {
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: Proposal_proposal_votes_yes_votes_party_stakingSummary;
|
||||
stake: Proposal_proposal_votes_yes_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface Proposal_proposal_votes_yes_votes {
|
||||
@@ -206,8 +198,8 @@ export interface Proposal_proposal_votes_yes {
|
||||
votes: Proposal_proposal_votes_yes_votes[] | null;
|
||||
}
|
||||
|
||||
export interface Proposal_proposal_votes_no_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface Proposal_proposal_votes_no_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
@@ -223,7 +215,7 @@ export interface Proposal_proposal_votes_no_votes_party {
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: Proposal_proposal_votes_no_votes_party_stakingSummary;
|
||||
stake: Proposal_proposal_votes_no_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface Proposal_proposal_votes_no_votes {
|
||||
@@ -276,10 +268,6 @@ export interface Proposal_proposal {
|
||||
* Proposal ID that is filled by Vega once proposal reaches the network
|
||||
*/
|
||||
id: string | null;
|
||||
/**
|
||||
* Rationale behind the proposal
|
||||
*/
|
||||
rationale: Proposal_proposal_rationale;
|
||||
/**
|
||||
* A UUID reference to aid tracking proposals on Vega
|
||||
*/
|
||||
@@ -296,14 +284,14 @@ export interface Proposal_proposal {
|
||||
* Reason for the proposal to be rejected by the core
|
||||
*/
|
||||
rejectionReason: ProposalRejectionReason | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: Proposal_proposal_party;
|
||||
/**
|
||||
* Error details of the rejectionReason
|
||||
*/
|
||||
errorDetails: string | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: Proposal_proposal_party;
|
||||
/**
|
||||
* Terms of the proposal
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export {
|
||||
ProposalContainer,
|
||||
PROPOSAL_QUERY,
|
||||
ProposalContainer as default,
|
||||
} from './proposal-container';
|
||||
|
||||
@@ -4,14 +4,14 @@ import { useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { Proposal } from '../components/proposal';
|
||||
import { PROPOSAL_FRAGMENT } from '../proposal-fragment';
|
||||
import { PROPOSALS_FRAGMENT } from '../proposal-fragment';
|
||||
import type {
|
||||
Proposal as ProposalQueryResult,
|
||||
ProposalVariables,
|
||||
} from './__generated__/Proposal';
|
||||
|
||||
export const PROPOSAL_QUERY = gql`
|
||||
${PROPOSAL_FRAGMENT}
|
||||
${PROPOSALS_FRAGMENT}
|
||||
query Proposal($proposalId: ID!) {
|
||||
proposal(id: $proposalId) {
|
||||
...ProposalFields
|
||||
|
||||
@@ -9,23 +9,7 @@ import { ProposalState, ProposalRejectionReason, VoteValue } from "@vegaprotocol
|
||||
// GraphQL query operation: Proposals
|
||||
// ====================================================
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_rationale {
|
||||
__typename: "ProposalRationale";
|
||||
/**
|
||||
* Title to be used to give a short description of the proposal in lists.
|
||||
* This is to be between 0 and 100 unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Description to show a short title / something in case the link goes offline.
|
||||
* This is to be between 0 and 20k unicode characters.
|
||||
* This is mandatory for all proposals.
|
||||
*/
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_party {
|
||||
export interface Proposals_proposals_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -33,11 +17,11 @@ export interface Proposals_proposalsConnection_edges_node_party {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_UpdateAsset {
|
||||
export interface Proposals_proposals_terms_change_UpdateAsset {
|
||||
__typename: "UpdateAsset" | "NewFreeform";
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument_futureProduct_settlementAsset {
|
||||
export interface Proposals_proposals_terms_change_NewMarket_instrument_futureProduct_settlementAsset {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The symbol of the asset (e.g: GBP)
|
||||
@@ -45,15 +29,15 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket
|
||||
symbol: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument_futureProduct {
|
||||
export interface Proposals_proposals_terms_change_NewMarket_instrument_futureProduct {
|
||||
__typename: "FutureProduct";
|
||||
/**
|
||||
* Product asset ID
|
||||
*/
|
||||
settlementAsset: Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument_futureProduct_settlementAsset;
|
||||
settlementAsset: Proposals_proposals_terms_change_NewMarket_instrument_futureProduct_settlementAsset;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument {
|
||||
export interface Proposals_proposals_terms_change_NewMarket_instrument {
|
||||
__typename: "InstrumentConfiguration";
|
||||
/**
|
||||
* Full and fairly descriptive name for the instrument
|
||||
@@ -66,23 +50,31 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket
|
||||
/**
|
||||
* Future product specification
|
||||
*/
|
||||
futureProduct: Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument_futureProduct | null;
|
||||
futureProduct: Proposals_proposals_terms_change_NewMarket_instrument_futureProduct | null;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewMarket {
|
||||
export interface Proposals_proposals_terms_change_NewMarket {
|
||||
__typename: "NewMarket";
|
||||
/**
|
||||
* Decimal places used for the new market, sets the smallest price increment on the book
|
||||
*/
|
||||
decimalPlaces: number;
|
||||
/**
|
||||
* Metadata for this instrument, tags
|
||||
*/
|
||||
metadata: string[] | null;
|
||||
/**
|
||||
* New market instrument configuration
|
||||
*/
|
||||
instrument: Proposals_proposalsConnection_edges_node_terms_change_NewMarket_instrument;
|
||||
instrument: Proposals_proposals_terms_change_NewMarket_instrument;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_UpdateMarket {
|
||||
export interface Proposals_proposals_terms_change_UpdateMarket {
|
||||
__typename: "UpdateMarket";
|
||||
marketId: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset {
|
||||
export interface Proposals_proposals_terms_change_NewAsset_source_BuiltinAsset {
|
||||
__typename: "BuiltinAsset";
|
||||
/**
|
||||
* Maximum amount that can be requested by a party through the built-in asset faucet at a time
|
||||
@@ -90,7 +82,7 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset_
|
||||
maxFaucetAmountMint: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20 {
|
||||
export interface Proposals_proposals_terms_change_NewAsset_source_ERC20 {
|
||||
__typename: "ERC20";
|
||||
/**
|
||||
* The address of the ERC20 contract
|
||||
@@ -98,9 +90,9 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset_
|
||||
contractAddress: string;
|
||||
}
|
||||
|
||||
export type Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source = Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source_BuiltinAsset | Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source_ERC20;
|
||||
export type Proposals_proposals_terms_change_NewAsset_source = Proposals_proposals_terms_change_NewAsset_source_BuiltinAsset | Proposals_proposals_terms_change_NewAsset_source_ERC20;
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset {
|
||||
export interface Proposals_proposals_terms_change_NewAsset {
|
||||
__typename: "NewAsset";
|
||||
/**
|
||||
* The full name of the asset (e.g: Great British Pound)
|
||||
@@ -113,10 +105,10 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_NewAsset
|
||||
/**
|
||||
* The source of the new asset
|
||||
*/
|
||||
source: Proposals_proposalsConnection_edges_node_terms_change_NewAsset_source;
|
||||
source: Proposals_proposals_terms_change_NewAsset_source;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter {
|
||||
export interface Proposals_proposals_terms_change_UpdateNetworkParameter_networkParameter {
|
||||
__typename: "NetworkParameter";
|
||||
/**
|
||||
* The name of the network parameter
|
||||
@@ -128,14 +120,14 @@ export interface Proposals_proposalsConnection_edges_node_terms_change_UpdateNet
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter {
|
||||
export interface Proposals_proposals_terms_change_UpdateNetworkParameter {
|
||||
__typename: "UpdateNetworkParameter";
|
||||
networkParameter: Proposals_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter_networkParameter;
|
||||
networkParameter: Proposals_proposals_terms_change_UpdateNetworkParameter_networkParameter;
|
||||
}
|
||||
|
||||
export type Proposals_proposalsConnection_edges_node_terms_change = Proposals_proposalsConnection_edges_node_terms_change_UpdateAsset | Proposals_proposalsConnection_edges_node_terms_change_NewMarket | Proposals_proposalsConnection_edges_node_terms_change_UpdateMarket | Proposals_proposalsConnection_edges_node_terms_change_NewAsset | Proposals_proposalsConnection_edges_node_terms_change_UpdateNetworkParameter;
|
||||
export type Proposals_proposals_terms_change = Proposals_proposals_terms_change_UpdateAsset | Proposals_proposals_terms_change_NewMarket | Proposals_proposals_terms_change_UpdateMarket | Proposals_proposals_terms_change_NewAsset | Proposals_proposals_terms_change_UpdateNetworkParameter;
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_terms {
|
||||
export interface Proposals_proposals_terms {
|
||||
__typename: "ProposalTerms";
|
||||
/**
|
||||
* RFC3339Nano time and date when voting closes for this proposal.
|
||||
@@ -151,18 +143,18 @@ export interface Proposals_proposalsConnection_edges_node_terms {
|
||||
/**
|
||||
* Actual change being introduced by the proposal - action the proposal triggers if passed and enacted.
|
||||
*/
|
||||
change: Proposals_proposalsConnection_edges_node_terms_change;
|
||||
change: Proposals_proposals_terms_change;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface Proposals_proposals_votes_yes_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
currentStakeAvailable: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_yes_votes_party {
|
||||
export interface Proposals_proposals_votes_yes_votes_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -171,10 +163,10 @@ export interface Proposals_proposalsConnection_edges_node_votes_yes_votes_party
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: Proposals_proposalsConnection_edges_node_votes_yes_votes_party_stakingSummary;
|
||||
stake: Proposals_proposals_votes_yes_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_yes_votes {
|
||||
export interface Proposals_proposals_votes_yes_votes {
|
||||
__typename: "Vote";
|
||||
/**
|
||||
* The vote value cast
|
||||
@@ -183,14 +175,14 @@ export interface Proposals_proposalsConnection_edges_node_votes_yes_votes {
|
||||
/**
|
||||
* The party casting the vote
|
||||
*/
|
||||
party: Proposals_proposalsConnection_edges_node_votes_yes_votes_party;
|
||||
party: Proposals_proposals_votes_yes_votes_party;
|
||||
/**
|
||||
* RFC3339Nano time and date when the vote reached Vega network
|
||||
*/
|
||||
datetime: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_yes {
|
||||
export interface Proposals_proposals_votes_yes {
|
||||
__typename: "ProposalVoteSide";
|
||||
/**
|
||||
* Total number of governance tokens from the votes cast for this side
|
||||
@@ -203,18 +195,18 @@ export interface Proposals_proposalsConnection_edges_node_votes_yes {
|
||||
/**
|
||||
* All votes cast for this side
|
||||
*/
|
||||
votes: Proposals_proposalsConnection_edges_node_votes_yes_votes[] | null;
|
||||
votes: Proposals_proposals_votes_yes_votes[] | null;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary {
|
||||
__typename: "StakingSummary";
|
||||
export interface Proposals_proposals_votes_no_votes_party_stake {
|
||||
__typename: "PartyStake";
|
||||
/**
|
||||
* The stake currently available for the party
|
||||
*/
|
||||
currentStakeAvailable: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_no_votes_party {
|
||||
export interface Proposals_proposals_votes_no_votes_party {
|
||||
__typename: "Party";
|
||||
/**
|
||||
* Party identifier
|
||||
@@ -223,10 +215,10 @@ export interface Proposals_proposalsConnection_edges_node_votes_no_votes_party {
|
||||
/**
|
||||
* The staking information for this Party
|
||||
*/
|
||||
stakingSummary: Proposals_proposalsConnection_edges_node_votes_no_votes_party_stakingSummary;
|
||||
stake: Proposals_proposals_votes_no_votes_party_stake;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_no_votes {
|
||||
export interface Proposals_proposals_votes_no_votes {
|
||||
__typename: "Vote";
|
||||
/**
|
||||
* The vote value cast
|
||||
@@ -235,14 +227,14 @@ export interface Proposals_proposalsConnection_edges_node_votes_no_votes {
|
||||
/**
|
||||
* The party casting the vote
|
||||
*/
|
||||
party: Proposals_proposalsConnection_edges_node_votes_no_votes_party;
|
||||
party: Proposals_proposals_votes_no_votes_party;
|
||||
/**
|
||||
* RFC3339Nano time and date when the vote reached Vega network
|
||||
*/
|
||||
datetime: string;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes_no {
|
||||
export interface Proposals_proposals_votes_no {
|
||||
__typename: "ProposalVoteSide";
|
||||
/**
|
||||
* Total number of governance tokens from the votes cast for this side
|
||||
@@ -255,31 +247,27 @@ export interface Proposals_proposalsConnection_edges_node_votes_no {
|
||||
/**
|
||||
* All votes cast for this side
|
||||
*/
|
||||
votes: Proposals_proposalsConnection_edges_node_votes_no_votes[] | null;
|
||||
votes: Proposals_proposals_votes_no_votes[] | null;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node_votes {
|
||||
export interface Proposals_proposals_votes {
|
||||
__typename: "ProposalVotes";
|
||||
/**
|
||||
* Yes votes cast for this proposal
|
||||
*/
|
||||
yes: Proposals_proposalsConnection_edges_node_votes_yes;
|
||||
yes: Proposals_proposals_votes_yes;
|
||||
/**
|
||||
* No votes cast for this proposal
|
||||
*/
|
||||
no: Proposals_proposalsConnection_edges_node_votes_no;
|
||||
no: Proposals_proposals_votes_no;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges_node {
|
||||
export interface Proposals_proposals {
|
||||
__typename: "Proposal";
|
||||
/**
|
||||
* Proposal ID that is filled by Vega once proposal reaches the network
|
||||
*/
|
||||
id: string | null;
|
||||
/**
|
||||
* Rationale behind the proposal
|
||||
*/
|
||||
rationale: Proposals_proposalsConnection_edges_node_rationale;
|
||||
/**
|
||||
* A UUID reference to aid tracking proposals on Vega
|
||||
*/
|
||||
@@ -296,43 +284,27 @@ export interface Proposals_proposalsConnection_edges_node {
|
||||
* Reason for the proposal to be rejected by the core
|
||||
*/
|
||||
rejectionReason: ProposalRejectionReason | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: Proposals_proposalsConnection_edges_node_party;
|
||||
/**
|
||||
* Error details of the rejectionReason
|
||||
*/
|
||||
errorDetails: string | null;
|
||||
/**
|
||||
* Party that prepared the proposal
|
||||
*/
|
||||
party: Proposals_proposals_party;
|
||||
/**
|
||||
* Terms of the proposal
|
||||
*/
|
||||
terms: Proposals_proposalsConnection_edges_node_terms;
|
||||
terms: Proposals_proposals_terms;
|
||||
/**
|
||||
* Votes cast for this proposal
|
||||
*/
|
||||
votes: Proposals_proposalsConnection_edges_node_votes;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection_edges {
|
||||
__typename: "ProposalEdge";
|
||||
/**
|
||||
* The proposal data
|
||||
*/
|
||||
node: Proposals_proposalsConnection_edges_node;
|
||||
}
|
||||
|
||||
export interface Proposals_proposalsConnection {
|
||||
__typename: "ProposalsConnection";
|
||||
/**
|
||||
* List of proposals available for the connection
|
||||
*/
|
||||
edges: (Proposals_proposalsConnection_edges | null)[] | null;
|
||||
votes: Proposals_proposals_votes;
|
||||
}
|
||||
|
||||
export interface Proposals {
|
||||
/**
|
||||
* All governance proposals in the Vega network
|
||||
*/
|
||||
proposalsConnection: Proposals_proposalsConnection;
|
||||
proposals: Proposals_proposals[] | null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export {
|
||||
ProposalsContainer,
|
||||
ProposalsContainer as default,
|
||||
PROPOSALS_QUERY,
|
||||
ProposalsContainer as default,
|
||||
} from './proposals-container';
|
||||
|
||||
@@ -1,36 +1,56 @@
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { getNotRejectedProposals } from '@vegaprotocol/governance';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import compact from 'lodash/compact';
|
||||
import filter from 'lodash/filter';
|
||||
import flow from 'lodash/flow';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { SplashLoader } from '../../../components/splash-loader';
|
||||
import { ProposalsList } from '../components/proposals-list';
|
||||
import { PROPOSAL_FRAGMENT } from '../proposal-fragment';
|
||||
import { PROPOSALS_FRAGMENT } from '../proposal-fragment';
|
||||
import type { Proposals } from './__generated__/Proposals';
|
||||
|
||||
export const PROPOSALS_QUERY = gql`
|
||||
${PROPOSAL_FRAGMENT}
|
||||
${PROPOSALS_FRAGMENT}
|
||||
query Proposals {
|
||||
proposalsConnection {
|
||||
edges {
|
||||
node {
|
||||
...ProposalFields
|
||||
}
|
||||
}
|
||||
proposals {
|
||||
...ProposalFields
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const ProposalsContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { data, loading, error } = useQuery<Proposals>(PROPOSALS_QUERY, {
|
||||
const { data, loading, error } = useQuery<Proposals, never>(PROPOSALS_QUERY, {
|
||||
pollInterval: 5000,
|
||||
fetchPolicy: 'network-only',
|
||||
errorPolicy: 'ignore',
|
||||
errorPolicy: 'ignore', // this is to get around some backend issues and should be removed in future
|
||||
});
|
||||
|
||||
const proposals = useMemo(() => getNotRejectedProposals(data), [data]);
|
||||
const proposals = React.useMemo(() => {
|
||||
if (!data?.proposals?.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return flow([
|
||||
compact,
|
||||
(arr) =>
|
||||
filter(arr, ({ state }) => state !== ProposalState.STATE_REJECTED),
|
||||
(arr) =>
|
||||
orderBy(
|
||||
arr,
|
||||
[
|
||||
(p) => new Date(p.terms.enactmentDatetime).getTime(),
|
||||
(p) => new Date(p.terms.closingDatetime).getTime(),
|
||||
(p) => p.id,
|
||||
],
|
||||
['desc', 'desc', 'desc']
|
||||
),
|
||||
])(data.proposals);
|
||||
}, [data]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
|
||||
@@ -1,19 +1,46 @@
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import compact from 'lodash/compact';
|
||||
import filter from 'lodash/filter';
|
||||
import flow from 'lodash/flow';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PROPOSALS_QUERY } from '../proposals';
|
||||
|
||||
import { SplashLoader } from '../../../components/splash-loader';
|
||||
import { RejectedProposalsList } from '../components/proposals-list';
|
||||
import { getRejectedProposals } from '@vegaprotocol/governance';
|
||||
import { PROPOSALS_QUERY } from '../proposals';
|
||||
import type { Proposals } from '../proposals/__generated__/Proposals';
|
||||
import { ProposalState } from '@vegaprotocol/types';
|
||||
|
||||
export const RejectedProposalsContainer = () => {
|
||||
const { t } = useTranslation();
|
||||
const { data, loading, error } = useQuery<Proposals>(PROPOSALS_QUERY);
|
||||
const { data, loading, error } = useQuery<Proposals, never>(PROPOSALS_QUERY, {
|
||||
pollInterval: 5000,
|
||||
errorPolicy: 'ignore', // this is to get around some backend issues and should be removed in future
|
||||
});
|
||||
|
||||
const proposals = useMemo(() => getRejectedProposals(data), [data]);
|
||||
const proposals = React.useMemo(() => {
|
||||
if (!data?.proposals?.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return flow([
|
||||
compact,
|
||||
(arr) =>
|
||||
filter(arr, ({ state }) => state === ProposalState.STATE_REJECTED),
|
||||
(arr) =>
|
||||
orderBy(
|
||||
arr,
|
||||
[
|
||||
(p) => new Date(p.terms.enactmentDatetime).getTime(),
|
||||
(p) => new Date(p.terms.closingDatetime).getTime(),
|
||||
(p) => p.id,
|
||||
],
|
||||
['desc', 'desc', 'desc']
|
||||
),
|
||||
])(data.proposals);
|
||||
}, [data]);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
|
||||
@@ -16,11 +16,6 @@ export function generateProposal(
|
||||
const defaultProposal: ProposalFields = {
|
||||
__typename: 'Proposal',
|
||||
id: faker.datatype.uuid(),
|
||||
rationale: {
|
||||
__typename: 'ProposalRationale',
|
||||
title: '',
|
||||
description: '',
|
||||
},
|
||||
reference: 'ref' + faker.datatype.uuid(),
|
||||
state: ProposalState.STATE_OPEN,
|
||||
datetime: faker.date.past().toISOString(),
|
||||
@@ -89,8 +84,8 @@ export const generateYesVotes = (
|
||||
party: {
|
||||
id: faker.datatype.uuid(),
|
||||
__typename: 'Party',
|
||||
stakingSummary: {
|
||||
__typename: 'StakingSummary',
|
||||
stake: {
|
||||
__typename: 'PartyStake',
|
||||
currentStakeAvailable: fixedTokenValue
|
||||
? fixedTokenValue.toString()
|
||||
: faker.datatype
|
||||
@@ -124,8 +119,8 @@ export const generateNoVotes = (
|
||||
party: {
|
||||
id: faker.datatype.uuid(),
|
||||
__typename: 'Party',
|
||||
stakingSummary: {
|
||||
__typename: 'StakingSummary',
|
||||
stake: {
|
||||
__typename: 'PartyStake',
|
||||
currentStakeAvailable: fixedTokenValue
|
||||
? fixedTokenValue.toString()
|
||||
: faker.datatype
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { Button, Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { formatDistance } from 'date-fns';
|
||||
// @ts-ignore No types available for duration-js
|
||||
// @ts-ignore No types availabel for duration-js
|
||||
import Duration from 'duration-js';
|
||||
import gql from 'graphql-tag';
|
||||
import React from 'react';
|
||||
@@ -15,10 +15,10 @@ import {
|
||||
AppStateActionType,
|
||||
useAppState,
|
||||
} from '../../../contexts/app-state/app-state-context';
|
||||
import { useNetworkParam } from '../../../hooks/use-network-param';
|
||||
import type { Rewards } from './__generated__/Rewards';
|
||||
import { RewardInfo } from './reward-info';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useNetworkParams } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const REWARDS_QUERY = gql`
|
||||
query Rewards($partyId: ID!) {
|
||||
@@ -77,7 +77,7 @@ export const RewardsIndex = () => {
|
||||
data: rewardAssetData,
|
||||
loading: rewardAssetLoading,
|
||||
error: rewardAssetError,
|
||||
} = useNetworkParams([
|
||||
} = useNetworkParam([
|
||||
NetworkParams.REWARD_ASSET,
|
||||
NetworkParams.REWARD_PAYOUT_DURATION,
|
||||
]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schema as Types } from '@vegaprotocol/types';
|
||||
import * as Types from '@vegaprotocol/types/types';
|
||||
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { TokenInput } from '../../components/token-input';
|
||||
import { NetworkParams } from '../../config';
|
||||
import { useAppState } from '../../contexts/app-state/app-state-context';
|
||||
import { useNetworkParam } from '../../hooks/use-network-param';
|
||||
import { useSearchParams } from '../../hooks/use-search-params';
|
||||
import { BigNumber } from '../../lib/bignumber';
|
||||
import { addDecimal, removeDecimal } from '../../lib/decimals';
|
||||
@@ -30,7 +31,6 @@ import type {
|
||||
UndelegateSubmissionBody,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useNetworkParam } from '@vegaprotocol/react-helpers';
|
||||
|
||||
export const PARTY_DELEGATIONS_QUERY = gql`
|
||||
query PartyDelegations($partyId: ID!) {
|
||||
@@ -103,9 +103,9 @@ export const StakingForm = ({
|
||||
setAmount('');
|
||||
}, [action, setAmount]);
|
||||
|
||||
const { data } = useNetworkParam(
|
||||
NetworkParams.VALIDATOR_DELEGATION_MIN_AMOUNT
|
||||
);
|
||||
const { data } = useNetworkParam([
|
||||
NetworkParams.VALIDATOR_DELEGATION_MIN_AMOUNT,
|
||||
]);
|
||||
|
||||
const minTokensWithDecimals = React.useMemo(() => {
|
||||
const minTokens = new BigNumber(data && data.length === 1 ? data[0] : '');
|
||||
|
||||
@@ -3,28 +3,28 @@ import { generateDepositPage } from '../support/mocks/generate-deposit-page';
|
||||
import { generateNetworkParameters } from '../support/mocks/generate-network-parameters';
|
||||
|
||||
const connectEthWalletBtn = 'connect-eth-wallet-btn';
|
||||
const assetSelectField = 'select[name="asset"]';
|
||||
const toAddressField = 'input[name="to"]';
|
||||
const amountField = 'input[name="amount"]';
|
||||
const formFieldError = 'input-error-text';
|
||||
|
||||
describe('deposit form validation', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'NetworkParamsQuery', generateNetworkParameters());
|
||||
aliasQuery(req, 'DepositPage', generateDepositPage());
|
||||
aliasQuery(req, 'AssetsConnection', generateDepositPage());
|
||||
});
|
||||
cy.visit('/portfolio/deposit');
|
||||
|
||||
cy.wait('@AssetsConnection');
|
||||
// Deposit page requires connection Ethereum wallet first
|
||||
cy.getByTestId(connectEthWalletBtn).click();
|
||||
cy.getByTestId('web3-connector-MetaMask').click();
|
||||
|
||||
cy.wait('@DepositPage');
|
||||
});
|
||||
|
||||
it('handles empty fields', () => {
|
||||
const assetSelectField = 'select[name="asset"]';
|
||||
const toAddressField = 'input[name="to"]';
|
||||
const amountField = 'input[name="amount"]';
|
||||
const formFieldError = 'input-error-text';
|
||||
|
||||
// Submit form to trigger any empty validaion messages
|
||||
cy.getByTestId('deposit-submit').click();
|
||||
|
||||
@@ -56,14 +56,6 @@ describe('deposit form validation', () => {
|
||||
.should('have.text', 'Insufficient amount in Ethereum wallet');
|
||||
});
|
||||
|
||||
it('unable to select assets not enabled', () => {
|
||||
cy.getByTestId('deposit-submit').click();
|
||||
// Assets not enabled in mocks
|
||||
cy.get(assetSelectField + ' option:contains(Asset 2)').should('not.exist');
|
||||
cy.get(assetSelectField + ' option:contains(Asset 3)').should('not.exist');
|
||||
cy.get(assetSelectField + ' option:contains(Asset 4)').should('not.exist');
|
||||
});
|
||||
|
||||
it('able to disconnect eth wallet', () => {
|
||||
const ethWalletAddress = Cypress.env('ETHEREUM_WALLET_ADDRESS');
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user