Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
917c452116 | ||
|
|
166c9b6fb9 | ||
|
|
8dd63d7cac | ||
|
|
8bffc05be2 | ||
|
|
26e3596c5a | ||
|
|
6ad68f87cc | ||
|
|
86fdd75d6c | ||
|
|
f688b28b29 | ||
|
|
6ddceaf6bd | ||
|
|
a9e8b6915e | ||
|
|
9318dab698 | ||
|
|
ae0424e21a | ||
|
|
5e484dfab0 | ||
|
|
e5b1390302 | ||
|
|
6a6779ee72 | ||
|
|
414b8ced13 | ||
|
|
e310f04034 | ||
|
|
adf6059701 | ||
|
|
5dda58334e | ||
|
|
3b03b16938 | ||
|
|
0d8c052ec6 | ||
|
|
9836f29e15 | ||
|
|
4d69dceaa7 | ||
|
|
6af189150b | ||
|
|
6f20c9125d | ||
|
|
7c6b14f73a | ||
|
|
0fa1f47ad5 | ||
|
|
c4468d507b | ||
|
|
191e73335e | ||
|
|
dae8949b46 | ||
|
|
3aca9207ed | ||
|
|
69db3fdecb | ||
|
|
d9a747102d | ||
|
|
3f6bd066f1 | ||
|
|
195e234f16 | ||
|
|
b505a0598d | ||
|
|
f87fd676f6 | ||
|
|
b885696659 | ||
|
|
5d553271a5 | ||
|
|
87f7efd960 | ||
|
|
d9e3b9de99 | ||
|
|
b5e2513d53 | ||
|
|
ba27f9e738 | ||
|
|
22787bd4c4 | ||
|
|
c5eeead356 | ||
|
|
612b906cb4 | ||
|
|
94a2de859f | ||
|
|
f287dced18 | ||
|
|
3beb43a719 | ||
|
|
da807c883d | ||
|
|
5a842c9be9 | ||
|
|
3bec65ac67 | ||
|
|
f124275ce5 | ||
|
|
d271f28b82 | ||
|
|
483cf05050 | ||
|
|
a452a6e831 | ||
|
|
ebf2bfc7a9 | ||
|
|
d60cf3e5e6 | ||
|
|
2650329a31 | ||
|
|
4ef8218267 | ||
|
|
e3254564ae | ||
|
|
7effa0791c | ||
|
|
93108c5b48 | ||
|
|
06a2fc4d12 | ||
|
|
c274a4694a |
@@ -24,10 +24,10 @@ on:
|
||||
jobs:
|
||||
manual:
|
||||
name: Run capsule tests -- manual trigger
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: self-hosted
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
GOPROXY: ${{ secrets.GO_PROXY }}
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
steps:
|
||||
#######
|
||||
## Setup langs
|
||||
@@ -43,6 +43,12 @@ jobs:
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
#######
|
||||
## Install Yarn
|
||||
#######
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
#######
|
||||
## Checkout repos
|
||||
#######
|
||||
@@ -70,18 +76,18 @@ jobs:
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './capsule'
|
||||
|
||||
# Checkout vega
|
||||
- name: Checkout Vega
|
||||
uses: actions/checkout@v2
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.54.0
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
#######
|
||||
@@ -97,17 +103,20 @@ jobs:
|
||||
|
||||
- name: Install Vega binaries
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: go install -v ./cmd/vega
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vega-linux-amd64.zip'
|
||||
unzip vega-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install date-node binaries
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: go install ./cmd/data-node
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/data-node-linux-amd64.zip'
|
||||
unzip data-node-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install Vega wallet binaries
|
||||
run: go install ./cmd/vegawallet
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vegawallet-linux-amd64.zip'
|
||||
unzip vegawallet-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
######
|
||||
## Start capsule
|
||||
@@ -149,20 +158,21 @@ jobs:
|
||||
run: vegawallet service run --network fairground --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
- name: Start service using capsule network
|
||||
if: ${{ env.RUN_CAPSULE==true }}
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
######
|
||||
## Run some tests
|
||||
######
|
||||
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run smoke Cypress tests
|
||||
if: ${{ github.event.inputs.runAlltests == 'true' }}
|
||||
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.grepTags='@smoke'
|
||||
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.grepTags='@smoke' --browser chrome
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
@@ -172,7 +182,7 @@ jobs:
|
||||
|
||||
- name: Run Cypress tests
|
||||
if: ${{ github.event.inputs.runAlltests == 'false' }}
|
||||
run: yarn nx run ${{ github.event.inputs.project }}:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
run: yarn nx run ${{ github.event.inputs.project }}: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 }}
|
||||
@@ -185,11 +195,11 @@ jobs:
|
||||
######
|
||||
|
||||
- name: Logs
|
||||
if: ${{ env.RUN_CAPSULE==true }}
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ env.RUN_CAPSULE==true }}
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
with:
|
||||
name: logs
|
||||
path: ./vega-capsule-logs.txt
|
||||
|
||||
@@ -9,9 +9,10 @@ on:
|
||||
jobs:
|
||||
nightly:
|
||||
name: Run capsule tests -- nightly
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: self-hosted
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
steps:
|
||||
#######
|
||||
## Setup langs
|
||||
@@ -28,7 +29,13 @@ jobs:
|
||||
node-version: 16
|
||||
|
||||
#######
|
||||
## Checkout capsule
|
||||
## Install Yarn
|
||||
#######
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
#######
|
||||
## Checkout repos
|
||||
#######
|
||||
|
||||
# Checkout front ends
|
||||
@@ -48,6 +55,20 @@ jobs:
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './capsule'
|
||||
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
#######
|
||||
## Build binaries
|
||||
#######
|
||||
@@ -58,25 +79,20 @@ jobs:
|
||||
- name: Set GOBIN
|
||||
run: echo GOBIN=$(go env GOPATH)/bin >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout Vega
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.55.0
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
|
||||
- name: Install Vega binaries
|
||||
run: go install -v ./cmd/vega
|
||||
working-directory: vega
|
||||
|
||||
- name: Install Vega wallet binaries
|
||||
run: go install ./cmd/vegawallet
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vega-linux-amd64.zip'
|
||||
unzip vega-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install date-node binaries
|
||||
run: go install ./cmd/data-node
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/data-node-linux-amd64.zip'
|
||||
unzip data-node-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install Vega wallet binaries
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vegawallet-linux-amd64.zip'
|
||||
unzip vegawallet-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
######
|
||||
## Start capsule
|
||||
@@ -112,12 +128,13 @@ jobs:
|
||||
## Run some tests
|
||||
######
|
||||
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: yarn nx run-many --target=e2e --all --record --key ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||
run: yarn nx run-many --target=e2e --all --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 }}
|
||||
@@ -131,7 +148,6 @@ jobs:
|
||||
######
|
||||
|
||||
- name: Logs
|
||||
if: ${{ always() }}
|
||||
run: vegacapsule network logs > vega-capsule-logs.txt
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
|
||||
@@ -3,8 +3,8 @@ name: Capsule tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
@@ -15,10 +15,10 @@ on:
|
||||
jobs:
|
||||
pr:
|
||||
name: Run capsule tests - PR
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.draft == false }}
|
||||
runs-on: self-hosted
|
||||
env:
|
||||
GO111MODULE: 'on'
|
||||
VEGA_VERSION: 'v0.57.0'
|
||||
steps:
|
||||
#######
|
||||
## Setup langs
|
||||
@@ -34,6 +34,12 @@ jobs:
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
#######
|
||||
## Install Yarn
|
||||
#######
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
#######
|
||||
## Checkout repos
|
||||
#######
|
||||
@@ -46,27 +52,18 @@ jobs:
|
||||
fetch-depth: 0
|
||||
path: './frontend-monorepo'
|
||||
|
||||
# Checkout capsule to build local network
|
||||
- name: Checkout capsule
|
||||
uses: actions/checkout@v2
|
||||
# Restore node_modules from cache if possible
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
repository: vegaprotocol/vegacapsule
|
||||
ref: main
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './capsule'
|
||||
|
||||
# Checkout vega
|
||||
- name: Checkout Vega
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vega
|
||||
ref: v0.54.0
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './vega'
|
||||
path: |
|
||||
frontend-monorepo/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
key: node_modules_cypress-${{ hashFiles('frontend-monorepo/yarn.lock') }}
|
||||
|
||||
# Install frontend dependencies
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
run: yarn install --frozen-lockfile
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
# See affected apps to see if building all binaries is necessary
|
||||
@@ -78,6 +75,16 @@ jobs:
|
||||
if: ${{ contains(env.AFFECTED, 'token') || contains(env.AFFECTED, 'token-e2e') || contains(env.AFFECTED, 'explorer') || contains(env.AFFECTED, 'explorer-e2e') }}
|
||||
run: echo RUN_CAPSULE=true >> $GITHUB_ENV
|
||||
|
||||
# Checkout capsule to build local network
|
||||
- name: Checkout capsule
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: vegaprotocol/vegacapsule
|
||||
ref: main
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
path: './capsule'
|
||||
|
||||
#######
|
||||
## Build binaries
|
||||
#######
|
||||
@@ -91,17 +98,20 @@ jobs:
|
||||
|
||||
- name: Install Vega binaries
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: go install -v ./cmd/vega
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vega-linux-amd64.zip'
|
||||
unzip vega-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install date-node binaries
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: go install ./cmd/data-node
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/data-node-linux-amd64.zip'
|
||||
unzip data-node-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
- name: Install Vega wallet binaries
|
||||
run: go install ./cmd/vegawallet
|
||||
working-directory: vega
|
||||
run: |
|
||||
wget 'https://github.com/vegaprotocol/vega/releases/download/${{ env.VEGA_VERSION }}/vegawallet-linux-amd64.zip'
|
||||
unzip vegawallet-linux-amd64.zip -d ${{ env.GOBIN }}
|
||||
|
||||
######
|
||||
## Start capsule
|
||||
@@ -143,7 +153,7 @@ jobs:
|
||||
run: vegawallet service run --network fairground --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
- name: Start service using capsule network
|
||||
if: ${{ env.RUN_CAPSULE==true }}
|
||||
if: ${{ env.RUN_CAPSULE }}
|
||||
run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
|
||||
|
||||
######
|
||||
@@ -156,8 +166,13 @@ jobs:
|
||||
working-directory: frontend-monorepo
|
||||
main-branch-name: ${{github.base_ref}}
|
||||
|
||||
# To make sure that all Cypress binaries are installed properly
|
||||
- name: Install cypress bins
|
||||
run: yarn cypress install
|
||||
working-directory: frontend-monorepo
|
||||
|
||||
- name: Run Cypress tests
|
||||
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.grepTags='@smoke'
|
||||
run: npx nx affected:e2e --record --key ${{ secrets.CYPRESS_RECORD_KEY }} --env.grepTags='@smoke' --browser chrome
|
||||
working-directory: frontend-monorepo
|
||||
env:
|
||||
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
|
||||
|
||||
@@ -3,50 +3,16 @@ name: Unit tests & build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
master:
|
||||
name: Test and lint - main
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: 'read'
|
||||
actions: 'read'
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
fetch-depth: 0
|
||||
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||
uses: nrwl/nx-set-shas@v2
|
||||
with:
|
||||
main-branch-name: master
|
||||
- name: Use Node.js 16
|
||||
id: Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.14.0
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
- name: Check formatting
|
||||
run: yarn nx format:check
|
||||
- name: Lint affected
|
||||
run: yarn nx affected:lint --max-warnings=0
|
||||
- name: Test affected
|
||||
run: yarn nx affected:test
|
||||
- name: Build affected
|
||||
run: yarn nx affected:build
|
||||
pr:
|
||||
name: Test and lint - PR
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: 'read'
|
||||
actions: 'read'
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -55,14 +21,19 @@ jobs:
|
||||
- name: Derive appropriate SHAs for base and head for `nx affected` commands
|
||||
uses: nrwl/nx-set-shas@v2
|
||||
with:
|
||||
main-branch-name: develop
|
||||
main-branch-name: ${{ github.base_ref }}
|
||||
- name: Use Node.js 16
|
||||
id: Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16.14.0
|
||||
- name: Restore node_modules from cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: node_modules-${{ hashFiles('**/yarn.lock') }}
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
run: yarn install --frozen-lockfile
|
||||
- name: Check formatting
|
||||
run: yarn nx format:check
|
||||
- name: Lint affected
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('market selector', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'Markets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'MarketsCandlesQuery', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsDataQuery', generateMarketsData());
|
||||
aliasQuery(req, 'DealTicketQuery', generateDealTicket());
|
||||
aliasQuery(req, 'DealTicket', generateDealTicket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('Market trade', { tags: '@smoke' }, () => {
|
||||
aliasQuery(req, 'MarketsCandlesQuery', generateMarketsCandles());
|
||||
aliasQuery(req, 'MarketsDataQuery', generateMarketsData());
|
||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||
aliasQuery(req, 'DealTicketQuery', generateDealTicket());
|
||||
aliasQuery(req, 'DealTicket', generateDealTicket());
|
||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||
aliasQuery(req, 'MarketPositions', generateMarketPositions());
|
||||
aliasQuery(req, 'EstimateOrder', generateEstimateOrder());
|
||||
|
||||
@@ -3,7 +3,10 @@ import {
|
||||
disconnectVegaWallet,
|
||||
} from '../support/connect-wallet';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { generatePositions } from '../support/mocks/generate-positions';
|
||||
import {
|
||||
generatePositions,
|
||||
emptyPositions,
|
||||
} from '../support/mocks/generate-positions';
|
||||
import { generateAccounts } from '../support/mocks/generate-accounts';
|
||||
import { generateOrders } from '../support/mocks/generate-orders';
|
||||
import { generateFills } from '../support/mocks/generate-fills';
|
||||
@@ -112,4 +115,42 @@ describe('Portfolio page', { tags: '@smoke' }, () => {
|
||||
cy.get('.ag-center-cols-container .ag-row').should('have.length', 4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Empty views', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Positions', emptyPositions());
|
||||
aliasQuery(req, 'Accounts', { party: null });
|
||||
aliasQuery(req, 'Orders', { party: null });
|
||||
aliasQuery(req, 'Fills', { party: null });
|
||||
aliasQuery(req, 'Markets', {
|
||||
marketsConnection: { edges: [], __typename: 'MarketConnection' },
|
||||
});
|
||||
});
|
||||
cy.visit('/portfolio');
|
||||
connectVegaWallet();
|
||||
});
|
||||
|
||||
it('"No data to display" should be always displayed', () => {
|
||||
cy.getByTestId('assets').click();
|
||||
cy.get('div.flex.items-center.justify-center').contains(
|
||||
'No data to display'
|
||||
);
|
||||
|
||||
cy.getByTestId('positions').click();
|
||||
cy.get('div.flex.items-center.justify-center').contains(
|
||||
'No data to display'
|
||||
);
|
||||
|
||||
cy.getByTestId('orders').click();
|
||||
cy.get('div.flex.items-center.justify-center').contains(
|
||||
'No data to display'
|
||||
);
|
||||
|
||||
cy.getByTestId('fills').click();
|
||||
cy.get('div.flex.items-center.justify-center').contains(
|
||||
'No data to display'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import type {
|
||||
Fills,
|
||||
Fills_party_tradesConnection_edges_node,
|
||||
} from '@vegaprotocol/fills';
|
||||
import type { FillsQuery, FillFieldsFragment } from '@vegaprotocol/fills';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import merge from 'lodash/merge';
|
||||
import type { PartialDeep } from 'type-fest';
|
||||
|
||||
export const generateFills = (override?: PartialDeep<Fills>): Fills => {
|
||||
const fills: Fills_party_tradesConnection_edges_node[] = [
|
||||
export const generateFills = (
|
||||
override?: PartialDeep<FillsQuery>
|
||||
): FillsQuery => {
|
||||
const fills: FillFieldsFragment[] = [
|
||||
generateFill({
|
||||
buyer: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
@@ -45,7 +44,7 @@ export const generateFills = (override?: PartialDeep<Fills>): Fills => {
|
||||
}),
|
||||
];
|
||||
|
||||
const defaultResult: Fills = {
|
||||
const defaultResult: FillsQuery = {
|
||||
party: {
|
||||
id: 'buyer-id',
|
||||
tradesConnection: {
|
||||
@@ -72,10 +71,8 @@ export const generateFills = (override?: PartialDeep<Fills>): Fills => {
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const generateFill = (
|
||||
override?: PartialDeep<Fills_party_tradesConnection_edges_node>
|
||||
) => {
|
||||
const defaultFill: Fills_party_tradesConnection_edges_node = {
|
||||
export const generateFill = (override?: PartialDeep<FillFieldsFragment>) => {
|
||||
const defaultFill: FillFieldsFragment = {
|
||||
__typename: 'Trade',
|
||||
id: '0',
|
||||
createdAt: new Date().toISOString(),
|
||||
|
||||
@@ -189,3 +189,13 @@ export const generatePositions = (
|
||||
|
||||
return merge(defaultResult, override);
|
||||
};
|
||||
|
||||
export const emptyPositions = () => {
|
||||
return {
|
||||
party: {
|
||||
id: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||
positionsConnection: { edges: null, __typename: 'PositionConnection' },
|
||||
__typename: 'Party',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
|
||||
NX_VEGA_URL=https://api.n12.testnet.vega.xyz/graphql
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_NETWORKS='{\"MAINNET\":\"https://alpha.console.vega.xyz\"}'
|
||||
NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
import {
|
||||
VegaConnectDialog,
|
||||
@@ -18,8 +16,7 @@ import LocalContext from './context/local-context';
|
||||
import useLocalValues from './hooks/use-local-values';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const localValues = useLocalValues(theme, toggleTheme);
|
||||
const localValues = useLocalValues();
|
||||
const {
|
||||
vegaWalletDialog,
|
||||
menu: { setMenuOpen },
|
||||
@@ -32,29 +29,27 @@ function App() {
|
||||
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWalletDialog.connect}
|
||||
setDialogOpen={vegaWalletDialog.setConnect}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</LocalContext.Provider>
|
||||
</VegaWalletProvider>
|
||||
</NetworkLoader>
|
||||
</ThemeContext.Provider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||
<Header />
|
||||
<Main />
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWalletDialog.connect}
|
||||
setDialogOpen={vegaWalletDialog.setConnect}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWalletDialog.manage}
|
||||
setDialogOpen={vegaWalletDialog.setManage}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</LocalContext.Provider>
|
||||
</VegaWalletProvider>
|
||||
</NetworkLoader>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
import React, {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
useContext,
|
||||
useMemo,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import React, { forwardRef, useCallback, useMemo, useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
t,
|
||||
ThemeContext,
|
||||
useScreenDimensions,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useScreenDimensions, useTheme } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
GridOptions,
|
||||
GetRowIdParams,
|
||||
TabToNextCellParams,
|
||||
CellKeyDownEvent,
|
||||
FullWidthCellKeyDownEvent,
|
||||
IGetRowsParams,
|
||||
IDatasource,
|
||||
} from 'ag-grid-community';
|
||||
import { NO_DATA_MESSAGE } from '../../constants';
|
||||
import * as constants from '../simple-market-list/constants';
|
||||
|
||||
export interface GetRowsParams<T>
|
||||
extends Omit<IGetRowsParams, 'successCallback'> {
|
||||
successCallback(rowsThisBlock: T[], lastRow?: number): void;
|
||||
}
|
||||
|
||||
export interface Datasource<T> extends IDatasource {
|
||||
getRows(params: GetRowsParams<T>): void;
|
||||
}
|
||||
interface Props<T> extends GridOptions {
|
||||
data?: T[];
|
||||
rowData?: T[];
|
||||
datasource?: Datasource<T>;
|
||||
handleRowClicked?: (event: { data: T }) => void;
|
||||
components?: Record<string, unknown>;
|
||||
classNamesParam?: string | string[];
|
||||
}
|
||||
|
||||
const ConsoleLiteGrid = <T extends { id?: string }>(
|
||||
{ data, handleRowClicked, getRowId, classNamesParam, ...props }: Props<T>,
|
||||
{ handleRowClicked, getRowId, classNamesParam, ...props }: Props<T>,
|
||||
ref?: React.Ref<AgGridReact>
|
||||
) => {
|
||||
const { isMobile, screenSize } = useScreenDimensions();
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const theme = useContext(ThemeContext);
|
||||
const { theme } = useTheme();
|
||||
const handleOnGridReady = useCallback(() => {
|
||||
(
|
||||
(ref as React.RefObject<AgGridReact>) || gridRef
|
||||
@@ -73,7 +75,6 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
|
||||
return (
|
||||
<AgGrid
|
||||
className={classNames(classNamesParam)}
|
||||
rowData={data}
|
||||
rowHeight={60}
|
||||
customThemeParams={
|
||||
theme === 'dark'
|
||||
@@ -85,7 +86,7 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
|
||||
rowClass={isMobile ? 'mobile' : ''}
|
||||
rowClassRules={constants.ROW_CLASS_RULES}
|
||||
ref={ref || gridRef}
|
||||
overlayNoRowsTemplate={t('No data to display')}
|
||||
overlayNoRowsTemplate={NO_DATA_MESSAGE}
|
||||
suppressContextMenu
|
||||
getRowId={getRowId || getRowIdLocal}
|
||||
suppressMovableColumns
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery_party_accounts } from './__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from '../../hooks/use-settlement-account';
|
||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||
import { AccountType } from '@vegaprotocol/types';
|
||||
|
||||
interface DealTicketBalanceProps {
|
||||
settlementAsset: DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset;
|
||||
settlementAsset: DealTicketMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset'];
|
||||
accounts: PartyBalanceQuery_party_accounts[];
|
||||
isWalletConnected: boolean;
|
||||
className?: string;
|
||||
|
||||
@@ -52,6 +52,10 @@ export const DealTicketContainer = () => {
|
||||
const container = marketId ? (
|
||||
<Container marketId={marketId}>
|
||||
{(data) => {
|
||||
if (!data.market) {
|
||||
return null as unknown as JSX.Element;
|
||||
}
|
||||
|
||||
const balance = (
|
||||
<DealTicketBalance
|
||||
className="mb-4"
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { Stepper } from '../stepper';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { InputError } from '@vegaprotocol/ui-toolkit';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import { MarketSelector } from '@vegaprotocol/deal-ticket';
|
||||
@@ -37,7 +37,7 @@ import { Side, OrderType } from '@vegaprotocol/types';
|
||||
import { DealTicketSlippage } from './deal-ticket-slippage';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
market: DealTicketQuery_market;
|
||||
market: DealTicketMarketFragment;
|
||||
partyData?: PartyBalanceQuery;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import { SIDE_NAMES } from './side-selector';
|
||||
import SimpleMarketExpires from '../simple-market-list/simple-market-expires';
|
||||
@@ -33,7 +33,7 @@ export const MARKET_TAGS_QUERY = gql`
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
market: DealTicketQuery_market;
|
||||
market: DealTicketMarketFragment;
|
||||
isDisabled: boolean;
|
||||
transactionStatus?: string;
|
||||
order: Order;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
query Deposits {
|
||||
query DepositAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
|
||||
+15
-12
@@ -6,14 +6,14 @@
|
||||
import { AssetStatus } from "@vegaprotocol/types";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: Deposits
|
||||
// GraphQL query operation: DepositAssets
|
||||
// ====================================================
|
||||
|
||||
export interface Deposits_assetsConnection_edges_node_source_BuiltinAsset {
|
||||
export interface DepositAssets_assetsConnection_edges_node_source_BuiltinAsset {
|
||||
__typename: "BuiltinAsset";
|
||||
}
|
||||
|
||||
export interface Deposits_assetsConnection_edges_node_source_ERC20 {
|
||||
export interface DepositAssets_assetsConnection_edges_node_source_ERC20 {
|
||||
__typename: "ERC20";
|
||||
/**
|
||||
* The address of the ERC20 contract
|
||||
@@ -21,9 +21,9 @@ export interface Deposits_assetsConnection_edges_node_source_ERC20 {
|
||||
contractAddress: string;
|
||||
}
|
||||
|
||||
export type Deposits_assetsConnection_edges_node_source = Deposits_assetsConnection_edges_node_source_BuiltinAsset | Deposits_assetsConnection_edges_node_source_ERC20;
|
||||
export type DepositAssets_assetsConnection_edges_node_source = DepositAssets_assetsConnection_edges_node_source_BuiltinAsset | DepositAssets_assetsConnection_edges_node_source_ERC20;
|
||||
|
||||
export interface Deposits_assetsConnection_edges_node {
|
||||
export interface DepositAssets_assetsConnection_edges_node {
|
||||
__typename: "Asset";
|
||||
/**
|
||||
* The ID of the asset
|
||||
@@ -48,25 +48,28 @@ export interface Deposits_assetsConnection_edges_node {
|
||||
/**
|
||||
* The origin source of the asset (e.g: an ERC20 asset)
|
||||
*/
|
||||
source: Deposits_assetsConnection_edges_node_source;
|
||||
source: DepositAssets_assetsConnection_edges_node_source;
|
||||
}
|
||||
|
||||
export interface Deposits_assetsConnection_edges {
|
||||
export interface DepositAssets_assetsConnection_edges {
|
||||
__typename: "AssetEdge";
|
||||
node: Deposits_assetsConnection_edges_node;
|
||||
/**
|
||||
* The asset information
|
||||
*/
|
||||
node: DepositAssets_assetsConnection_edges_node;
|
||||
}
|
||||
|
||||
export interface Deposits_assetsConnection {
|
||||
export interface DepositAssets_assetsConnection {
|
||||
__typename: "AssetsConnection";
|
||||
/**
|
||||
* The assets
|
||||
*/
|
||||
edges: (Deposits_assetsConnection_edges | null)[] | null;
|
||||
edges: (DepositAssets_assetsConnection_edges | null)[] | null;
|
||||
}
|
||||
|
||||
export interface Deposits {
|
||||
export interface DepositAssets {
|
||||
/**
|
||||
* The list of all assets in use in the Vega network or the specified asset if ID is provided
|
||||
*/
|
||||
assetsConnection: Deposits_assetsConnection | null;
|
||||
assetsConnection: DepositAssets_assetsConnection | null;
|
||||
}
|
||||
@@ -3,14 +3,14 @@ import { Schema as Types } from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type DepositsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
export type DepositAssetsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type DepositsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } } | null> | null } | null };
|
||||
export type DepositAssetsQuery = { __typename?: 'Query', assetsConnection?: { __typename?: 'AssetsConnection', edges?: Array<{ __typename?: 'AssetEdge', node: { __typename?: 'Asset', id: string, name: string, symbol: string, decimals: number, source: { __typename?: 'BuiltinAsset' } | { __typename?: 'ERC20', contractAddress: string } } } | null> | null } | null };
|
||||
|
||||
|
||||
export const DepositsDocument = gql`
|
||||
query Deposits {
|
||||
export const DepositAssetsDocument = gql`
|
||||
query DepositAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
@@ -30,28 +30,28 @@ export const DepositsDocument = gql`
|
||||
`;
|
||||
|
||||
/**
|
||||
* __useDepositsQuery__
|
||||
* __useDepositAssetsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useDepositsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useDepositsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* To run a query within a React component, call `useDepositAssetsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useDepositAssetsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useDepositsQuery({
|
||||
* const { data, loading, error } = useDepositAssetsQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useDepositsQuery(baseOptions?: Apollo.QueryHookOptions<DepositsQuery, DepositsQueryVariables>) {
|
||||
export function useDepositAssetsQuery(baseOptions?: Apollo.QueryHookOptions<DepositAssetsQuery, DepositAssetsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<DepositsQuery, DepositsQueryVariables>(DepositsDocument, options);
|
||||
return Apollo.useQuery<DepositAssetsQuery, DepositAssetsQueryVariables>(DepositAssetsDocument, options);
|
||||
}
|
||||
export function useDepositsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<DepositsQuery, DepositsQueryVariables>) {
|
||||
export function useDepositAssetsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<DepositAssetsQuery, DepositAssetsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<DepositsQuery, DepositsQueryVariables>(DepositsDocument, options);
|
||||
return Apollo.useLazyQuery<DepositAssetsQuery, DepositAssetsQueryVariables>(DepositAssetsDocument, options);
|
||||
}
|
||||
export type DepositsQueryHookResult = ReturnType<typeof useDepositsQuery>;
|
||||
export type DepositsLazyQueryHookResult = ReturnType<typeof useDepositsLazyQuery>;
|
||||
export type DepositsQueryResult = Apollo.QueryResult<DepositsQuery, DepositsQueryVariables>;
|
||||
export type DepositAssetsQueryHookResult = ReturnType<typeof useDepositAssetsQuery>;
|
||||
export type DepositAssetsLazyQueryHookResult = ReturnType<typeof useDepositAssetsLazyQuery>;
|
||||
export type DepositAssetsQueryResult = Apollo.QueryResult<DepositAssetsQuery, DepositAssetsQueryVariables>;
|
||||
@@ -5,10 +5,10 @@ import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { Web3Container } from '@vegaprotocol/web3';
|
||||
import type { Deposits } from './__generated__/Deposits';
|
||||
import type { DepositAssets } from './__generated__/DepositAssets';
|
||||
|
||||
const DEPOSITS_QUERY = gql`
|
||||
query Deposits {
|
||||
query DepositAssets {
|
||||
assetsConnection {
|
||||
edges {
|
||||
node {
|
||||
@@ -35,7 +35,7 @@ export const DepositContainer = () => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const { keypair } = useVegaWallet();
|
||||
|
||||
const { data, loading, error } = useQuery<Deposits>(DEPOSITS_QUERY, {
|
||||
const { data, loading, error } = useQuery<DepositAssets>(DEPOSITS_QUERY, {
|
||||
variables: { partyId: keypair?.pub },
|
||||
skip: !keypair?.pub,
|
||||
});
|
||||
@@ -43,7 +43,7 @@ export const DepositContainer = () => {
|
||||
const assets = getEnabledAssets(data);
|
||||
|
||||
return (
|
||||
<AsyncRenderer<Deposits> data={data} loading={loading} error={error}>
|
||||
<AsyncRenderer<DepositAssets> data={data} loading={loading} error={error}>
|
||||
{assets.length ? (
|
||||
<Web3Container>
|
||||
<DepositManager
|
||||
|
||||
@@ -12,7 +12,7 @@ const Header = () => {
|
||||
} = useContext(LocalContext);
|
||||
return (
|
||||
<div
|
||||
className="flex items-stretch pr-6 py-6 bg-black text-neutral-400"
|
||||
className="dark flex items-stretch pr-6 py-6 bg-black text-neutral-400"
|
||||
data-testid="header"
|
||||
>
|
||||
<Logo />
|
||||
@@ -21,12 +21,7 @@ const Header = () => {
|
||||
setConnectDialog={setConnect}
|
||||
setManageDialog={setManage}
|
||||
/>
|
||||
<ThemeSwitcher
|
||||
theme={theme}
|
||||
onToggle={toggleTheme}
|
||||
className="-my-4"
|
||||
fixedBg="dark"
|
||||
/>
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useMemo, useRef } from 'react';
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import { PriceCell, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import type {
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
AssetDetailsDialog,
|
||||
useAssetDetailsDialogStore,
|
||||
} from '@vegaprotocol/assets';
|
||||
import { NO_DATA_MESSAGE } from '../../../constants';
|
||||
import { ConsoleLiteGrid } from '../../console-lite-grid';
|
||||
import { useAccountColumnDefinitions } from '.';
|
||||
|
||||
@@ -22,19 +24,12 @@ interface AccountObj extends AccountFieldsFragment {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
const AccountsManager = ({ partyId }: Props) => {
|
||||
const {
|
||||
isAssetDetailsDialogOpen,
|
||||
assetDetailsDialogSymbol,
|
||||
setAssetDetailsDialogOpen,
|
||||
} = useAssetDetailsDialogStore();
|
||||
const AccountsManager = () => {
|
||||
const { partyId = '' } = useOutletContext<{ partyId: string }>();
|
||||
const { isOpen, symbol, setOpen } = useAssetDetailsDialogStore();
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
const update = accountsManagerUpdate(gridRef);
|
||||
const update = useMemo(() => accountsManagerUpdate(gridRef), []);
|
||||
const { data, error, loading } = useDataProvider<
|
||||
AccountFieldsFragment[],
|
||||
AccountEventsSubscription['accounts']
|
||||
@@ -42,9 +37,14 @@ const AccountsManager = ({ partyId }: Props) => {
|
||||
const { columnDefs, defaultColDef } = useAccountColumnDefinitions();
|
||||
return (
|
||||
<>
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={data}
|
||||
noDataMessage={NO_DATA_MESSAGE}
|
||||
>
|
||||
<ConsoleLiteGrid<AccountObj>
|
||||
data={data as AccountObj[]}
|
||||
rowData={data as AccountObj[]}
|
||||
columnDefs={columnDefs}
|
||||
defaultColDef={defaultColDef}
|
||||
components={{ PriceCell }}
|
||||
@@ -52,9 +52,9 @@ const AccountsManager = ({ partyId }: Props) => {
|
||||
/>
|
||||
</AsyncRenderer>
|
||||
<AssetDetailsDialog
|
||||
assetSymbol={assetDetailsDialogSymbol}
|
||||
open={isAssetDetailsDialogOpen}
|
||||
onChange={(open) => setAssetDetailsDialogOpen(open)}
|
||||
assetSymbol={symbol}
|
||||
open={isOpen}
|
||||
onChange={(open) => setOpen(open)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -42,8 +42,7 @@ const comparator = (
|
||||
};
|
||||
|
||||
const useAccountColumnDefinitions = () => {
|
||||
const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } =
|
||||
useAssetDetailsDialogStore();
|
||||
const { open } = useAssetDetailsDialogStore();
|
||||
const columnDefs: ColDef[] = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
@@ -60,8 +59,7 @@ const useAccountColumnDefinitions = () => {
|
||||
<button
|
||||
className="hover:underline"
|
||||
onClick={() => {
|
||||
setAssetDetailsDialogOpen(true);
|
||||
setAssetDetailsDialogSymbol(value);
|
||||
open(value);
|
||||
}}
|
||||
>
|
||||
{value}
|
||||
@@ -97,7 +95,7 @@ const useAccountColumnDefinitions = () => {
|
||||
addDecimalsFormatNumber(value, data.asset.decimals),
|
||||
},
|
||||
];
|
||||
}, [setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol]);
|
||||
}, [open]);
|
||||
|
||||
const defaultColDef = useMemo(() => {
|
||||
return {
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { useRef } from 'react';
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import type { TradeWithMarket } from '@vegaprotocol/fills';
|
||||
import { useFillsList } from '@vegaprotocol/fills';
|
||||
import type { BodyScrollEndEvent, BodyScrollEvent } from 'ag-grid-community';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { ConsoleLiteGrid } from '../../console-lite-grid';
|
||||
import { NO_DATA_MESSAGE } from '../../../constants';
|
||||
import useColumnDefinitions from './use-column-definitions';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
const FillsManager = ({ partyId }: Props) => {
|
||||
const FillsManager = () => {
|
||||
const { partyId } = useOutletContext<{ partyId: string }>();
|
||||
const { columnDefs, defaultColDef } = useColumnDefinitions({ partyId });
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const scrolledToTop = useRef(true);
|
||||
@@ -32,7 +31,12 @@ const FillsManager = ({ partyId }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={data?.length ? data : null}
|
||||
noDataMessage={NO_DATA_MESSAGE}
|
||||
>
|
||||
<ConsoleLiteGrid<TradeWithMarket>
|
||||
ref={gridRef}
|
||||
rowModelType="infinite"
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
export * from './portfolio';
|
||||
export * from './accounts';
|
||||
export * from './fills';
|
||||
export * from './orders';
|
||||
export * from './positions';
|
||||
export * as constants from './constants';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import type { AgGridReact } from 'ag-grid-react';
|
||||
import type { BodyScrollEndEvent, BodyScrollEvent } from 'ag-grid-community';
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import type { OrderWithMarket } from '@vegaprotocol/orders';
|
||||
import {
|
||||
useOrderCancel,
|
||||
@@ -14,13 +15,11 @@ import {
|
||||
} from '@vegaprotocol/orders';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { ConsoleLiteGrid } from '../../console-lite-grid';
|
||||
import { NO_DATA_MESSAGE } from '../../../constants';
|
||||
import useColumnDefinitions from './use-column-definitions';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
const OrdersManager = ({ partyId }: Props) => {
|
||||
const OrdersManager = () => {
|
||||
const { partyId } = useOutletContext<{ partyId: string }>();
|
||||
const [editOrder, setEditOrder] = useState<OrderWithMarket | null>(null);
|
||||
const orderCancel = useOrderCancel();
|
||||
const orderEdit = useOrderEdit(editOrder);
|
||||
@@ -49,10 +48,16 @@ const OrdersManager = ({ partyId }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
<AsyncRenderer
|
||||
loading={loading}
|
||||
error={error}
|
||||
data={data?.length ? data : null}
|
||||
noDataMessage={NO_DATA_MESSAGE}
|
||||
>
|
||||
<ConsoleLiteGrid<OrderWithMarket>
|
||||
ref={gridRef}
|
||||
rowModelType="infinite"
|
||||
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||
rowData={data?.length ? undefined : []}
|
||||
datasource={{ getRows }}
|
||||
onBodyScrollEnd={onBodyScrollEnd}
|
||||
onBodyScroll={onBodyScroll}
|
||||
|
||||
@@ -1,54 +1,27 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { AccountManager } from './accounts';
|
||||
import React from 'react';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import ConnectWallet from '../wallet-connector';
|
||||
import { DepositContainer } from '../deposits';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useOutlet, useLocation } from 'react-router-dom';
|
||||
import { HorizontalMenu } from '../horizontal-menu';
|
||||
import * as constants from './constants';
|
||||
import { PositionsManager } from './positions';
|
||||
import { OrdersManager } from './orders';
|
||||
import { FillsManager } from './fills';
|
||||
|
||||
type RouterParams = {
|
||||
module?: string;
|
||||
};
|
||||
|
||||
export const Portfolio = () => {
|
||||
const { keypair } = useVegaWallet();
|
||||
const params = useParams<RouterParams>();
|
||||
|
||||
const module = useMemo(() => {
|
||||
if (!keypair) {
|
||||
return (
|
||||
<section className="xl:w-1/2">
|
||||
<ConnectWallet />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
switch (params?.module) {
|
||||
case constants.PORTFOLIO_ASSETS:
|
||||
default:
|
||||
return <AccountManager partyId={keypair.pub} />;
|
||||
case constants.PORTFOLIO_POSITIONS:
|
||||
return <PositionsManager partyId={keypair.pub} />;
|
||||
case constants.PORTFOLIO_ORDERS:
|
||||
return <OrdersManager partyId={keypair.pub} />;
|
||||
case constants.PORTFOLIO_FILLS:
|
||||
return <FillsManager partyId={keypair.pub} />;
|
||||
case constants.PORTFOLIO_DEPOSITS:
|
||||
return <DepositContainer />;
|
||||
}
|
||||
}, [params?.module, keypair]);
|
||||
const { pathname } = useLocation();
|
||||
const module = pathname.split('/portfolio/')?.[1] ?? '';
|
||||
const outlet = useOutlet({ partyId: keypair?.pub || '' });
|
||||
if (!keypair) {
|
||||
return (
|
||||
<section className="xl:w-1/2">
|
||||
<ConnectWallet />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-full p-4 md:p-6 grid grid-rows-[min-content_1fr]">
|
||||
<HorizontalMenu
|
||||
active={params?.module}
|
||||
items={constants.PORTFOLIO_ITEMS}
|
||||
/>
|
||||
{module}
|
||||
<HorizontalMenu active={module} items={constants.PORTFOLIO_ITEMS} />
|
||||
{outlet}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,11 +17,11 @@ const getRowId = ({ data }: { data: Position }) => data.marketId;
|
||||
|
||||
const PositionsAsset = ({ partyId, assetSymbol }: Props) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const { data, error, loading, getRows } = usePositionsData({
|
||||
const { data, error, loading, getRows } = usePositionsData(
|
||||
partyId,
|
||||
assetSymbol,
|
||||
gridRef,
|
||||
});
|
||||
assetSymbol
|
||||
);
|
||||
const { columnDefs, defaultColDef } = useColumnDefinitions();
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
@@ -47,7 +47,7 @@ const PositionsAsset = ({ partyId, assetSymbol }: Props) => {
|
||||
defaultColDef={defaultColDef}
|
||||
getRowId={getRowId}
|
||||
rowModelType={data?.length ? 'infinite' : 'clientSide'}
|
||||
data={data?.length ? undefined : []}
|
||||
rowData={data?.length ? undefined : []}
|
||||
datasource={{ getRows }}
|
||||
components={{ PriceFlashCell }}
|
||||
/>
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
import { useOutletContext } from 'react-router-dom';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { usePositionsAssets } from '@vegaprotocol/positions';
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import PositionsAsset from './positions-asset';
|
||||
|
||||
interface Props {
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
const Positions = ({ partyId }: Props) => {
|
||||
const { data, error, loading, assetSymbols } = usePositionsAssets({
|
||||
partyId,
|
||||
});
|
||||
const Positions = () => {
|
||||
const { partyId } = useOutletContext<{ partyId: string }>();
|
||||
const { data, error, loading, assetSymbols } = usePositionsAssets(partyId);
|
||||
return (
|
||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||
{assetSymbols && assetSymbols.length && (
|
||||
{assetSymbols && assetSymbols.length > 0 && (
|
||||
<div className="w-full, h-max">
|
||||
{assetSymbols?.map((assetSymbol) => (
|
||||
<PositionsAsset
|
||||
|
||||
@@ -67,7 +67,7 @@ const SimpleMarketList = () => {
|
||||
<ConsoleLiteGrid<MarketWithPercentChange>
|
||||
classNamesParam="mb-32 min-h-[300px]"
|
||||
columnDefs={columnDefs}
|
||||
data={localData}
|
||||
rowData={localData}
|
||||
defaultColDef={defaultColDef}
|
||||
handleRowClicked={handleRowClicked}
|
||||
/>
|
||||
|
||||
+6
-1
@@ -68,9 +68,14 @@ const SimpleMarketPercentChangeWrapper = (props: Props) => {
|
||||
};
|
||||
|
||||
const SimpleMarketPercentChange = ({ candles, marketId, setValue }: Props) => {
|
||||
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: marketCandlesProvider,
|
||||
variables: { marketId, interval: Interval.INTERVAL_I1D },
|
||||
variables: {
|
||||
marketId,
|
||||
interval: Interval.INTERVAL_I1D,
|
||||
since: new Date(yesterday * 1000).toISOString(),
|
||||
},
|
||||
});
|
||||
|
||||
const close = data?.map((m) => m.close);
|
||||
|
||||
@@ -24,3 +24,5 @@ export const MARKET_STATES_MAP: Record<MarketState | '', string> = {
|
||||
[MarketState.STATE_TRADING_TERMINATED]: t('TradingTerminated'),
|
||||
'': t('Unknown'),
|
||||
};
|
||||
|
||||
export const NO_DATA_MESSAGE = t('No data to display');
|
||||
|
||||
@@ -16,8 +16,6 @@ interface MenuState {
|
||||
export interface LocalValues {
|
||||
vegaWalletDialog: VegaWalletDialogState;
|
||||
menu: MenuState;
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
const LocalContext = createContext<LocalValues>({} as LocalValues);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
export interface MarketMarkPrice_market_data {
|
||||
__typename: "MarketData";
|
||||
/**
|
||||
* the mark price (an unsigned integer)
|
||||
* The mark price (an unsigned integer)
|
||||
*/
|
||||
markPrice: string;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export interface MarketMarkPrice_market_data {
|
||||
export interface MarketMarkPrice_market {
|
||||
__typename: "Market";
|
||||
/**
|
||||
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
|
||||
* The number of decimal places that an integer must be shifted by in order to get a correct
|
||||
* number denominated in the currency of the market. (uint64)
|
||||
*
|
||||
* Examples:
|
||||
|
||||
@@ -60,19 +60,19 @@ export interface PartyMarketData_party_marginsConnection_edges_node_market {
|
||||
export interface PartyMarketData_party_marginsConnection_edges_node {
|
||||
__typename: "MarginLevels";
|
||||
/**
|
||||
* market in which the margin is required for this party
|
||||
* Market in which the margin is required for this party
|
||||
*/
|
||||
market: PartyMarketData_party_marginsConnection_edges_node_market;
|
||||
/**
|
||||
* this is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
* This is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
*/
|
||||
initialLevel: string;
|
||||
/**
|
||||
* minimal margin for the position to be maintained in the network (unsigned integer)
|
||||
* Minimal margin for the position to be maintained in the network (unsigned integer)
|
||||
*/
|
||||
maintenanceLevel: string;
|
||||
/**
|
||||
* if the margin is between maintenance and search, the network will initiate a collateral search (unsigned integer)
|
||||
* If the margin is between maintenance and search, the network will initiate a collateral search (unsigned integer)
|
||||
*/
|
||||
searchLevel: string;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface EstimateOrder_estimateOrder_fee {
|
||||
export interface EstimateOrder_estimateOrder_marginLevels {
|
||||
__typename: "MarginLevels";
|
||||
/**
|
||||
* this is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
* This is the minimum margin required for a party to place a new order on the network (unsigned integer)
|
||||
*/
|
||||
initialLevel: string;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export interface EstimateOrder_estimateOrder {
|
||||
|
||||
export interface EstimateOrder {
|
||||
/**
|
||||
* return an estimation of the potential cost for a new order
|
||||
* Return an estimation of the potential cost for a new order
|
||||
*/
|
||||
estimateOrder: EstimateOrder_estimateOrder;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ export interface MarketPositions_party_positionsConnection_edges_node {
|
||||
|
||||
export interface MarketPositions_party_positionsConnection_edges {
|
||||
__typename: "PositionEdge";
|
||||
/**
|
||||
* The position
|
||||
*/
|
||||
node: MarketPositions_party_positionsConnection_edges_node;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import type { LocalValues } from '../context/local-context';
|
||||
|
||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
const useLocalValues = () => {
|
||||
const [connect, setConnect] = useState<boolean>(false);
|
||||
const [manage, setManage] = useState<boolean>(false);
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
@@ -9,10 +9,8 @@ const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
||||
() => ({
|
||||
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||
theme,
|
||||
toggleTheme,
|
||||
}),
|
||||
[connect, manage, theme, toggleTheme, menuOpen]
|
||||
[connect, manage, menuOpen]
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { renderHook } from '@testing-library/react';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import useOrderCloseOut from './use-order-closeout';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
|
||||
jest.mock('@vegaprotocol/wallet', () => ({
|
||||
@@ -49,7 +49,7 @@ describe('useOrderCloseOut Hook', () => {
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
order: order as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyData: partyData as PartyBalanceQuery,
|
||||
}),
|
||||
{
|
||||
@@ -66,7 +66,7 @@ describe('useOrderCloseOut Hook', () => {
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
order: { ...order, side: 'SIDE_SELL' } as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyData: partyData as PartyBalanceQuery,
|
||||
}),
|
||||
{
|
||||
@@ -83,7 +83,7 @@ describe('useOrderCloseOut Hook', () => {
|
||||
() =>
|
||||
useOrderCloseOut({
|
||||
order: { ...order, side: 'SIDE_SELL' } as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
}),
|
||||
{
|
||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PartyBalanceQuery } from '../components/deal-ticket/__generated__/PartyBalanceQuery';
|
||||
import { useSettlementAccount } from './use-settlement-account';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
@@ -47,7 +47,7 @@ const CLOSEOUT_PRICE_QUERY = gql`
|
||||
|
||||
interface Props {
|
||||
order: Order;
|
||||
market: DealTicketQuery_market;
|
||||
market: DealTicketMarketFragment;
|
||||
partyData?: PartyBalanceQuery;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
import type { Order } from '@vegaprotocol/orders';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import type { PositionMargin } from './use-market-positions';
|
||||
import useOrderMargin from './use-order-margin';
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('useOrderMargin Hook', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyId,
|
||||
})
|
||||
);
|
||||
@@ -72,7 +72,7 @@ describe('useOrderMargin Hook', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyId,
|
||||
})
|
||||
);
|
||||
@@ -84,7 +84,7 @@ describe('useOrderMargin Hook', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyId,
|
||||
})
|
||||
);
|
||||
@@ -111,7 +111,7 @@ describe('useOrderMargin Hook', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useOrderMargin({
|
||||
order: order as Order,
|
||||
market: market as DealTicketQuery_market,
|
||||
market: market as DealTicketMarketFragment,
|
||||
partyId,
|
||||
})
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
EstimateOrderVariables,
|
||||
EstimateOrder_estimateOrder_fee,
|
||||
} from './__generated__/estimateOrder';
|
||||
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import type { DealTicketMarketFragment } from '@vegaprotocol/deal-ticket';
|
||||
import { Side } from '@vegaprotocol/types';
|
||||
import { addDecimal, removeDecimal } from '@vegaprotocol/react-helpers';
|
||||
import useMarketPositions from './use-market-positions';
|
||||
@@ -47,7 +47,7 @@ export const ESTIMATE_ORDER_QUERY = gql`
|
||||
|
||||
interface Props {
|
||||
order: Order;
|
||||
market: DealTicketQuery_market;
|
||||
market: DealTicketMarketFragment;
|
||||
partyId: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import { DealTicketContainer } from '../components/deal-ticket';
|
||||
import { SimpleMarketList } from '../components/simple-market-list';
|
||||
import { Portfolio } from '../components/portfolio';
|
||||
import {
|
||||
Portfolio,
|
||||
AccountManager,
|
||||
PositionsManager,
|
||||
OrdersManager,
|
||||
FillsManager,
|
||||
constants,
|
||||
} from '../components/portfolio';
|
||||
import { DepositContainer } from '../components/deposits';
|
||||
|
||||
export const ROUTES = {
|
||||
MARKETS: 'markets',
|
||||
@@ -51,13 +59,33 @@ export const routerConfig = [
|
||||
name: 'Portfolio',
|
||||
text: t('Portfolio'),
|
||||
element: <Portfolio />,
|
||||
children: [
|
||||
{
|
||||
path: ':module',
|
||||
element: <Portfolio />,
|
||||
},
|
||||
],
|
||||
icon: 'portfolio',
|
||||
isNavItem: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
element: <AccountManager />,
|
||||
},
|
||||
{
|
||||
path: constants.PORTFOLIO_ASSETS,
|
||||
element: <AccountManager />,
|
||||
},
|
||||
{
|
||||
path: constants.PORTFOLIO_POSITIONS,
|
||||
element: <PositionsManager />,
|
||||
},
|
||||
{
|
||||
path: constants.PORTFOLIO_ORDERS,
|
||||
element: <OrdersManager />,
|
||||
},
|
||||
{
|
||||
path: constants.PORTFOLIO_FILLS,
|
||||
element: <FillsManager />,
|
||||
},
|
||||
{
|
||||
path: constants.PORTFOLIO_DEPOSITS,
|
||||
element: <DepositContainer />,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -6,3 +6,4 @@ NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
|
||||
|
||||
@@ -14,5 +14,8 @@
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useState, useEffect } from 'react';
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { BrowserTracing } from '@sentry/tracing';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
EnvironmentProvider,
|
||||
NetworkLoader,
|
||||
@@ -18,7 +17,6 @@ import { ENV } from './config/env';
|
||||
|
||||
function App() {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const [menuOpen, setMenuOpen] = useState(false);
|
||||
|
||||
const location = useLocation();
|
||||
@@ -37,31 +35,24 @@ function App() {
|
||||
}, [VEGA_ENV]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div
|
||||
className={`${
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||
>
|
||||
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
|
||||
<Header
|
||||
theme={theme}
|
||||
toggleTheme={toggleTheme}
|
||||
menuOpen={menuOpen}
|
||||
setMenuOpen={setMenuOpen}
|
||||
/>
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div
|
||||
className={`${
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||
>
|
||||
<div className="grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
|
||||
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
|
||||
<Nav menuOpen={menuOpen} />
|
||||
<Main />
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||
<NetworkInfo />
|
||||
</footer>
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</TendermintWebsocketProvider>
|
||||
</ThemeContext.Provider>
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</TendermintWebsocketProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,30 +8,24 @@ import type { Dispatch, SetStateAction } from 'react';
|
||||
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
||||
|
||||
interface ThemeToggleProps {
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
menuOpen: boolean;
|
||||
setMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
export const Header = ({
|
||||
theme,
|
||||
toggleTheme,
|
||||
menuOpen,
|
||||
setMenuOpen,
|
||||
}: ThemeToggleProps) => {
|
||||
export const Header = ({ menuOpen, setMenuOpen }: ThemeToggleProps) => {
|
||||
const headerClasses = classnames(
|
||||
'md:col-span-2',
|
||||
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
||||
'p-4 gap-2 md:gap-4',
|
||||
'border-b border-neutral-700 dark:border-neutral-300'
|
||||
'border-b border-neutral-700 dark:border-neutral-300 bg-black',
|
||||
'dark text-white'
|
||||
);
|
||||
return (
|
||||
<header className={headerClasses}>
|
||||
<div className="flex h-full items-center sm:items-stretch gap-4">
|
||||
<Link to={Routes.HOME}>
|
||||
<h1
|
||||
className="text-3xl font-alpha uppercase calt mb-0"
|
||||
className="text-white text-3xl font-alpha uppercase calt mb-0"
|
||||
data-testid="explorer-header"
|
||||
>
|
||||
{t('Vega Explorer')}
|
||||
@@ -41,13 +35,13 @@ export const Header = ({
|
||||
</div>
|
||||
<button
|
||||
data-testid="open-menu"
|
||||
className="md:hidden"
|
||||
className="md:hidden text-white"
|
||||
onClick={() => setMenuOpen(!menuOpen)}
|
||||
>
|
||||
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
||||
</button>
|
||||
<Search />
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
||||
<ThemeSwitcher className="-my-4" />
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './info-panel';
|
||||
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Panel } from '../panel';
|
||||
import {
|
||||
CopyWithTooltip,
|
||||
Icon,
|
||||
Intent,
|
||||
Lozenge,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
interface InfoPanelProps {
|
||||
children?: ReactNode | ReactNode[];
|
||||
title: string;
|
||||
id: string;
|
||||
type?: string;
|
||||
copy?: boolean;
|
||||
}
|
||||
|
||||
export const InfoPanel = ({
|
||||
children,
|
||||
title,
|
||||
id,
|
||||
type,
|
||||
copy = true,
|
||||
}: InfoPanelProps) => {
|
||||
return (
|
||||
<Panel>
|
||||
<section className="flex gap-3 mb-1 items-center">
|
||||
<h3 className="text-lg font-bold">{title}</h3>
|
||||
<p title={id} className="truncate ...">
|
||||
{id}
|
||||
</p>
|
||||
{type && (
|
||||
<Lozenge
|
||||
className="text-xs leading-relaxed cursor-auto"
|
||||
variant={Intent.None}
|
||||
>
|
||||
<Tooltip side="top" description={type} align="center">
|
||||
<span>{type}</span>
|
||||
</Tooltip>
|
||||
</Lozenge>
|
||||
)}
|
||||
{copy && (
|
||||
<CopyWithTooltip text={id}>
|
||||
<button className="underline">
|
||||
<Icon name="duplicate" className="ml-2" />
|
||||
</button>
|
||||
</CopyWithTooltip>
|
||||
)}
|
||||
</section>
|
||||
{children}
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from './panel';
|
||||
@@ -0,0 +1,10 @@
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
interface PanelProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
export const Panel = ({ children, className }: PanelProps) => (
|
||||
<div className={classNames('border p-5 mb-5', className)}>{children}</div>
|
||||
);
|
||||
@@ -63,6 +63,7 @@ export const Search = () => {
|
||||
{...register('search')}
|
||||
id="search"
|
||||
data-testid="search"
|
||||
className="text-white"
|
||||
hasError={Boolean(error?.message)}
|
||||
type="text"
|
||||
placeholder={t('Enter block number or transaction hash')}
|
||||
|
||||
@@ -81,6 +81,9 @@ export interface AssetsQuery_assetsConnection_edges_node {
|
||||
|
||||
export interface AssetsQuery_assetsConnection_edges {
|
||||
__typename: "AssetEdge";
|
||||
/**
|
||||
* The asset information
|
||||
*/
|
||||
node: AssetsQuery_assetsConnection_edges_node;
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,7 @@ export interface ProposalsQuery_proposalsConnection_edges_node {
|
||||
*/
|
||||
datetime: string;
|
||||
/**
|
||||
* Reason for the proposal to be rejected by the core
|
||||
* Why the proposal was rejected by the core
|
||||
*/
|
||||
rejectionReason: ProposalRejectionReason | null;
|
||||
/**
|
||||
|
||||
+28
-28
@@ -104,15 +104,15 @@ export interface MarketsQuery_markets_tradableInstrument_instrument {
|
||||
export interface MarketsQuery_markets_tradableInstrument_riskModel_LogNormalRiskModel_params {
|
||||
__typename: "LogNormalModelParams";
|
||||
/**
|
||||
* r parameter
|
||||
* R parameter
|
||||
*/
|
||||
r: number;
|
||||
/**
|
||||
* sigma parameter, annualised volatility of the underlying asset, must be a strictly non-negative real number
|
||||
* Sigma parameter, annualised volatility of the underlying asset, must be a strictly non-negative real number
|
||||
*/
|
||||
sigma: number;
|
||||
/**
|
||||
* mu parameter, annualised growth rate of the underlying asset
|
||||
* Mu parameter, annualised growth rate of the underlying asset
|
||||
*/
|
||||
mu: number;
|
||||
}
|
||||
@@ -158,15 +158,15 @@ export type MarketsQuery_markets_tradableInstrument_riskModel = MarketsQuery_mar
|
||||
export interface MarketsQuery_markets_tradableInstrument_marginCalculator_scalingFactors {
|
||||
__typename: "ScalingFactors";
|
||||
/**
|
||||
* the scaling factor that determines the margin level at which Vega has to search for more money
|
||||
* The scaling factor that determines the margin level at which Vega has to search for more money
|
||||
*/
|
||||
searchLevel: number;
|
||||
/**
|
||||
* the scaling factor that determines the optimal margin level
|
||||
* The scaling factor that determines the optimal margin level
|
||||
*/
|
||||
initialMargin: number;
|
||||
/**
|
||||
* the scaling factor that determines the overflow margin level
|
||||
* The scaling factor that determines the overflow margin level
|
||||
*/
|
||||
collateralRelease: number;
|
||||
}
|
||||
@@ -362,47 +362,47 @@ export interface MarketsQuery_markets_data_liquidityProviderFeeShare {
|
||||
export interface MarketsQuery_markets_data {
|
||||
__typename: "MarketData";
|
||||
/**
|
||||
* the mark price (an unsigned integer)
|
||||
* The mark price (an unsigned integer)
|
||||
*/
|
||||
markPrice: string;
|
||||
/**
|
||||
* the highest price level on an order book for buy orders.
|
||||
* The highest price level on an order book for buy orders.
|
||||
*/
|
||||
bestBidPrice: string;
|
||||
/**
|
||||
* the aggregated volume being bid at the best bid price.
|
||||
* The aggregated volume being bid at the best bid price.
|
||||
*/
|
||||
bestBidVolume: string;
|
||||
/**
|
||||
* the lowest price level on an order book for offer orders.
|
||||
* The lowest price level on an order book for offer orders.
|
||||
*/
|
||||
bestOfferPrice: string;
|
||||
/**
|
||||
* the aggregated volume being offered at the best offer price.
|
||||
* The aggregated volume being offered at the best offer price.
|
||||
*/
|
||||
bestOfferVolume: string;
|
||||
/**
|
||||
* the highest price level on an order book for buy orders not including pegged orders.
|
||||
* The highest price level on an order book for buy orders not including pegged orders.
|
||||
*/
|
||||
bestStaticBidPrice: string;
|
||||
/**
|
||||
* the aggregated volume being offered at the best static bid price, excluding pegged orders
|
||||
* The aggregated volume being offered at the best static bid price, excluding pegged orders
|
||||
*/
|
||||
bestStaticBidVolume: string;
|
||||
/**
|
||||
* the lowest price level on an order book for offer orders not including pegged orders.
|
||||
* The lowest price level on an order book for offer orders not including pegged orders.
|
||||
*/
|
||||
bestStaticOfferPrice: string;
|
||||
/**
|
||||
* the aggregated volume being offered at the best static offer price, excluding pegged orders.
|
||||
* The aggregated volume being offered at the best static offer price, excluding pegged orders.
|
||||
*/
|
||||
bestStaticOfferVolume: string;
|
||||
/**
|
||||
* the arithmetic average of the best bid price and best offer price.
|
||||
* The arithmetic average of the best bid price and best offer price.
|
||||
*/
|
||||
midPrice: string;
|
||||
/**
|
||||
* the arithmetic average of the best static bid price and best static offer price
|
||||
* The arithmetic average of the best static bid price and best static offer price
|
||||
*/
|
||||
staticMidPrice: string;
|
||||
/**
|
||||
@@ -410,7 +410,7 @@ export interface MarketsQuery_markets_data {
|
||||
*/
|
||||
timestamp: string;
|
||||
/**
|
||||
* the sum of the size of all positions greater than 0.
|
||||
* The sum of the size of all positions greater than 0.
|
||||
*/
|
||||
openInterest: string;
|
||||
/**
|
||||
@@ -422,39 +422,39 @@ export interface MarketsQuery_markets_data {
|
||||
*/
|
||||
auctionStart: string | null;
|
||||
/**
|
||||
* indicative price if the auction ended now, 0 if not in auction mode
|
||||
* Indicative price if the auction ended now, 0 if not in auction mode
|
||||
*/
|
||||
indicativePrice: string;
|
||||
/**
|
||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||
* Indicative volume if the auction ended now, 0 if not in auction mode
|
||||
*/
|
||||
indicativeVolume: string;
|
||||
/**
|
||||
* what triggered an auction (if an auction was started)
|
||||
* What triggered an auction (if an auction was started)
|
||||
*/
|
||||
trigger: AuctionTrigger;
|
||||
/**
|
||||
* what extended the ongoing auction (if an auction was extended)
|
||||
* What extended the ongoing auction (if an auction was extended)
|
||||
*/
|
||||
extensionTrigger: AuctionTrigger;
|
||||
/**
|
||||
* the amount of stake targeted for this market
|
||||
* The amount of stake targeted for this market
|
||||
*/
|
||||
targetStake: string | null;
|
||||
/**
|
||||
* the supplied stake for the market
|
||||
* The supplied stake for the market
|
||||
*/
|
||||
suppliedStake: string | null;
|
||||
/**
|
||||
* a list of valid price ranges per associated trigger
|
||||
* A list of valid price ranges per associated trigger
|
||||
*/
|
||||
priceMonitoringBounds: MarketsQuery_markets_data_priceMonitoringBounds[] | null;
|
||||
/**
|
||||
* the market value proxy
|
||||
* The market value proxy
|
||||
*/
|
||||
marketValueProxy: string;
|
||||
/**
|
||||
* the equity like share of liquidity fee for each liquidity provider
|
||||
* The equity like share of liquidity fee for each liquidity provider
|
||||
*/
|
||||
liquidityProviderFeeShare: MarketsQuery_markets_data_liquidityProviderFeeShare[] | null;
|
||||
}
|
||||
@@ -474,7 +474,7 @@ export interface MarketsQuery_markets {
|
||||
*/
|
||||
tradableInstrument: MarketsQuery_markets_tradableInstrument;
|
||||
/**
|
||||
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
|
||||
* The number of decimal places that an integer must be shifted by in order to get a correct
|
||||
* number denominated in the currency of the market. (uint64)
|
||||
*
|
||||
* Examples:
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export interface NetworkParametersQuery_networkParameters {
|
||||
|
||||
export interface NetworkParametersQuery {
|
||||
/**
|
||||
* return the full list of network parameters
|
||||
* Return the full list of network parameters
|
||||
*/
|
||||
networkParameters: NetworkParametersQuery_networkParameters[] | null;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
formatNumber,
|
||||
t,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { suitableForSyntaxHighlighter } from '@vegaprotocol/react-helpers';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
import type {
|
||||
NetworkParametersQuery,
|
||||
@@ -58,7 +59,7 @@ export const NetworkParameterRow = ({
|
||||
}: {
|
||||
row: NetworkParametersQuery_networkParameters;
|
||||
}) => {
|
||||
const isSyntaxRow = isJsonObject(value);
|
||||
const isSyntaxRow = suitableForSyntaxHighlighter(value);
|
||||
|
||||
return (
|
||||
<KeyValueTableRow
|
||||
@@ -85,14 +86,6 @@ export const NetworkParameterRow = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const isJsonObject = (str: string) => {
|
||||
try {
|
||||
return JSON.parse(str) && Object.keys(JSON.parse(str)).length > 0;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const NETWORK_PARAMETERS_QUERY = gql`
|
||||
query NetworkParametersQuery {
|
||||
networkParameters {
|
||||
|
||||
+11
-11
@@ -12,11 +12,11 @@ import { OracleSpecStatus, PropertyKeyType, ConditionOperator } from "@vegaproto
|
||||
export interface OracleSpecs_oracleSpecs_filters_key {
|
||||
__typename: "PropertyKey";
|
||||
/**
|
||||
* name is the name of the property.
|
||||
* The name of the property.
|
||||
*/
|
||||
name: string | null;
|
||||
/**
|
||||
* type is the type of the property.
|
||||
* The type of the property.
|
||||
*/
|
||||
type: PropertyKeyType;
|
||||
}
|
||||
@@ -24,11 +24,11 @@ export interface OracleSpecs_oracleSpecs_filters_key {
|
||||
export interface OracleSpecs_oracleSpecs_filters_conditions {
|
||||
__typename: "Condition";
|
||||
/**
|
||||
* value is used by the comparator.
|
||||
* The value to compare against.
|
||||
*/
|
||||
value: string | null;
|
||||
/**
|
||||
* comparator is the type of comparison to make on the value.
|
||||
* The type of comparison to make on the value.
|
||||
*/
|
||||
operator: ConditionOperator;
|
||||
}
|
||||
@@ -36,11 +36,11 @@ export interface OracleSpecs_oracleSpecs_filters_conditions {
|
||||
export interface OracleSpecs_oracleSpecs_filters {
|
||||
__typename: "Filter";
|
||||
/**
|
||||
* key is the oracle data property key targeted by the filter.
|
||||
* The oracle data property key targeted by the filter.
|
||||
*/
|
||||
key: OracleSpecs_oracleSpecs_filters_key;
|
||||
/**
|
||||
* conditions are the conditions that should be matched by the data to be
|
||||
* The conditions that should be matched by the data to be
|
||||
* considered of interest.
|
||||
*/
|
||||
conditions: OracleSpecs_oracleSpecs_filters_conditions[] | null;
|
||||
@@ -49,7 +49,7 @@ export interface OracleSpecs_oracleSpecs_filters {
|
||||
export interface OracleSpecs_oracleSpecs_data {
|
||||
__typename: "OracleData";
|
||||
/**
|
||||
* pubKeys is the list of public keys that signed the data
|
||||
* The list of public keys that signed the data
|
||||
*/
|
||||
pubKeys: string[] | null;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export interface OracleSpecs_oracleSpecs_data {
|
||||
export interface OracleSpecs_oracleSpecs {
|
||||
__typename: "OracleSpec";
|
||||
/**
|
||||
* status describes the status of the oracle spec
|
||||
* Status describes the status of the oracle spec
|
||||
*/
|
||||
status: OracleSpecStatus;
|
||||
/**
|
||||
@@ -73,18 +73,18 @@ export interface OracleSpecs_oracleSpecs {
|
||||
*/
|
||||
updatedAt: string | null;
|
||||
/**
|
||||
* pubKeys is the list of authorized public keys that signed the data for this
|
||||
* The list of authorized public keys that signed the data for this
|
||||
* oracle. All the public keys in the oracle data should be contained in these
|
||||
* public keys.
|
||||
*/
|
||||
pubKeys: string[] | null;
|
||||
/**
|
||||
* filters describes which oracle data are considered of interest or not for
|
||||
* Filters describes which oracle data are considered of interest or not for
|
||||
* the product (or the risk model).
|
||||
*/
|
||||
filters: OracleSpecs_oracleSpecs_filters[] | null;
|
||||
/**
|
||||
* data list all the oracle data broadcast to this spec
|
||||
* Data list all the oracle data broadcast to this spec
|
||||
*/
|
||||
data: OracleSpecs_oracleSpecs_data[];
|
||||
}
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { useQuery } from '@apollo/client';
|
||||
import { gql } from '@apollo/client';
|
||||
import { t, useFetch } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
t,
|
||||
useFetch,
|
||||
addDecimalsFormatNumber,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { AccountTypeMapping } from '@vegaprotocol/types';
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { RouteTitle } from '../../../components/route-title';
|
||||
import { SubHeading } from '../../../components/sub-heading';
|
||||
import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||
import { Panel } from '../../../components/panel';
|
||||
import { InfoPanel } from '../../../components/info-panel';
|
||||
import { DATA_SOURCES } from '../../../config';
|
||||
import type { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
|
||||
import type {
|
||||
@@ -69,12 +76,80 @@ const Party = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const header = data?.party?.id ? (
|
||||
<InfoPanel
|
||||
title={t('Address')}
|
||||
id={data.party.id}
|
||||
type={data.party.__typename}
|
||||
/>
|
||||
) : (
|
||||
<Panel>
|
||||
<p>No party found for key {party}</p>
|
||||
</Panel>
|
||||
);
|
||||
|
||||
const accounts = (
|
||||
<section>
|
||||
{data?.party?.accounts?.length ? (
|
||||
data.party.accounts.map((account) => {
|
||||
return (
|
||||
<InfoPanel
|
||||
title={account.asset.name}
|
||||
id={account.asset.id}
|
||||
type={`Account Type - ${AccountTypeMapping[account.type]}`}
|
||||
>
|
||||
<section>
|
||||
<dl className="flex gap-2 font-mono">
|
||||
<dt className="font-bold">
|
||||
{t('Balance')} ({account.asset.symbol})
|
||||
</dt>
|
||||
<dd>
|
||||
{addDecimalsFormatNumber(
|
||||
account.balance,
|
||||
account.asset.decimals
|
||||
)}
|
||||
</dd>
|
||||
</dl>
|
||||
</section>
|
||||
</InfoPanel>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Panel>
|
||||
<p>No Data</p>
|
||||
</Panel>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
|
||||
const staking = (
|
||||
<section>
|
||||
{data?.party?.stake?.currentStakeAvailable ? (
|
||||
<InfoPanel
|
||||
title={t('Current Stake Available')}
|
||||
id={data?.party?.stake?.currentStakeAvailable}
|
||||
type={data?.party?.stake.__typename}
|
||||
copy={false}
|
||||
/>
|
||||
) : (
|
||||
<Panel>
|
||||
<p>Nothing staked for {party}</p>
|
||||
</Panel>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
|
||||
return (
|
||||
<section>
|
||||
<RouteTitle data-testid="parties-header">{t('Party')}</RouteTitle>
|
||||
{data ? (
|
||||
<>
|
||||
{header}
|
||||
<SubHeading>{t('Asset data')}</SubHeading>
|
||||
{accounts}
|
||||
<SubHeading>{t('Staking')}</SubHeading>
|
||||
{staking}
|
||||
<SubHeading>{t('JSON')}</SubHeading>
|
||||
<SyntaxHighlighter data={data} />
|
||||
</>
|
||||
) : null}
|
||||
|
||||
@@ -69,13 +69,19 @@ export interface NodesQuery_nodes {
|
||||
* Amount of stake on the next epoch
|
||||
*/
|
||||
pendingStake: string;
|
||||
/**
|
||||
* Summary of epoch data across all nodes
|
||||
*/
|
||||
epochData: NodesQuery_nodes_epochData | null;
|
||||
/**
|
||||
* Validator status of the node
|
||||
*/
|
||||
status: NodeStatus;
|
||||
}
|
||||
|
||||
export interface NodesQuery {
|
||||
/**
|
||||
* all known network nodes
|
||||
* All known network nodes
|
||||
*/
|
||||
nodes: NodesQuery_nodes[] | null;
|
||||
}
|
||||
|
||||
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": "53.36134639776761480005283301623541348",
|
||||
"locked_amount": "36.75072805682389880003638685946220188",
|
||||
"deposits": [
|
||||
{
|
||||
"amount": "1000",
|
||||
|
||||
+7
-13
@@ -1,24 +1,18 @@
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
import { Header } from './components/header';
|
||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
||||
<div className="layout-grid w-screen justify-self-center">
|
||||
<Header theme={theme} toggleTheme={toggleTheme} />
|
||||
<StatsManager className="max-w-3xl px-24" />
|
||||
</div>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
||||
<div className="layout-grid w-screen justify-self-center">
|
||||
<Header />
|
||||
<StatsManager className="max-w-3xl px-24" />
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</ThemeContext.Provider>
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
import { VegaLogo, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { VegaBackgroundVideo } from '../videos';
|
||||
|
||||
interface ThemeToggleProps {
|
||||
theme: 'light' | 'dark';
|
||||
toggleTheme: () => void;
|
||||
}
|
||||
|
||||
export const Header = ({ theme, toggleTheme }: ThemeToggleProps) => {
|
||||
export const Header = () => {
|
||||
return (
|
||||
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
|
||||
<VegaBackgroundVideo />
|
||||
|
||||
<div className="relative flex justify-center px-8 dark:bg-black bg-white">
|
||||
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
|
||||
<VegaLogo />
|
||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -63,7 +63,10 @@ context(
|
||||
.and('have.text', 'There are no enacted or rejected proposals');
|
||||
});
|
||||
|
||||
it('should be able to see a connect wallet button - if vega wallet disconnected and new proposal button selected', function () {
|
||||
// Skipping this test for now, the new proposal button no longer takes a user directly
|
||||
// to a proposal form, instead it takes them to a page where they can select a proposal type.
|
||||
// Keeping this test here for now as it can be repurposed to test the new proposal forms.
|
||||
it.skip('should be able to see a connect wallet button - if vega wallet disconnected and new proposal button selected', function () {
|
||||
cy.get(newProposalButton).should('be.visible').click();
|
||||
cy.get(connectToVegaWalletButton)
|
||||
.should('be.visible')
|
||||
|
||||
@@ -23,6 +23,9 @@ const manageLink = '[data-testid="manage-vega-wallet"]';
|
||||
const dialogVegaKey = '[data-testid="vega-public-key-full"]';
|
||||
const dialogDisconnectBtn = '[data-testid="disconnect"]';
|
||||
const copyPublicKeyBtn = '[data-testid="copy-vega-public-key"]';
|
||||
const vegaWalletCurrencyTitle = '[data-testid="currency-title"]';
|
||||
const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey');
|
||||
const txTimeout = Cypress.env('txTimeout');
|
||||
|
||||
context(
|
||||
'Vega Wallet - verify elements on widget',
|
||||
@@ -282,5 +285,136 @@ context(
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when assets exist in vegawallet', function () {
|
||||
before('send-faucet assets to connected vega wallet', function () {
|
||||
cy.vega_wallet_receive_fauceted_asset(
|
||||
'USDC (fake)',
|
||||
'10',
|
||||
vegaWalletPublicKey
|
||||
);
|
||||
cy.vega_wallet_receive_fauceted_asset(
|
||||
'BTC (fake)',
|
||||
'6',
|
||||
vegaWalletPublicKey
|
||||
);
|
||||
cy.vega_wallet_receive_fauceted_asset(
|
||||
'EURO (fake)',
|
||||
'8',
|
||||
vegaWalletPublicKey
|
||||
);
|
||||
cy.vega_wallet_receive_fauceted_asset(
|
||||
'DAI (fake)',
|
||||
'2',
|
||||
vegaWalletPublicKey
|
||||
);
|
||||
// cy.vega_wallet_connect(); - to be changed when dialog state is fixed - https://github.com/vegaprotocol/frontend-monorepo/issues/838
|
||||
// then code below can be removed
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get('button')
|
||||
.contains('Connect Vega wallet to use associated $VEGA')
|
||||
.should('be.enabled')
|
||||
.and('be.visible')
|
||||
.click({ force: true });
|
||||
});
|
||||
cy.get(restConnectorForm).within(() => {
|
||||
cy.get('#wallet').click().type(Cypress.env('vegaWalletName'));
|
||||
cy.get('#passphrase')
|
||||
.click()
|
||||
.type(Cypress.env('vegaWalletPassphrase'));
|
||||
cy.get('button').contains('Connect').click();
|
||||
});
|
||||
cy.ethereum_wallet_connect();
|
||||
});
|
||||
|
||||
it('should see fUSDC assets - within vega wallet', function () {
|
||||
let currency = { id: 'fUSDC', name: 'USDC (fake)' };
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id, txTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('10.00000').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.contains(currency.name);
|
||||
});
|
||||
});
|
||||
|
||||
it('should see fBTC assets - within vega wallet', function () {
|
||||
let currency = { id: 'fBTC', name: 'BTC (fake)' };
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id, txTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('6.00000').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.contains(currency.name);
|
||||
});
|
||||
});
|
||||
|
||||
it('should see fEURO assets - within vega wallet', function () {
|
||||
let currency = { id: 'fEURO', name: 'EURO (fake)' };
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id, txTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('8.00000').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.contains(currency.name);
|
||||
});
|
||||
});
|
||||
|
||||
it('should see fDAI assets - within vega wallet', function () {
|
||||
let currency = { id: 'fDAI', name: 'DAI (fake)' };
|
||||
cy.get(walletContainer).within(() => {
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id, txTimeout)
|
||||
.should('be.visible');
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.siblings()
|
||||
.within(() => cy.contains_exactly('2.00000').should('be.visible'));
|
||||
|
||||
cy.get(vegaWalletCurrencyTitle)
|
||||
.contains(currency.id)
|
||||
.parent()
|
||||
.contains(currency.name);
|
||||
});
|
||||
});
|
||||
|
||||
after(
|
||||
'teardown environment to prevent test data bleeding into other tests',
|
||||
function () {
|
||||
if (Cypress.env('CYPRESS_TEARDOWN_NETWORK_AFTER_FLOWS')) {
|
||||
cy.restartVegacapsuleNetwork();
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -17,6 +17,10 @@ const navigation = {
|
||||
pageSpinner: '[data-testid="splash-loader"]',
|
||||
};
|
||||
|
||||
Cypress.Commands.add('contains_exactly', (expected_result) => {
|
||||
return cy.contains(new RegExp('^' + expected_result + '$', 'g'));
|
||||
});
|
||||
|
||||
Cypress.Commands.add('navigate_to', (page) => {
|
||||
return cy.get(navigation.section, { timeout: 10000 }).within(() => {
|
||||
cy.get(navigation[page]).click({ force: true });
|
||||
|
||||
@@ -15,12 +15,6 @@ Cypress.Commands.add('vega_wallet_import', () => {
|
||||
cy.exec(
|
||||
`vega wallet service run --network DV --automatic-consent --home ${vegaWalletLocation}`
|
||||
);
|
||||
|
||||
cy.exec(`vega wallet version`)
|
||||
.its('stdout')
|
||||
.then((output) => {
|
||||
cy.log(output);
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add('vega_wallet_connect', () => {
|
||||
|
||||
@@ -7,3 +7,4 @@ NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
|
||||
|
||||
@@ -7,3 +7,4 @@ NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/mainnet
|
||||
|
||||
@@ -7,6 +7,7 @@ NX_VEGA_ENV=STAGNET3
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.token.vega.xyz","STAGNET3":"https://stagnet3.token.vega.xyz","TESTNET":"https://token.fairground.wtf","MAINNET":"https://token.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/stagnet3-network.json
|
||||
NX_VEGA_EXPLORER_URL=https://staging3.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
|
||||
|
||||
# App flags
|
||||
NX_EXPLORER_ASSETS=1
|
||||
|
||||
@@ -7,3 +7,4 @@ NX_ETHEREUM_PROVIDER_URL=https://ropsten.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://ropsten.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/docs/testnet
|
||||
|
||||
@@ -12,7 +12,7 @@ import { AccountType } from "@vegaprotocol/types";
|
||||
export interface Delegations_epoch {
|
||||
__typename: "Epoch";
|
||||
/**
|
||||
* Presumably this is an integer or something. If there's no such thing, disregard
|
||||
* Numeric sequence number used to identify the epoch
|
||||
*/
|
||||
id: string;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export interface Delegations_party {
|
||||
|
||||
export interface Delegations {
|
||||
/**
|
||||
* get data for a specific epoch, if ID omitted it gets the current epoch. If the string is 'next', fetch the next epoch
|
||||
* Get data for a specific epoch, if ID omitted it gets the current epoch. If the string is 'next', fetch the next epoch
|
||||
*/
|
||||
epoch: Delegations_epoch;
|
||||
/**
|
||||
|
||||
@@ -48,6 +48,8 @@ export const ENV = {
|
||||
// Environment
|
||||
dsn: windowOrDefault('NX_SENTRY_DSN'),
|
||||
urlConnect: TRUTHY.includes(windowOrDefault('NX_ETH_URL_CONNECT')),
|
||||
explorerUrl: windowOrDefault('NX_VEGA_EXPLORER'),
|
||||
docsUrl: windowOrDefault('NX_VEGA_DOCS_URL'),
|
||||
ethWalletMnemonic: windowOrDefault('NX_ETH_WALLET_MNEMONIC'),
|
||||
localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'),
|
||||
flags: {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from './flags';
|
||||
export * from './links';
|
||||
export * from './network-params';
|
||||
export * from './env';
|
||||
|
||||
@@ -11,4 +11,5 @@ export const Links = {
|
||||
STAKING_GUIDE:
|
||||
'https://docs.vega.xyz/docs/mainnet/concepts/vega-chain/#staking-on-vega',
|
||||
GOVERNANCE_PAGE: 'https://vega.xyz/governance',
|
||||
PROPOSALS_GUIDE: 'https://docs.vega.xyz/docs/mainnet/tutorials/proposals',
|
||||
};
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
export const NetworkParams = {
|
||||
ETHEREUM_CONFIG: 'blockchains.ethereumConfig',
|
||||
REWARD_ASSET: 'reward.asset',
|
||||
REWARD_PAYOUT_DURATION: 'reward.staking.delegation.payoutDelay',
|
||||
GOV_UPDATE_MARKET_REQUIRED_MAJORITY:
|
||||
'governance.proposal.updateMarket.requiredMajority',
|
||||
GOV_UPDATE_MARKET_REQUIRED_PARTICIPATION:
|
||||
'governance.proposal.updateMarket.requiredParticipation',
|
||||
GOV_NEW_MARKET_REQUIRED_MAJORITY:
|
||||
'governance.proposal.market.requiredMajority',
|
||||
GOV_NEW_MARKET_REQUIRED_PARTICIPATION:
|
||||
'governance.proposal.market.requiredParticipation',
|
||||
GOV_ASSET_REQUIRED_MAJORITY: 'governance.proposal.asset.requiredMajority',
|
||||
GOV_ASSET_REQUIRED_PARTICIPATION:
|
||||
'governance.proposal.asset.requiredParticipation',
|
||||
GOV_UPDATE_NET_PARAM_REQUIRED_MAJORITY:
|
||||
'governance.proposal.updateNetParam.requiredMajority',
|
||||
GOV_UPDATE_NET_PARAM_REQUIRED_PARTICIPATION:
|
||||
'governance.proposal.updateNetParam.requiredParticipation',
|
||||
GOV_FREEFORM_REQUIRED_PARTICIPATION:
|
||||
'governance.proposal.freeform.requiredParticipation',
|
||||
GOV_FREEFORM_REQUIRED_MAJORITY:
|
||||
'governance.proposal.freeform.requiredMajority',
|
||||
VALIDATOR_DELEGATION_MIN_AMOUNT: 'validators.delegation.minAmount',
|
||||
};
|
||||
@@ -630,8 +630,62 @@
|
||||
"FilterProposalsDescription": "Filter by proposal ID or proposer ID",
|
||||
"Freeform proposal": "Freeform proposal",
|
||||
"NewProposal": "New proposal",
|
||||
"MinProposalRequirements": "You must have at least 1 VEGA associated to make a proposal",
|
||||
"ProposalTypeQuestion": "What type of proposal would you like to make?",
|
||||
"NetworkParameterProposal": "Update network parameter proposal",
|
||||
"NewMarketProposal": "New market proposal",
|
||||
"UpdateMarketProposal": "Update market proposal",
|
||||
"NewAssetProposal": "New asset proposal",
|
||||
"NewFreeformProposal": "New freeform proposal",
|
||||
"NewRawProposal": "New raw proposal",
|
||||
"MinProposalRequirements": "You must have at least {{value}} VEGA associated to make a proposal",
|
||||
"totalSupply": "Total Supply",
|
||||
"viaWallet": "via wallet",
|
||||
"viaContract": "via vesting"
|
||||
"viaContract": "via vesting",
|
||||
"ProposalDocsPrefix": "For guidance on how to make proposals, see",
|
||||
"NetworkParameter": "Network parameter",
|
||||
"NewMarket": "New market",
|
||||
"UpdateMarket": "Update market",
|
||||
"NewAsset": "New asset",
|
||||
"Freeform": "Freeform",
|
||||
"RawProposal": "Let me choose (raw proposal)",
|
||||
"UseMin": "Use minimum",
|
||||
"UseMax": "Use maximum",
|
||||
"Proposal": "Proposal",
|
||||
"ProposalRationale": "Proposal rationale",
|
||||
"ProposalTitle": "Title",
|
||||
"ProposalTitleText": "Tell people what you are proposing and why (100 characters or less)",
|
||||
"ProposalsGuide": "proposals guide",
|
||||
"ProposalDescription": "Description",
|
||||
"ProposalDescriptionText": "Full justification for what you are proposing (20,000 characters or less). Markdown is recommended. When linking to external resources please use IPFS",
|
||||
"ProposalTerms": "Proposal terms (JSON format)",
|
||||
"ProposalTermsText": "For more information visit",
|
||||
"ProposalReference": "Reference",
|
||||
"ProposalVoteTitle": "Vote deadline",
|
||||
"ProposalVoteAndEnactmentTitle": "Vote deadline and enactment",
|
||||
"ProposalVoteDeadline": "Time till voting closes",
|
||||
"ProposalEnactmentDeadline": "Time till enactment (after vote close)",
|
||||
"ProposalValidationDeadline": "Time till ERC-20 asset validation. Maximum value is affected by the vote deadline.",
|
||||
"ThisWillSetVotingDeadlineTo": "This will set the voting deadline to",
|
||||
"ThisWillSetEnactmentDeadlineTo": "This will set the enactment date to",
|
||||
"ThisWillSetValidationDeadlineTo": "This will set the validation deadline to",
|
||||
"Hours": "hours",
|
||||
"ThisWillAdd2MinutesToAllowTimeToConfirmInWallet": "Note: we add 2 minutes of extra time when you choose the minimum value. This gives you time to confirm the proposal in your wallet.",
|
||||
"SelectAMarketToChange": "Select a market to change",
|
||||
"MarketName": "Market name",
|
||||
"MarketCode": "Market code",
|
||||
"MarketId": "Market ID",
|
||||
"ProposeNewMarketTerms": "terms.changes.newMarket (JSON format)",
|
||||
"ProposeUpdateMarketTerms": "terms.updateMarket.changes (JSON format)",
|
||||
"SelectAParameterToChange": "Select a parameter to change",
|
||||
"SelectParameter": "Select parameter",
|
||||
"SelectMarket": "Select market",
|
||||
"CurrentValue": "Current value",
|
||||
"NewProposedValue": "New proposed value",
|
||||
"MoreProposalsInfo": "To see Explorer data on proposals visit",
|
||||
"MoreNetParamsInfo": "To see Explorer data on network params visit",
|
||||
"MoreMarketsInfo": "To see Explorer data on existing markets visit",
|
||||
"MoreAssetsInfo": "To see Explorer data on existing assets visit",
|
||||
"ProposalNotFound": "Proposal not found",
|
||||
"ProposalNotFoundDetails": "The proposal you are looking for is not here, it may have been enacted before the last chain restore. You could check the Vega forums/discord instead for information about it.",
|
||||
"FreeformProposal": "Freeform proposal"
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { Heading } from '../../components/heading';
|
||||
import { SplashLoader } from '../../components/splash-loader';
|
||||
import { ENV } from '../../config/env';
|
||||
import type { RouteChildProps } from '../index';
|
||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||
|
||||
const Contracts = () => {
|
||||
const Contracts = ({ name }: RouteChildProps) => {
|
||||
useDocumentTitle(name);
|
||||
const { config } = useEthereumConfig();
|
||||
const { ETHERSCAN_URL } = useEnvironment();
|
||||
|
||||
|
||||
@@ -49,6 +49,15 @@ fragment ProposalFields on Proposal {
|
||||
value
|
||||
}
|
||||
}
|
||||
... on UpdateAsset {
|
||||
quantum
|
||||
source {
|
||||
... on UpdateERC20 {
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
votes {
|
||||
|
||||
@@ -33,8 +33,8 @@ export interface ProposalFields_party {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface ProposalFields_terms_change_UpdateAsset {
|
||||
__typename: "UpdateAsset" | "NewFreeform";
|
||||
export interface ProposalFields_terms_change_NewFreeform {
|
||||
__typename: "NewFreeform";
|
||||
}
|
||||
|
||||
export interface ProposalFields_terms_change_NewMarket_instrument_futureProduct_settlementAsset {
|
||||
@@ -133,7 +133,33 @@ export interface ProposalFields_terms_change_UpdateNetworkParameter {
|
||||
networkParameter: ProposalFields_terms_change_UpdateNetworkParameter_networkParameter;
|
||||
}
|
||||
|
||||
export type ProposalFields_terms_change = ProposalFields_terms_change_UpdateAsset | ProposalFields_terms_change_NewMarket | ProposalFields_terms_change_UpdateMarket | ProposalFields_terms_change_NewAsset | ProposalFields_terms_change_UpdateNetworkParameter;
|
||||
export interface ProposalFields_terms_change_UpdateAsset_source {
|
||||
__typename: "UpdateERC20";
|
||||
/**
|
||||
* The lifetime limits deposit per address
|
||||
* Note: this is a temporary measure for alpha mainnet
|
||||
*/
|
||||
lifetimeLimit: string;
|
||||
/**
|
||||
* The maximum allowed per withdrawal
|
||||
* Note: this is a temporary measure for alpha mainnet
|
||||
*/
|
||||
withdrawThreshold: string;
|
||||
}
|
||||
|
||||
export interface ProposalFields_terms_change_UpdateAsset {
|
||||
__typename: "UpdateAsset";
|
||||
/**
|
||||
* The minimum economically meaningful amount of this specific asset
|
||||
*/
|
||||
quantum: string;
|
||||
/**
|
||||
* The source of the updated asset
|
||||
*/
|
||||
source: ProposalFields_terms_change_UpdateAsset_source;
|
||||
}
|
||||
|
||||
export type ProposalFields_terms_change = ProposalFields_terms_change_NewFreeform | ProposalFields_terms_change_NewMarket | ProposalFields_terms_change_UpdateMarket | ProposalFields_terms_change_NewAsset | ProposalFields_terms_change_UpdateNetworkParameter | ProposalFields_terms_change_UpdateAsset;
|
||||
|
||||
export interface ProposalFields_terms {
|
||||
__typename: "ProposalTerms";
|
||||
@@ -293,7 +319,7 @@ export interface ProposalFields {
|
||||
*/
|
||||
datetime: string;
|
||||
/**
|
||||
* Reason for the proposal to be rejected by the core
|
||||
* Why the proposal was rejected by the core
|
||||
*/
|
||||
rejectionReason: ProposalRejectionReason | null;
|
||||
/**
|
||||
|
||||
@@ -3,19 +3,19 @@ import { Schema as Types } from '@vegaprotocol/types';
|
||||
import { gql } from '@apollo/client';
|
||||
import * as Apollo from '@apollo/client';
|
||||
const defaultOptions = {} as const;
|
||||
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } };
|
||||
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset', quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } };
|
||||
|
||||
export type ProposalQueryVariables = Types.Exact<{
|
||||
proposalId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ProposalQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } } | null };
|
||||
export type ProposalQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset', quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } } | null };
|
||||
|
||||
export type ProposalsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type ProposalsQuery = { __typename?: 'Query', proposals?: Array<{ __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } }> | null };
|
||||
export type ProposalsQuery = { __typename?: 'Query', proposals?: Array<{ __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: string, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: string, enactmentDatetime?: string | null, change: { __typename: 'NewAsset', name: string, symbol: string, source: { __typename: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename: 'ERC20', contractAddress: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', decimalPlaces: number, metadata?: Array<string> | null, instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'UpdateAsset', quantum: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, votes?: Array<{ __typename?: 'Vote', value: Types.VoteValue, datetime: string, party: { __typename?: 'Party', id: string, stake: { __typename?: 'PartyStake', currentStakeAvailable: string } } }> | null } } }> | null };
|
||||
|
||||
export const ProposalFieldsFragmentDoc = gql`
|
||||
fragment ProposalFields on Proposal {
|
||||
@@ -69,6 +69,15 @@ export const ProposalFieldsFragmentDoc = gql`
|
||||
value
|
||||
}
|
||||
}
|
||||
... on UpdateAsset {
|
||||
quantum
|
||||
source {
|
||||
... on UpdateERC20 {
|
||||
lifetimeLimit
|
||||
withdrawThreshold
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
votes {
|
||||
|
||||
+3
-4
@@ -63,7 +63,7 @@ export const CurrentProposalStatus = ({
|
||||
<>
|
||||
<span>{t('voteFailedReason')}</span>
|
||||
<StatusFail>{t('participationNotMet')}</StatusFail>
|
||||
<span> {daysClosedAgo}.</span>
|
||||
<span> {daysClosedAgo}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export const CurrentProposalStatus = ({
|
||||
<>
|
||||
<span>{t('voteFailedReason')}</span>
|
||||
<StatusFail>{t('majorityNotMet')}</StatusFail>
|
||||
<span> {daysClosedAgo}.</span>
|
||||
<span> {daysClosedAgo}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ export const CurrentProposalStatus = ({
|
||||
<>
|
||||
<span>{t('voteFailedReason')}</span>
|
||||
<StatusFail>{proposal.state}</StatusFail>
|
||||
<span> {daysClosedAgo}.</span>
|
||||
<span> {daysClosedAgo}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -99,7 +99,6 @@ export const CurrentProposalStatus = ({
|
||||
{proposal.state === ProposalState.STATE_ENACTED
|
||||
? daysEnactedAgo
|
||||
: daysClosedAgo}
|
||||
.
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
|
||||
+22
@@ -79,6 +79,28 @@ it('Changes data based on if data is in future or past', () => {
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Does not render enactment time for freeform proposal', () => {
|
||||
const proposal = generateProposal({
|
||||
state: ProposalState.STATE_ENACTED,
|
||||
terms: {
|
||||
__typename: 'ProposalTerms',
|
||||
change: {
|
||||
__typename: 'NewFreeform',
|
||||
},
|
||||
},
|
||||
});
|
||||
render(<ProposalChangeTable proposal={proposal} />);
|
||||
expect(screen.queryByText('Enacted on')).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(
|
||||
format(
|
||||
new Date(proposal.terms.enactmentDatetime || 0),
|
||||
DATE_FORMAT_DETAILED
|
||||
)
|
||||
)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders error details and rejection reason if present', () => {
|
||||
const errorDetails = 'Error message';
|
||||
const proposal = generateProposal({
|
||||
|
||||
+8
-6
@@ -31,12 +31,14 @@ export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
|
||||
: t('closedOn')}
|
||||
{format(new Date(terms.closingDatetime), DATE_FORMAT_DETAILED)}
|
||||
</KeyValueTableRow>
|
||||
<KeyValueTableRow>
|
||||
{isFuture(new Date(terms.enactmentDatetime || 0))
|
||||
? t('proposedEnactment')
|
||||
: t('enactedOn')}
|
||||
{format(new Date(terms.enactmentDatetime || 0), DATE_FORMAT_DETAILED)}
|
||||
</KeyValueTableRow>
|
||||
{terms.change.__typename !== 'NewFreeform' ? (
|
||||
<KeyValueTableRow>
|
||||
{isFuture(new Date(terms.enactmentDatetime || 0))
|
||||
? t('proposedEnactment')
|
||||
: t('enactedOn')}
|
||||
{format(new Date(terms.enactmentDatetime || 0), DATE_FORMAT_DETAILED)}
|
||||
</KeyValueTableRow>
|
||||
) : null}
|
||||
<KeyValueTableRow>
|
||||
{t('proposedBy')}
|
||||
<span style={{ wordBreak: 'break-word' }}>{proposal.party.id}</span>
|
||||
|
||||
+19
-2
@@ -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 { ProposalFields } from '../../__generated__/ProposalFields';
|
||||
|
||||
const renderComponent = (proposal: Proposal_proposal) => (
|
||||
const renderComponent = (proposal: ProposalFields) => (
|
||||
<ProposalHeader proposal={proposal} />
|
||||
);
|
||||
|
||||
@@ -234,6 +234,23 @@ describe('Proposal header', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Renders asset change proposal header', () => {
|
||||
render(
|
||||
renderComponent(
|
||||
generateProposal({
|
||||
terms: {
|
||||
change: {
|
||||
__typename: 'UpdateAsset',
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
expect(screen.getByTestId('proposal-details')).toHaveTextContent(
|
||||
'Update asset'
|
||||
);
|
||||
});
|
||||
|
||||
it("Renders unknown proposal if it's a different proposal type", () => {
|
||||
render(
|
||||
renderComponent(
|
||||
|
||||
+5
-2
@@ -73,8 +73,11 @@ export const ProposalHeader = ({ proposal }: { proposal: ProposalFields }) => {
|
||||
break;
|
||||
}
|
||||
case 'NewFreeform': {
|
||||
details = `${proposal.id}`;
|
||||
|
||||
details = `${t('FreeformProposal')}: ${proposal.id}`;
|
||||
break;
|
||||
}
|
||||
case 'UpdateAsset': {
|
||||
details = `${t('Update asset')}`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { ProposalNotFound } from './proposal-not-found';
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalNotFound } from './proposal-not-found';
|
||||
|
||||
describe('Proposal container', () => {
|
||||
it('Renders not found if the proposal is not found', () => {
|
||||
render(<ProposalNotFound />);
|
||||
expect(screen.getByText('Proposal not found')).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(
|
||||
'The proposal you are looking for is not here, it may have been enacted before the last chain restore. You could check the Vega forums/discord instead for information about it.'
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ProposalNotFound = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<section data-testid="proposal-not-found">
|
||||
<header>
|
||||
<h2 className="text-lg mx-0 mt-0 mb-1 font-semibold">
|
||||
{t('ProposalNotFound')}
|
||||
</h2>
|
||||
</header>
|
||||
<p>{t('ProposalNotFoundDetails')}</p>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export * from './proposal-form-subheader';
|
||||
export * from './proposal-form-min-requirements';
|
||||
export * from './proposal-form-title';
|
||||
export * from './proposal-form-description';
|
||||
export * from './proposal-form-terms';
|
||||
export * from './proposal-form-submit';
|
||||
export * from './proposal-form-transaction-dialog';
|
||||
export * from './proposal-form-vote-and-enactment-deadline';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalFormDescription } from './proposal-form-description';
|
||||
|
||||
describe('Proposal Form Description', () => {
|
||||
it('should display error text', () => {
|
||||
const register = jest.fn();
|
||||
render(
|
||||
<ProposalFormDescription
|
||||
registerField={register('proposalDescription')}
|
||||
errorMessage="Error text"
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('Error text')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FormGroup, InputError, TextArea } from '@vegaprotocol/ui-toolkit';
|
||||
import type { UseFormRegisterReturn } from 'react-hook-form';
|
||||
|
||||
interface ProposalFormDescriptionProps {
|
||||
registerField: UseFormRegisterReturn<'proposalDescription'>;
|
||||
errorMessage: string | undefined;
|
||||
}
|
||||
|
||||
export const ProposalFormDescription = ({
|
||||
registerField: register,
|
||||
errorMessage,
|
||||
}: ProposalFormDescriptionProps) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<FormGroup
|
||||
label={t('ProposalDescription')}
|
||||
labelDescription={t('ProposalDescriptionText')}
|
||||
labelFor="proposal-description"
|
||||
>
|
||||
<TextArea
|
||||
id="proposal-description"
|
||||
maxLength={20000}
|
||||
className="min-h-[200px]"
|
||||
hasError={Boolean(errorMessage)}
|
||||
data-testid="proposal-description"
|
||||
{...register}
|
||||
/>
|
||||
{errorMessage && <InputError intent="danger">{errorMessage}</InputError>}
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import { ProposalFormMinRequirements } from './proposal-form-min-requirements';
|
||||
|
||||
describe('ProposalFormMinRequirements', () => {
|
||||
it('should render successfully with spam protection value, if larger', () => {
|
||||
const { baseElement } = render(
|
||||
<ProposalFormMinRequirements
|
||||
minProposerBalance="1000000000000000000"
|
||||
spamProtectionMin="2000000000000000000"
|
||||
/>
|
||||
);
|
||||
expect(baseElement).toBeTruthy();
|
||||
|
||||
expect(baseElement).toHaveTextContent(
|
||||
'You must have at least 2 VEGA associated to make a proposal'
|
||||
);
|
||||
});
|
||||
|
||||
it('should render successfully with min proposer value, if larger', () => {
|
||||
const { baseElement } = render(
|
||||
<ProposalFormMinRequirements
|
||||
minProposerBalance="3000000000000000000"
|
||||
spamProtectionMin="1000000000000000000"
|
||||
/>
|
||||
);
|
||||
expect(baseElement).toBeTruthy();
|
||||
|
||||
expect(baseElement).toHaveTextContent(
|
||||
'You must have at least 3 VEGA associated to make a proposal'
|
||||
);
|
||||
});
|
||||
});
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface ProposalFormMinRequirementsProps {
|
||||
minProposerBalance: string | undefined;
|
||||
spamProtectionMin: string | undefined;
|
||||
}
|
||||
|
||||
export const ProposalFormMinRequirements = ({
|
||||
minProposerBalance,
|
||||
spamProtectionMin,
|
||||
}: ProposalFormMinRequirementsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const minProposerBalanceFormatted =
|
||||
minProposerBalance && new BigNumber(addDecimal(minProposerBalance, 18));
|
||||
const spamProtectionMinFormatted =
|
||||
spamProtectionMin && new BigNumber(addDecimal(spamProtectionMin, 18));
|
||||
|
||||
const larger =
|
||||
Number(minProposerBalanceFormatted) > (spamProtectionMinFormatted || 0)
|
||||
? minProposerBalanceFormatted
|
||||
: spamProtectionMinFormatted;
|
||||
|
||||
return (
|
||||
<p className="mb-4" data-testid="min-proposal-requirements">
|
||||
{t('MinProposalRequirements', { value: larger })}
|
||||
</p>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
interface ProposalFormSubheaderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const ProposalFormSubheader = ({
|
||||
children,
|
||||
}: ProposalFormSubheaderProps) => <h2 className="mt-8 mb-4">{children}</h2>;
|
||||
@@ -0,0 +1,24 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
interface ProposalFormSubmitProps {
|
||||
isSubmitting: boolean;
|
||||
}
|
||||
|
||||
export const ProposalFormSubmit = ({
|
||||
isSubmitting,
|
||||
}: ProposalFormSubmitProps) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div className="mt-10 my-20">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="submit"
|
||||
data-testid="proposal-submit"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
{isSubmitting ? t('Submitting') : t('Submit')} {t('Proposal')}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalFormTerms } from './proposal-form-terms';
|
||||
|
||||
jest.mock('@vegaprotocol/environment', () => ({
|
||||
useEnvironment: () => ({
|
||||
VEGA_DOCS_URL: 'https://docs.vega.xyz',
|
||||
}),
|
||||
}));
|
||||
|
||||
const renderComponent = () => {
|
||||
const register = jest.fn();
|
||||
render(
|
||||
<ProposalFormTerms
|
||||
registerField={register('proposalTerms')}
|
||||
errorMessage="Error text"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
describe('Proposal Form Terms', () => {
|
||||
it('should render', () => {
|
||||
renderComponent();
|
||||
expect(screen.getByTestId('proposal-terms')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display error text', () => {
|
||||
renderComponent();
|
||||
expect(screen.getByText('Error text')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the generic docs link if no custom override', () => {
|
||||
renderComponent();
|
||||
expect(
|
||||
screen.getByText('https://docs.vega.xyz/tutorials/proposals')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the custom docs link if provided', () => {
|
||||
const register = jest.fn();
|
||||
render(
|
||||
<ProposalFormTerms
|
||||
registerField={register('proposalTerms')}
|
||||
errorMessage="Error text"
|
||||
customDocLink="/custom"
|
||||
/>
|
||||
);
|
||||
expect(
|
||||
screen.getByText('https://docs.vega.xyz/tutorials/proposals/custom')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
FormGroup,
|
||||
InputError,
|
||||
Link,
|
||||
TextArea,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import type { UseFormRegisterReturn } from 'react-hook-form';
|
||||
|
||||
interface ProposalFormTermsProps {
|
||||
registerField: UseFormRegisterReturn<'proposalTerms'>;
|
||||
errorMessage: string | undefined;
|
||||
labelOverride?: string;
|
||||
customDocLink?: string;
|
||||
}
|
||||
|
||||
export const ProposalFormTerms = ({
|
||||
registerField: register,
|
||||
errorMessage,
|
||||
labelOverride,
|
||||
customDocLink,
|
||||
}: ProposalFormTermsProps) => {
|
||||
const { VEGA_DOCS_URL } = useEnvironment();
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<FormGroup
|
||||
label={labelOverride || t('ProposalTerms')}
|
||||
labelFor="proposal-terms"
|
||||
>
|
||||
{VEGA_DOCS_URL && (
|
||||
<div className="mt-[-4px] mb-2 text-sm font-light">
|
||||
<span className="mr-1">{t('ProposalTermsText')}</span>
|
||||
<Link
|
||||
href={`${VEGA_DOCS_URL}/tutorials/proposals${customDocLink || ''}`}
|
||||
target="_blank"
|
||||
>{`${VEGA_DOCS_URL}/tutorials/proposals${customDocLink || ''}`}</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<TextArea
|
||||
id="proposal-terms"
|
||||
className="min-h-[200px]"
|
||||
hasError={Boolean(errorMessage)}
|
||||
data-testid="proposal-terms"
|
||||
{...register}
|
||||
/>
|
||||
{errorMessage && <InputError intent="danger">{errorMessage}</InputError>}
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ProposalFormTitle } from './proposal-form-title';
|
||||
|
||||
describe('Proposal Form Title', () => {
|
||||
it('should display error text', () => {
|
||||
const register = jest.fn();
|
||||
render(
|
||||
<ProposalFormTitle
|
||||
registerField={register('proposalTitle')}
|
||||
errorMessage="Error text"
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('Error text')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user