Compare commits
217
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18f8d5e648 | ||
|
|
261f32aa5b | ||
|
|
053775bef6 | ||
|
|
0660eda334 | ||
|
|
f22a3bc2d2 | ||
|
|
fde77ebccb | ||
|
|
e309669736 | ||
|
|
b1621d1191 | ||
|
|
39907f07db | ||
|
|
3dab5f3d9b | ||
|
|
3cf9ae7582 | ||
|
|
557894e2ef | ||
|
|
baf9875c69 | ||
|
|
51199b02ce | ||
|
|
bb826c88f0 | ||
|
|
0da20b750f | ||
|
|
e16c447564 | ||
|
|
a2170d27d6 | ||
|
|
00d840b7b3 | ||
|
|
2a4a05630f | ||
|
|
97f1f40f2c | ||
|
|
a8e6963521 | ||
|
|
a2bffa1dfd | ||
|
|
9253e8067a | ||
|
|
58972f0a11 | ||
|
|
a3c55fd7c3 | ||
|
|
c63cba1071 | ||
|
|
bc9d87fe30 | ||
|
|
6a21862378 | ||
|
|
0fb4348e9c | ||
|
|
b751bcf17d | ||
|
|
d32f27fcb1 | ||
|
|
d05cd6a2ed | ||
|
|
c003e5fa30 | ||
|
|
f62d3289ab | ||
|
|
a3d3d18c5c | ||
|
|
77ca101781 | ||
|
|
d238c37d0c | ||
|
|
79feb485f6 | ||
|
|
6aa5c3b6e3 | ||
|
|
82abc13fda | ||
|
|
933f07cddf | ||
|
|
c8067669c2 | ||
|
|
78f5a9c520 | ||
|
|
462066959d | ||
|
|
f12f5ab961 | ||
|
|
98b2460d8b | ||
|
|
67c182f3de | ||
|
|
68e0009ab0 | ||
|
|
ad74b12908 | ||
|
|
7fff33e493 | ||
|
|
e7cb2c8276 | ||
|
|
4adaeea40a | ||
|
|
d47d894147 | ||
|
|
515932d401 | ||
|
|
723ff2805d | ||
|
|
424cced4be | ||
|
|
b2c7ee82c5 | ||
|
|
4cc63be4f9 | ||
|
|
9fbb7a13e6 | ||
|
|
1874095222 | ||
|
|
e459e92127 | ||
|
|
4dd65b4923 | ||
|
|
5d792d2458 | ||
|
|
59b2f75b13 | ||
|
|
95775679ca | ||
|
|
4cffee29f8 | ||
|
|
bd70b0c233 | ||
|
|
145792f216 | ||
|
|
10add7c236 | ||
|
|
362a2031c7 | ||
|
|
5aaeb87059 | ||
|
|
d240dddab5 | ||
|
|
0af1d0ba82 | ||
|
|
665ab6693a | ||
|
|
902ee2696c | ||
|
|
3beeb0140c | ||
|
|
4b208e90bf | ||
|
|
ec837854cf | ||
|
|
8b94a75ba4 | ||
|
|
08c57b6759 | ||
|
|
bb2184498f | ||
|
|
8b07ce3024 | ||
|
|
8a110584dd | ||
|
|
b82615a3d8 | ||
|
|
f178b85846 | ||
|
|
0796f2b31f | ||
|
|
67be224138 | ||
|
|
51c426ef4b | ||
|
|
fa28d31ef3 | ||
|
|
201a586b05 | ||
|
|
7d96d9bcd1 | ||
|
|
345be81142 | ||
|
|
2221e9faca | ||
|
|
7c0139e107 | ||
|
|
a157ff1e05 | ||
|
|
2e9fa0c52e | ||
|
|
c0790c1e93 | ||
|
|
13c1044f8e | ||
|
|
cf9f313e4c | ||
|
|
f56d34fe6e | ||
|
|
1379366caa | ||
|
|
8958c12fe3 | ||
|
|
fef13874db | ||
|
|
40f02ecf89 | ||
|
|
41cd6b1455 | ||
|
|
3cd393dac0 | ||
|
|
a52e60d6a2 | ||
|
|
bc13f1b359 | ||
|
|
eb81f4ae44 | ||
|
|
51ab02a2e2 | ||
|
|
ffada1b93d | ||
|
|
9dda3f712b | ||
|
|
df20dbeee0 | ||
|
|
cdfd8a2d00 | ||
|
|
1e5c523bc4 | ||
|
|
37cd69ba6e | ||
|
|
2c11045dd9 | ||
|
|
9aef41a119 | ||
|
|
80ab8821d0 | ||
|
|
8a3657a9b9 | ||
|
|
7100b0e9fc | ||
|
|
614a83b7d6 | ||
|
|
3dc77b0eff | ||
|
|
a59f7dfd29 | ||
|
|
61471228aa | ||
|
|
127e784ceb | ||
|
|
70d748fb15 | ||
|
|
e06f4818fc | ||
|
|
8182da3b31 | ||
|
|
c8c56307bb | ||
|
|
a8cd7f157f | ||
|
|
4f18caa486 | ||
|
|
5c7c626bbc | ||
|
|
e4c4c20631 | ||
|
|
0697302d07 | ||
|
|
2d926c0ce0 | ||
|
|
f57d6a7c7b | ||
|
|
15f905046f | ||
|
|
4f7918f64e | ||
|
|
52ab0562b0 | ||
|
|
4e2b0d1b1d | ||
|
|
0b0bcad9b3 | ||
|
|
bcf17bb34e | ||
|
|
a2b9b0da05 | ||
|
|
7588d0cd11 | ||
|
|
5ee1748495 | ||
|
|
73a118978f | ||
|
|
eac26c1966 | ||
|
|
d615587564 | ||
|
|
ba4ce1ce88 | ||
|
|
3bbacc1aa0 | ||
|
|
de5371435d | ||
|
|
12cb5e10b6 | ||
|
|
ee2909cc84 | ||
|
|
068d6abf1b | ||
|
|
e5d4d2b0b8 | ||
|
|
d4e801cfc6 | ||
|
|
964deb2f23 | ||
|
|
6669125dd3 | ||
|
|
129b6c4e89 | ||
|
|
ca418cabfe | ||
|
|
192af844c4 | ||
|
|
6a841f226a | ||
|
|
76426baa2a | ||
|
|
6fdac2419c | ||
|
|
87807d2088 | ||
|
|
a5f2533a66 | ||
|
|
1e9251c9c0 | ||
|
|
2a27e124d7 | ||
|
|
4ee85720ab | ||
|
|
a19da4c408 | ||
|
|
65ad4fffda | ||
|
|
11317cdb2e | ||
|
|
c98870f27d | ||
|
|
c0c56e4c48 | ||
|
|
a9ca215276 | ||
|
|
61a9eb2f5c | ||
|
|
bb47747501 | ||
|
|
5827b87f89 | ||
|
|
19b95832c4 | ||
|
|
48e4ab53a1 | ||
|
|
cefcff040f | ||
|
|
c3ef639daf | ||
|
|
b6052bc3e5 | ||
|
|
6e8894936e | ||
|
|
66f55855ae | ||
|
|
5725b824ad | ||
|
|
9344a2abc0 | ||
|
|
fae66ca4ce | ||
|
|
31524ac7a7 | ||
|
|
ea3e5a7651 | ||
|
|
b062339682 | ||
|
|
824bcf89bd | ||
|
|
f315917094 | ||
|
|
8e898cfd78 | ||
|
|
f377e07996 | ||
|
|
090d340364 | ||
|
|
6d32fa7362 | ||
|
|
1a7682c3c9 | ||
|
|
3294c0cabe | ||
|
|
c10084d441 | ||
|
|
96658134ee | ||
|
|
a070504d2e | ||
|
|
f891caf08b | ||
|
|
69bdc637e5 | ||
|
|
78add88014 | ||
|
|
02c425f304 | ||
|
|
06769f25cf | ||
|
|
b3014bb98a | ||
|
|
132f2e4b2b | ||
|
|
374890dc08 | ||
|
|
7f95ba577e | ||
|
|
2f7e53e282 | ||
|
|
568dcd5305 | ||
|
|
9605b0e7fa | ||
|
|
0776332ba7 |
+3
-1
@@ -73,9 +73,11 @@
|
|||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"prefer": "type-imports",
|
"prefer": "type-imports",
|
||||||
"disallowTypeAnnotations": true
|
"disallowTypeAnnotations": true,
|
||||||
|
"fixStyle": "inline-type-imports"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"@typescript-eslint/no-useless-constructor": 0,
|
||||||
"curly": ["error", "multi-line"]
|
"curly": ["error", "multi-line"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
* text eol=lf
|
* text eol=lf
|
||||||
*.png binary
|
*.png binary
|
||||||
*.ico binary
|
*.ico binary
|
||||||
|
*.woff2 binary
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
${{ runner.os }}-cache-node-modules-
|
${{ runner.os }}-cache-node-modules-
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
if: steps.cache.outputs.cache-hit != 'true'
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
@@ -57,7 +57,7 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
@@ -96,7 +96,7 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -128,7 +128,7 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
@@ -182,7 +182,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
if [[ "${{ github.base_ref }}" == "develop" ]]; then
|
if [[ "${{ github.base_ref }}" == "develop" ]]; then
|
||||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
elif [[ "${{ github.base_ref }}" == "main" ]]; then
|
elif [[ "${{ github.base_ref }}" == "main" ]]; then
|
||||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
|
elif [[ "${{ github.event_name }}" == "push" && "${{ github.ref_name }}" == *"release/"* ]]; then
|
||||||
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
echo "e2e-needed=true" >> $GITHUB_OUTPUT
|
||||||
@@ -205,7 +205,7 @@ jobs:
|
|||||||
|
|
||||||
console-e2e:
|
console-e2e:
|
||||||
needs: [build-sources, check-e2e-needed]
|
needs: [build-sources, check-e2e-needed]
|
||||||
name: '(CI) console python'
|
name: '(CI) trading e2e python'
|
||||||
uses: ./.github/workflows/console-test-run.yml
|
uses: ./.github/workflows/console-test-run.yml
|
||||||
secrets: inherit
|
secrets: inherit
|
||||||
if: needs.check-e2e-needed.outputs.run-tests == 'true' && contains(needs.build-sources.outputs.projects, 'trading')
|
if: needs.check-e2e-needed.outputs.run-tests == 'true' && contains(needs.build-sources.outputs.projects, 'trading')
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ on:
|
|||||||
inputs:
|
inputs:
|
||||||
console-test-branch:
|
console-test-branch:
|
||||||
type: choice
|
type: choice
|
||||||
description: 'main: v0.72.14, develop: v0.73.0-preview7'
|
description: 'main: v0.73.5, develop: v0.73.5'
|
||||||
options:
|
options:
|
||||||
- main
|
- main
|
||||||
- develop
|
- develop
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
create-docker-image:
|
create-docker-image:
|
||||||
name: Create docker image for console-test
|
name: Create docker image for console-test
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
timeout-minutes: 20
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# check-out frontend-monorepo
|
# check-out frontend-monorepo
|
||||||
@@ -32,9 +32,9 @@ jobs:
|
|||||||
# cache node modules
|
# cache node modules
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: setup node
|
- name: setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version-file: '.nvmrc'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Cache node modules
|
||||||
@@ -138,7 +138,7 @@ jobs:
|
|||||||
name: run-tests
|
name: run-tests
|
||||||
runs-on: 8-cores
|
runs-on: 8-cores
|
||||||
needs: [create-docker-image, console-test-branch]
|
needs: [create-docker-image, console-test-branch]
|
||||||
timeout-minutes: 20
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# load docker image
|
# load docker image
|
||||||
@@ -153,25 +153,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
docker load --input /tmp/console-image.tar
|
docker load --input /tmp/console-image.tar
|
||||||
docker image ls -a
|
docker image ls -a
|
||||||
|
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# check-out tests repo
|
# check-out frontend-monorepo
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Checkout console test repo
|
- name: Checkout frontend-monorepo
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: vegaprotocol/console-test
|
ref: ${{ inputs.github-sha || github.sha }}
|
||||||
ref: ${{ needs.console-test-branch.outputs.console-branch }}
|
#----------------------------------------------
|
||||||
|
# get vega version
|
||||||
- name: Load console test envs
|
#----------------------------------------------
|
||||||
id: console-test-env
|
- name: Set VEGA_VERSION from .env
|
||||||
uses: falti/dotenv-action@v1.0.4
|
id: set_vega_version
|
||||||
with:
|
run: echo "VEGA_VERSION=$(grep VEGA_VERSION apps/trading/e2e/.env | cut -d '=' -f2)" >> $GITHUB_ENV
|
||||||
path: '.env.${{ needs.console-test-branch.outputs.console-branch }}'
|
|
||||||
export-variables: true
|
|
||||||
keys-case: upper
|
|
||||||
log-variables: true
|
|
||||||
|
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# ----- Setup python -----
|
# ----- Setup python -----
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
@@ -194,22 +188,25 @@ jobs:
|
|||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: poetry install --no-interaction --no-root
|
run: poetry install --no-interaction --no-root
|
||||||
|
working-directory: apps/trading/e2e
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# install vega binaries
|
# install vega binaries
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Install vega binaries
|
- name: Install vega binaries
|
||||||
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
|
run: poetry run python -m vega_sim.tools.load_binaries --force --version ${{ env.VEGA_VERSION }}
|
||||||
|
working-directory: apps/trading/e2e
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# install playwright
|
# install playwrightworking-directory: apps/trading/e2e
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: install playwright
|
- name: install playwright
|
||||||
run: poetry run playwright install --with-deps chromium
|
run: poetry run playwright install --with-deps chromium
|
||||||
|
working-directory: apps/trading/e2e
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# run tests
|
# run tests
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
|
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 1 --dist loadfile --durations=45
|
||||||
|
working-directory: apps/trading/e2e
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# upload traces
|
# upload traces
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
@@ -218,7 +215,7 @@ jobs:
|
|||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: playwright-trace
|
name: playwright-trace
|
||||||
path: ./traces/
|
path: apps/trading/e2e/traces/
|
||||||
retention-days: 15
|
retention-days: 15
|
||||||
#----------------------------------------------
|
#----------------------------------------------
|
||||||
# ----- upload logs -----
|
# ----- upload logs -----
|
||||||
@@ -230,3 +227,46 @@ jobs:
|
|||||||
name: worker-logs
|
name: worker-logs
|
||||||
path: ./logs/
|
path: ./logs/
|
||||||
retention-days: 15
|
retention-days: 15
|
||||||
|
#----------------------------------------------
|
||||||
|
# ----- upload market-sim logs -----
|
||||||
|
#----------------------------------------------
|
||||||
|
- name: Prepare and Zip market-sim-logs
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
parent_dir="/tmp/market-sim-logs"
|
||||||
|
echo "Creating parent directory at $parent_dir"
|
||||||
|
mkdir -p "$parent_dir"
|
||||||
|
|
||||||
|
echo "Waiting for vega-sim-* folders to be created..."
|
||||||
|
sleep 10 # Waits 10 seconds to ensure all folders are created
|
||||||
|
|
||||||
|
echo "Before searching for vega-sim-* folders in /tmp..."
|
||||||
|
folders=$(find /tmp -mindepth 1 -type d -name 'vega-sim-*' -print) || echo "Find command failed with exit code $?"
|
||||||
|
|
||||||
|
echo "After searching for vega-sim-* folders in /tmp..."
|
||||||
|
|
||||||
|
if [ -z "$folders" ]; then
|
||||||
|
echo "No vega-sim-* folders found."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Moving vega-sim-* folders to $parent_dir"
|
||||||
|
echo "$folders" | xargs -I {} mv {} "$parent_dir/"
|
||||||
|
|
||||||
|
echo "Checking if $parent_dir is not empty..."
|
||||||
|
if [ "$(ls -A $parent_dir)" ]; then
|
||||||
|
echo "Zipping the parent directory..."
|
||||||
|
zip -r market-sim-logs.zip "$parent_dir" && echo "Zip file created successfully."
|
||||||
|
else
|
||||||
|
echo "$parent_dir is empty. No zip file created."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
shell: /usr/bin/bash -e {0}
|
||||||
|
|
||||||
|
- name: Upload market-sim-logs
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: market-sim-logs
|
||||||
|
path: market-sim-logs.zip
|
||||||
|
retention-days: 15
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Use Node.js 16
|
- name: Use Node.js 20
|
||||||
id: Node
|
id: Node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 16.15.1
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
- name: Run Cypress tests
|
- name: Run Cypress tests
|
||||||
uses: cypress-io/github-action@v4
|
uses: cypress-io/github-action@v4
|
||||||
|
|||||||
@@ -57,6 +57,14 @@ jobs:
|
|||||||
path: './frontend-monorepo'
|
path: './frontend-monorepo'
|
||||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||||
|
|
||||||
|
- name: Setup node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: './frontend-monorepo/.nvmrc'
|
||||||
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
|
cache: yarn
|
||||||
|
cache-dependency-path: './frontend-monorepo/yarn.lock'
|
||||||
|
|
||||||
# Restore node_modules from cache if possible
|
# Restore node_modules from cache if possible
|
||||||
- name: Restore node_modules from cache
|
- name: Restore node_modules from cache
|
||||||
id: cache-node-modules
|
id: cache-node-modules
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version-file: '.nvmrc'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
rm package.json
|
rm package.json
|
||||||
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
|
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
|
||||||
|
|
||||||
- name: Check PR title
|
- name: Check PR title
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ jobs:
|
|||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version-file: '.nvmrc'
|
node-version-file: '.nvmrc'
|
||||||
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
# https://stackoverflow.com/questions/61010294/how-to-cache-yarn-packages-in-github-actions
|
||||||
|
|||||||
+9
-1
@@ -48,7 +48,15 @@ cypress.env.json
|
|||||||
# Next.js
|
# Next.js
|
||||||
.next
|
.next
|
||||||
|
|
||||||
#cypress
|
# cypress
|
||||||
/apps/**/cypress/reports/
|
/apps/**/cypress/reports/
|
||||||
/apps/**/cypress/downloads/
|
/apps/**/cypress/downloads/
|
||||||
/apps/**/fixtures/wallet/node**
|
/apps/**/fixtures/wallet/node**
|
||||||
|
|
||||||
|
# apps/trading/e2e
|
||||||
|
__pycache__/
|
||||||
|
apps/trading/e2e/logs/
|
||||||
|
apps/trading/e2e/.pytest_cache/
|
||||||
|
apps/trading/e2e/traces/
|
||||||
|
|
||||||
|
.nx/
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
# Auto-format all files
|
||||||
|
yarn nx format:write
|
||||||
|
|
||||||
# Lint all staged files
|
# Lint all staged files
|
||||||
yarn lint-staged
|
yarn lint-staged
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
. "$(dirname "$0")/_/husky.sh"
|
||||||
|
|
||||||
# Lint all staged files
|
# Lint all staged files - this brings more value as pre-commit
|
||||||
yarn nx format:check
|
# yarn nx format:check
|
||||||
|
|
||||||
# Test all projects with changes
|
# Test all projects with changes
|
||||||
yarn nx affected -t test --exclude trading
|
# yarn nx affected -t test --exclude trading
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Add files here to ignore them from prettier formatting
|
# Add files here to ignore them from prettier formatting
|
||||||
|
|
||||||
/dist
|
/dist
|
||||||
|
/dist-result
|
||||||
/coverage
|
/coverage
|
||||||
__generated__
|
__generated__
|
||||||
__generated___
|
__generated___
|
||||||
@@ -8,3 +9,15 @@ __generated___
|
|||||||
apps/static/src/assets/devnet-tranches.json
|
apps/static/src/assets/devnet-tranches.json
|
||||||
apps/static/src/assets/mainnet-tranches.json
|
apps/static/src/assets/mainnet-tranches.json
|
||||||
apps/static/src/assets/testnet-tranches.json
|
apps/static/src/assets/testnet-tranches.json
|
||||||
|
|
||||||
|
/apps/**/cypress/reports/
|
||||||
|
/apps/**/cypress/downloads/
|
||||||
|
|
||||||
|
/.nx/cache
|
||||||
|
|
||||||
|
# apps/trading/e2e
|
||||||
|
__pycache__/
|
||||||
|
apps/trading/e2e/logs/
|
||||||
|
apps/trading/e2e/.pytest_cache/
|
||||||
|
apps/trading/e2e/traces/
|
||||||
|
.pytest_cache/
|
||||||
|
|||||||
@@ -1,2 +1,4 @@
|
|||||||
* @vegaprotocol/frontend
|
* @vegaprotocol/frontend
|
||||||
|
apps/ @vegaprotocol/frontend-qa
|
||||||
|
libs/ @vegaprotocol/frontend-qa
|
||||||
*.graphql @vegaprotocol/core
|
*.graphql @vegaprotocol/core
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ The [`docker`](./docker) subfolder has some docker configurations for easily set
|
|||||||
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build). The multistage builds ensures consistent CPU architecture and build toolchains are used so that the result will be identical.
|
Using multistage dockerfile dist is compiled using [node](https://hub.docker.com/_/node) image and later packed to nginx as in [dist build](#dist-build). The multistage builds ensures consistent CPU architecture and build toolchains are used so that the result will be identical.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=16.5.1 --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
|
docker build --build-arg APP=[YOUR APP] --build-arg NODE_VERSION=20.9.1 --build-arg ENV_NAME=mainnet -t [TAG] -f docker/node-inside-docker.Dockerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
### Computing ipfs-hash of the build
|
### Computing ipfs-hash of the build
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
"rules": {}
|
"rules": {
|
||||||
|
"cypress/unsafe-to-chain-command": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
"executor": "@nx/linter:eslint",
|
"executor": "@nx/eslint:lint",
|
||||||
"outputs": ["{options.outputFile}"],
|
"outputs": ["{options.outputFile}"],
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["apps/explorer-e2e/**/*.{js,ts}"]
|
"lintFilePatterns": ["apps/explorer-e2e/**/*.{js,ts}"]
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ context('Proposal page', { tags: '@smoke' }, function () {
|
|||||||
cy.getByTestId('icon-cross').click();
|
cy.getByTestId('icon-cross').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Proposal page displayed on mobile', function () {
|
it('Proposal page displayed on mobile', function () {
|
||||||
const proposalTitle = 'Add Lorem Ipsum market';
|
const proposalTitle = 'Add Lorem Ipsum market';
|
||||||
|
|
||||||
cy.common_switch_to_mobile_and_click_toggle();
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
@@ -55,7 +55,7 @@ context('Proposal page', { tags: '@smoke' }, function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to view new asset proposal', function () {
|
it.skip('Able to view new asset proposal', function () {
|
||||||
const proposalTitle = 'Test new asset proposal';
|
const proposalTitle = 'Test new asset proposal';
|
||||||
const newAssetProposalBody = getNewAssetTxBody();
|
const newAssetProposalBody = getNewAssetTxBody();
|
||||||
cy.VegaWalletSubmitProposal(newAssetProposalBody);
|
cy.VegaWalletSubmitProposal(newAssetProposalBody);
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
[[redirects]]
|
|
||||||
from = "/*"
|
|
||||||
to = "/index.html"
|
|
||||||
status = 200
|
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
"executor": "@nx/linter:eslint",
|
"executor": "@nx/eslint:lint",
|
||||||
"outputs": ["{options.outputFile}"],
|
"outputs": ["{options.outputFile}"],
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["apps/explorer/**/*.{ts,tsx,js,jsx}"]
|
"lintFilePatterns": ["apps/explorer/**/*.{ts,tsx,js,jsx}"]
|
||||||
@@ -63,14 +63,7 @@
|
|||||||
"executor": "@nx/jest:jest",
|
"executor": "@nx/jest:jest",
|
||||||
"outputs": ["{workspaceRoot}/coverage/apps/explorer"],
|
"outputs": ["{workspaceRoot}/coverage/apps/explorer"],
|
||||||
"options": {
|
"options": {
|
||||||
"jestConfig": "apps/explorer/jest.config.ts",
|
"jestConfig": "apps/explorer/jest.config.ts"
|
||||||
"passWithNoTests": true
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"ci": {
|
|
||||||
"ci": true,
|
|
||||||
"codeCoverage": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"generate-types": {
|
"generate-types": {
|
||||||
@@ -81,15 +74,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"build-netlify": {
|
|
||||||
"executor": "nx:run-commands",
|
|
||||||
"options": {
|
|
||||||
"commands": [
|
|
||||||
"cp apps/explorer/netlify.toml netlify.toml",
|
|
||||||
"nx build explorer"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"build-spec": {
|
"build-spec": {
|
||||||
"executor": "nx:run-commands",
|
"executor": "nx:run-commands",
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import '../i18n';
|
||||||
import {
|
import {
|
||||||
NetworkLoader,
|
NetworkLoader,
|
||||||
NodeFailure,
|
NodeFailure,
|
||||||
@@ -11,7 +12,8 @@ import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-web
|
|||||||
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
import { Loader, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
||||||
import { RouterProvider } from 'react-router-dom';
|
import { RouterProvider } from 'react-router-dom';
|
||||||
import { router } from './routes/router-config';
|
import { useRouterConfig } from './routes/router-config';
|
||||||
|
import { createBrowserRouter } from 'react-router-dom';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
@@ -28,20 +30,27 @@ function App() {
|
|||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<TendermintWebsocketProvider>
|
<TendermintWebsocketProvider>
|
||||||
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
<Suspense fallback={splashLoading}>
|
||||||
<NodeGuard
|
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
|
||||||
skeleton={<div>{t('Loading')}</div>}
|
<NodeGuard
|
||||||
failure={<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
skeleton={<div>{t('Loading')}</div>}
|
||||||
>
|
failure={
|
||||||
<Suspense fallback={splashLoading}>
|
<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />
|
||||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
}
|
||||||
</Suspense>
|
>
|
||||||
</NodeGuard>
|
<Suspense fallback={splashLoading}>
|
||||||
<NodeSwitcherDialog
|
<RouterProvider
|
||||||
open={nodeSwitcherOpen}
|
router={createBrowserRouter(useRouterConfig())}
|
||||||
setOpen={setNodeSwitcherOpen}
|
fallbackElement={splashLoading}
|
||||||
/>
|
/>
|
||||||
</NetworkLoader>
|
</Suspense>
|
||||||
|
</NodeGuard>
|
||||||
|
<NodeSwitcherDialog
|
||||||
|
open={nodeSwitcherOpen}
|
||||||
|
setOpen={setNodeSwitcherOpen}
|
||||||
|
/>
|
||||||
|
</NetworkLoader>
|
||||||
|
</Suspense>
|
||||||
</TendermintWebsocketProvider>
|
</TendermintWebsocketProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useAssetDataProvider } from '@vegaprotocol/assets';
|
import { useAssetDataProvider } from '@vegaprotocol/assets';
|
||||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
import { addDecimalsFixedFormatNumber } from '@vegaprotocol/utils';
|
||||||
import { AssetLink } from '../links';
|
import { AssetLink } from '../links';
|
||||||
|
|
||||||
export type AssetBalanceProps = {
|
export type AssetBalanceProps = {
|
||||||
@@ -23,12 +23,12 @@ const AssetBalance = ({
|
|||||||
|
|
||||||
const label =
|
const label =
|
||||||
!loading && asset && asset.decimals
|
!loading && asset && asset.decimals
|
||||||
? addDecimalsFormatNumber(price, asset.decimals)
|
? addDecimalsFixedFormatNumber(price, asset.decimals)
|
||||||
: price;
|
: price;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="inline-block">
|
<div className="inline-block">
|
||||||
<span>{label}</span>{' '}
|
<span className="font-mono">{label}</span>{' '}
|
||||||
{showAssetLink && asset?.id ? (
|
{showAssetLink && asset?.id ? (
|
||||||
<AssetLink showAssetSymbol={showAssetSymbol} assetId={assetId} />
|
<AssetLink showAssetSymbol={showAssetSymbol} assetId={assetId} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -1,24 +1,30 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
|
import {
|
||||||
import { AssetTypeMapping, AssetStatusMapping } from '@vegaprotocol/assets';
|
useAssetTypeMapping,
|
||||||
|
useAssetStatusMapping,
|
||||||
|
type AssetFieldsFragment,
|
||||||
|
} from '@vegaprotocol/assets';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import { type AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type { VegaICellRendererParams } from '@vegaprotocol/datagrid';
|
import { type VegaICellRendererParams } from '@vegaprotocol/datagrid';
|
||||||
import { useRef, useLayoutEffect } from 'react';
|
import { useRef, useLayoutEffect } from 'react';
|
||||||
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import type { RowClickedEvent, ColDef } from 'ag-grid-community';
|
import { type ColDef } from 'ag-grid-community';
|
||||||
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
|
|
||||||
type AssetsTableProps = {
|
type AssetsTableProps = {
|
||||||
data: AssetFieldsFragment[] | null;
|
data: AssetFieldsFragment[] | null;
|
||||||
};
|
};
|
||||||
export const AssetsTable = ({ data }: AssetsTableProps) => {
|
export const AssetsTable = ({ data }: AssetsTableProps) => {
|
||||||
|
const assetTypeMapping = useAssetTypeMapping();
|
||||||
|
const assetStatusMapping = useAssetStatusMapping();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const ref = useRef<AgGridReact>(null);
|
const ref = useRef<AgGridReact>(null);
|
||||||
const showColumnsOnDesktop = () => {
|
const showColumnsOnDesktop = () => {
|
||||||
ref.current?.columnApi.setColumnsVisible(
|
ref.current?.api.setColumnsVisible(
|
||||||
['id', 'type', 'status'],
|
['id', 'type', 'status'],
|
||||||
window.innerWidth > BREAKPOINT_MD
|
window.innerWidth > BREAKPOINT_MD
|
||||||
);
|
);
|
||||||
@@ -47,14 +53,14 @@ export const AssetsTable = ({ data }: AssetsTableProps) => {
|
|||||||
field: 'source.__typename',
|
field: 'source.__typename',
|
||||||
hide: window.innerWidth < BREAKPOINT_MD,
|
hide: window.innerWidth < BREAKPOINT_MD,
|
||||||
valueFormatter: ({ value }: { value?: string }) =>
|
valueFormatter: ({ value }: { value?: string }) =>
|
||||||
value ? AssetTypeMapping[value].value : '',
|
value ? assetTypeMapping[value].value : '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
headerName: t('Status'),
|
headerName: t('Status'),
|
||||||
field: 'status',
|
field: 'status',
|
||||||
hide: window.innerWidth < BREAKPOINT_MD,
|
hide: window.innerWidth < BREAKPOINT_MD,
|
||||||
valueFormatter: ({ value }: { value?: string }) =>
|
valueFormatter: ({ value }: { value?: string }) =>
|
||||||
value ? AssetStatusMapping[value].value : '',
|
value ? assetStatusMapping[value].value : '',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
colId: 'actions',
|
colId: 'actions',
|
||||||
@@ -69,7 +75,7 @@ export const AssetsTable = ({ data }: AssetsTableProps) => {
|
|||||||
}: VegaICellRendererParams<AssetFieldsFragment, 'id'>) =>
|
}: VegaICellRendererParams<AssetFieldsFragment, 'id'>) =>
|
||||||
value ? (
|
value ? (
|
||||||
<ButtonLink
|
<ButtonLink
|
||||||
onClick={(e) => {
|
onClick={() => {
|
||||||
navigate(value);
|
navigate(value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -80,7 +86,7 @@ export const AssetsTable = ({ data }: AssetsTableProps) => {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[navigate]
|
[navigate, assetStatusMapping, assetTypeMapping]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { Routes } from '../../routes/route-names';
|
|||||||
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
||||||
import type { Navigable } from '../../routes/router-config';
|
import type { Navigable } from '../../routes/router-config';
|
||||||
import { isNavigable } from '../../routes/router-config';
|
import { isNavigable } from '../../routes/router-config';
|
||||||
import { routerConfig } from '../../routes/router-config';
|
import { useRouterConfig } from '../../routes/router-config';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import compact from 'lodash/compact';
|
import compact from 'lodash/compact';
|
||||||
import { Search } from '../search';
|
import { Search } from '../search';
|
||||||
@@ -26,6 +26,7 @@ const routeToNavigationItem = (r: Navigable) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
|
const routerConfig = useRouterConfig();
|
||||||
const isHome = Boolean(useMatch(Routes.HOME));
|
const isHome = Boolean(useMatch(Routes.HOME));
|
||||||
const pages = routerConfig[0].children || [];
|
const pages = routerConfig[0].children || [];
|
||||||
const mainItems = compact(
|
const mainItems = compact(
|
||||||
|
|||||||
@@ -91,6 +91,6 @@ describe('Market link component', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const res = render(renderComponent('123', [mock]));
|
const res = render(renderComponent('123', [mock]));
|
||||||
expect(await res.findByText('123')).toBeInTheDocument();
|
expect(await res.findByTitle('123')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const PartyLink = ({ id, truncate = false, ...props }: PartyLinkProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="whitespace-nowrap">
|
<span>
|
||||||
{useName && <Icon size={4} name="cube" className="mr-2" />}
|
{useName && <Icon size={4} name="cube" className="mr-2" />}
|
||||||
<Link
|
<Link
|
||||||
className="underline font-mono"
|
className="underline font-mono"
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ import { useMemo } from 'react';
|
|||||||
import { getAsset, type MarketFieldsFragment } from '@vegaprotocol/markets';
|
import { getAsset, type MarketFieldsFragment } from '@vegaprotocol/markets';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import { type AgGridReact } from 'ag-grid-react';
|
||||||
import type { ColDef } from 'ag-grid-community';
|
import { type ColDef } from 'ag-grid-community';
|
||||||
import { AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import {
|
||||||
VegaICellRendererParams,
|
type VegaICellRendererParams,
|
||||||
VegaValueGetterParams,
|
type VegaValueGetterParams,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import { useRef, useLayoutEffect } from 'react';
|
import { useRef, useLayoutEffect } from 'react';
|
||||||
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
import { BREAKPOINT_MD } from '../../config/breakpoints';
|
||||||
import { MarketStateMapping } from '@vegaprotocol/types';
|
import { MarketStateMapping } from '@vegaprotocol/types';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
import type { RowClickedEvent } from 'ag-grid-community';
|
import { type RowClickedEvent } from 'ag-grid-community';
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
type MarketsTableProps = {
|
type MarketsTableProps = {
|
||||||
@@ -29,7 +29,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
|||||||
const gridRef = useRef<AgGridReact>(null);
|
const gridRef = useRef<AgGridReact>(null);
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const showColumnsOnDesktop = () => {
|
const showColumnsOnDesktop = () => {
|
||||||
gridRef.current?.columnApi.setColumnsVisible(
|
gridRef.current?.api.setColumnsVisible(
|
||||||
['id', 'state', 'asset'],
|
['id', 'state', 'asset'],
|
||||||
window.innerWidth > BREAKPOINT_MD
|
window.innerWidth > BREAKPOINT_MD
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import { render, waitFor } from '@testing-library/react';
|
import { render, waitFor } from '@testing-library/react';
|
||||||
import {
|
import { NestedDataList, sortNestedDataByChildren } from './nested-data-list';
|
||||||
BORDER_COLOURS,
|
|
||||||
NestedDataList,
|
|
||||||
sortNestedDataByChildren,
|
|
||||||
} from './nested-data-list';
|
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
|
|
||||||
const mockData = {
|
const mockData = {
|
||||||
@@ -61,38 +57,6 @@ describe('NestedDataList', () => {
|
|||||||
expect(parent[0].querySelector('li')).toHaveClass('pl-4 border-l-4 pt-2');
|
expect(parent[0].querySelector('li')).toHaveClass('pl-4 border-l-4 pt-2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should repeat the border colours in the correct order', () => {
|
|
||||||
const colourMockData = {
|
|
||||||
t0: {
|
|
||||||
t1: {
|
|
||||||
t2: {
|
|
||||||
t3: {
|
|
||||||
t4: {
|
|
||||||
t5: {
|
|
||||||
t6: {
|
|
||||||
t7: {
|
|
||||||
t8: {
|
|
||||||
hello: 'world',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const tree = render(<NestedDataList data={colourMockData} />);
|
|
||||||
const { getByTestId } = tree;
|
|
||||||
|
|
||||||
for (let i = 0; i < 8; i++) {
|
|
||||||
const item = getByTestId(`T${i}`);
|
|
||||||
const expected = BORDER_COLOURS.light[i % 5];
|
|
||||||
expect(item.style.borderColor.toUpperCase()).toBe(expected);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should sort the data by values with children', () => {
|
it('should sort the data by values with children', () => {
|
||||||
const mockData = {
|
const mockData = {
|
||||||
nonce: '5980890939790185837',
|
nonce: '5980890939790185837',
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function renderAmendOrderDetails(
|
|||||||
mocks: MockedResponse[]
|
mocks: MockedResponse[]
|
||||||
) {
|
) {
|
||||||
return render(
|
return render(
|
||||||
<MockedProvider mocks={mocks} addTypename={false}>
|
<MockedProvider mocks={mocks}>
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<AmendOrderDetails version={version} id={id} amend={amend} />
|
<AmendOrderDetails version={version} id={id} amend={amend} />
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
@@ -44,18 +44,18 @@ function renderExistingAmend(
|
|||||||
orderByID: {
|
orderByID: {
|
||||||
__typename: 'Order',
|
__typename: 'Order',
|
||||||
id: '123',
|
id: '123',
|
||||||
type: 'GTT',
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
status: Schema.OrderStatus.STATUS_ACTIVE,
|
status: Schema.OrderStatus.STATUS_ACTIVE,
|
||||||
version: version,
|
version: version ? version.toString() : '',
|
||||||
createdAt: '123',
|
createdAt: '123',
|
||||||
updatedAt: '456',
|
updatedAt: '456',
|
||||||
expiresAt: '789',
|
expiresAt: '789',
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
price: '200',
|
price: '200',
|
||||||
side: 'BUY',
|
side: Schema.Side.SIDE_BUY,
|
||||||
peggedOrder: null,
|
peggedOrder: null,
|
||||||
remaining: '99',
|
remaining: '99',
|
||||||
rejectionReason: 'rejection',
|
rejectionReason: Schema.OrderRejectionReason.ORDER_ERROR_NOT_FOUND,
|
||||||
reference: '123',
|
reference: '123',
|
||||||
size: '100',
|
size: '100',
|
||||||
party: {
|
party: {
|
||||||
@@ -65,18 +65,15 @@ function renderExistingAmend(
|
|||||||
market: {
|
market: {
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
id: '789',
|
id: '789',
|
||||||
state: 'STATUS_ACTIVE',
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
positionDecimalPlaces: 2,
|
positionDecimalPlaces: 2,
|
||||||
decimalPlaces: '5',
|
decimalPlaces: 0,
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
product: {
|
product: {
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
quoteName: '123',
|
quoteName: '123',
|
||||||
settlementAsset: {
|
|
||||||
decimals: 8,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -97,18 +94,18 @@ function renderExistingAmend(
|
|||||||
orderByID: {
|
orderByID: {
|
||||||
__typename: 'Order',
|
__typename: 'Order',
|
||||||
id: '123',
|
id: '123',
|
||||||
type: 'GTT',
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
status: Schema.OrderStatus.STATUS_ACTIVE,
|
status: Schema.OrderStatus.STATUS_ACTIVE,
|
||||||
version: 100,
|
version: '100',
|
||||||
createdAt: '123',
|
createdAt: '123',
|
||||||
updatedAt: '456',
|
updatedAt: '456',
|
||||||
expiresAt: '789',
|
expiresAt: '789',
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
peggedOrder: null,
|
peggedOrder: null,
|
||||||
price: '200',
|
price: '200',
|
||||||
side: 'BUY',
|
side: Schema.Side.SIDE_BUY,
|
||||||
remaining: '99',
|
remaining: '99',
|
||||||
rejectionReason: 'rejection',
|
rejectionReason: Schema.OrderRejectionReason.ORDER_ERROR_NOT_FOUND,
|
||||||
reference: '123',
|
reference: '123',
|
||||||
size: '200',
|
size: '200',
|
||||||
party: {
|
party: {
|
||||||
@@ -117,19 +114,16 @@ function renderExistingAmend(
|
|||||||
},
|
},
|
||||||
market: {
|
market: {
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
id: 'amend-to-order-latest-version',
|
id: '8888',
|
||||||
state: 'STATUS_ACTIVE',
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
positionDecimalPlaces: 2,
|
positionDecimalPlaces: 2,
|
||||||
decimalPlaces: '5',
|
decimalPlaces: 0,
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
name: 'amend-to-order-latest-version-test',
|
name: 'amend-to-order-latest-version-test',
|
||||||
product: {
|
product: {
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
quoteName: '123',
|
quoteName: '123',
|
||||||
settlementAsset: {
|
|
||||||
decimals: 8,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -142,13 +136,13 @@ function renderExistingAmend(
|
|||||||
request: {
|
request: {
|
||||||
query: ExplorerMarketDocument,
|
query: ExplorerMarketDocument,
|
||||||
variables: {
|
variables: {
|
||||||
id: '789',
|
id: '8888',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
data: {
|
data: {
|
||||||
market: {
|
market: {
|
||||||
id: '789',
|
id: '8888',
|
||||||
decimalPlaces: 5,
|
decimalPlaces: 5,
|
||||||
positionDecimalPlaces: 2,
|
positionDecimalPlaces: 2,
|
||||||
state: 'irrelevant-test-data',
|
state: 'irrelevant-test-data',
|
||||||
@@ -225,12 +219,10 @@ describe('Amend order details', () => {
|
|||||||
|
|
||||||
it('Fetches latest version when version is not specified', async () => {
|
it('Fetches latest version when version is not specified', async () => {
|
||||||
const amend: Amend = {
|
const amend: Amend = {
|
||||||
price: '-7879',
|
price: '123',
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = renderExistingAmend('123', undefined, amend);
|
const res = renderExistingAmend('123', undefined, amend);
|
||||||
expect(
|
expect(await res.findByText('test-label')).toBeInTheDocument();
|
||||||
await res.findByText('amend-to-order-latest-version')
|
|
||||||
).toBeInTheDocument();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
|
|||||||
<div className={wrapperClasses}>
|
<div className={wrapperClasses}>
|
||||||
<div className="mb-12 lg:mb-0">
|
<div className="mb-12 lg:mb-0">
|
||||||
<div className="relative block rounded-lg px-3 py-6 md:px-6 lg:-mr-7">
|
<div className="relative block rounded-lg px-3 py-6 md:px-6 lg:-mr-7">
|
||||||
<h2 className="text-3xl font-bold mb-4 display-5">
|
<h2 className="display-5 mb-4 text-3xl font-bold">
|
||||||
{t('Order not found')}
|
{t('Order not found')}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-500 mb-12">
|
<p className="mb-12 text-gray-500">
|
||||||
{t('No order created from this transaction')}
|
{t('No order created from this transaction')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,24 +68,24 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
|
|||||||
<div className={wrapperClasses}>
|
<div className={wrapperClasses}>
|
||||||
<div className="mb-12 lg:mb-0">
|
<div className="mb-12 lg:mb-0">
|
||||||
<div className="relative block px-3 py-6 md:px-6 lg:-mr-7">
|
<div className="relative block px-3 py-6 md:px-6 lg:-mr-7">
|
||||||
<h2 className="text-3xl font-bold mb-4 display-5">
|
<h2 className="display-5 mb-4 text-3xl font-bold">
|
||||||
{t('Edits to ')}
|
{t('Edits to ')}
|
||||||
{sideText[o.side]}
|
{sideText[o.side]}
|
||||||
{t(' order')}
|
{t(' order')}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-500 mb-4">
|
<div className="mb-4 text-gray-500">
|
||||||
In <MarketLink id={o.market.id} />, updated at{' '}
|
In <MarketLink id={o.market.id} />, updated at{' '}
|
||||||
<Time date={o.updatedAt} />.
|
<Time date={o.updatedAt} />.
|
||||||
</p>
|
</div>
|
||||||
|
|
||||||
<div className="grid md:grid-cols-4 gap-x-6">
|
<div className="grid gap-x-6 md:grid-cols-4">
|
||||||
{amend.sizeDelta && amend.sizeDelta !== '0' ? (
|
{amend.sizeDelta && amend.sizeDelta !== '0' ? (
|
||||||
<div className="mb-12 md:mb-0">
|
<div className="mb-12 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-dark mb-4 text-2xl font-bold">
|
||||||
{t('New size')}
|
{t('New size')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5
|
<h5
|
||||||
className={`text-lg font-medium text-gray-500 mb-0 capitalize ${getSideDeltaColour(
|
className={`mb-0 text-lg font-medium capitalize text-gray-500 ${getSideDeltaColour(
|
||||||
amend.sizeDelta
|
amend.sizeDelta
|
||||||
)}`}
|
)}`}
|
||||||
>
|
>
|
||||||
@@ -96,10 +96,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
|
|||||||
|
|
||||||
{amend.price && amend.price !== '0' ? (
|
{amend.price && amend.price !== '0' ? (
|
||||||
<div className="">
|
<div className="">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-dark mb-4 text-2xl font-bold">
|
||||||
{t('New price')}
|
{t('New price')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="mb-0 text-lg font-medium text-gray-500">
|
||||||
<PriceInMarket price={amend.price} marketId={o.market.id} />
|
<PriceInMarket price={amend.price} marketId={o.market.id} />
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
@@ -108,10 +108,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
|
|||||||
{amend.peggedReference &&
|
{amend.peggedReference &&
|
||||||
amend.peggedReference !== 'PEGGED_REFERENCE_UNSPECIFIED' ? (
|
amend.peggedReference !== 'PEGGED_REFERENCE_UNSPECIFIED' ? (
|
||||||
<div className="">
|
<div className="">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-dark mb-4 text-2xl font-bold">
|
||||||
{t('New reference')}
|
{t('New reference')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="mb-0 text-lg font-medium text-gray-500">
|
||||||
{peggedReference[amend.peggedReference]}
|
{peggedReference[amend.peggedReference]}
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
@@ -119,10 +119,10 @@ const AmendOrderDetails = ({ id, version, amend }: AmendOrderDetailsProps) => {
|
|||||||
|
|
||||||
{amend.peggedOffset ? (
|
{amend.peggedOffset ? (
|
||||||
<div className="">
|
<div className="">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-dark mb-4 text-2xl font-bold">
|
||||||
{t('New offset')}
|
{t('New offset')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="mb-0 text-lg font-medium text-gray-500">
|
||||||
{amend.peggedOffset}
|
{amend.peggedOffset}
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Time } from '../time';
|
|||||||
import { sideText, statusText, tifFull, tifShort } from './lib/order-labels';
|
import { sideText, statusText, tifFull, tifShort } from './lib/order-labels';
|
||||||
import SizeInMarket from '../size-in-market/size-in-market';
|
import SizeInMarket from '../size-in-market/size-in-market';
|
||||||
import { TxOrderPeggedReference } from '../txs/details/order/tx-order-peg';
|
import { TxOrderPeggedReference } from '../txs/details/order/tx-order-peg';
|
||||||
|
import { OrderTypeMapping } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export interface DeterministicOrderDetailsProps {
|
export interface DeterministicOrderDetailsProps {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -59,7 +60,7 @@ const DeterministicOrderDetails = ({
|
|||||||
const o = data.orderByID;
|
const o = data.orderByID;
|
||||||
return (
|
return (
|
||||||
<div className={wrapperClasses}>
|
<div className={wrapperClasses}>
|
||||||
<div className="mb-12 lg:mb-0">
|
<div className="mb-0">
|
||||||
<div className="relative block px-3 py-6 md:px-6 lg:-mr-7">
|
<div className="relative block px-3 py-6 md:px-6 lg:-mr-7">
|
||||||
<h2 className="text-3xl font-bold mb-4 display-5">
|
<h2 className="text-3xl font-bold mb-4 display-5">
|
||||||
<abbr title={tifFull[o.timeInForce]} className="bb-dotted mr-2">
|
<abbr title={tifFull[o.timeInForce]} className="bb-dotted mr-2">
|
||||||
@@ -69,7 +70,7 @@ const DeterministicOrderDetails = ({
|
|||||||
<span className="mx-5 text-base">@</span>
|
<span className="mx-5 text-base">@</span>
|
||||||
<PriceInMarket price={o.price} marketId={o.market.id} />
|
<PriceInMarket price={o.price} marketId={o.market.id} />
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-200">
|
<p className="text-gray-400 dark:text-gray-600">
|
||||||
In <MarketLink id={o.market.id} /> at <Time date={o.createdAt} />.
|
In <MarketLink id={o.market.id} /> at <Time date={o.createdAt} />.
|
||||||
</p>
|
</p>
|
||||||
{o.peggedOrder ? (
|
{o.peggedOrder ? (
|
||||||
@@ -83,15 +84,14 @@ const DeterministicOrderDetails = ({
|
|||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{o.reference ? (
|
{o.reference ? (
|
||||||
<p className="text-gray-500 mt-4">
|
<p className="text-gray-500 mt-4">
|
||||||
<span>{t('Reference')}</span>: {o.reference}
|
<span>{t('Reference')}</span>: {o.reference}
|
||||||
</p>
|
</p>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="grid md:grid-cols-4 gap-x-6 mt-4">
|
<div className="grid grid-cols-2 md:grid-cols-5 gap-x-6 mt-4">
|
||||||
<div className="mb-12 md:mb-0">
|
<div className="mb-6 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-2xl font-bold text-dark mb-0 md:mb-4">
|
||||||
{t('Status')}
|
{t('Status')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0 capitalize">
|
<h5 className="text-lg font-medium text-gray-500 mb-0 capitalize">
|
||||||
@@ -99,21 +99,33 @@ const DeterministicOrderDetails = ({
|
|||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-12 md:mb-0">
|
<div className="mb-6 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">{t('Size')}</h2>
|
<h2 className="text-2xl font-bold text-dark mb-0 md:mb-4">
|
||||||
|
{t('Size')}
|
||||||
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
||||||
<SizeInMarket size={o.size} marketId={o.market.id} />
|
<SizeInMarket size={o.size} marketId={o.market.id} />
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="">
|
<div className="mb-6 md:mb-0">
|
||||||
<h2 className="text-2xl font-bold text-dark mb-4">
|
<h2 className="text-2xl font-bold text-dark mb-0 md:mb-4">
|
||||||
{t('Version')}
|
{t('Version')}
|
||||||
</h2>
|
</h2>
|
||||||
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
||||||
{o.version}
|
{o.version}
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
{o.type ? (
|
||||||
|
<div className="mb-6 md:mb-0">
|
||||||
|
<h2 className="text-2xl font-bold text-dark mb-0 md:mb-4">
|
||||||
|
{t('Type')}
|
||||||
|
</h2>
|
||||||
|
<h5 className="text-lg font-medium text-gray-500 mb-0">
|
||||||
|
{OrderTypeMapping[o.type]}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
import { type ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
||||||
import { VoteProgress } from '@vegaprotocol/proposals';
|
import { VoteProgress } from '@vegaprotocol/proposals';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import { type AgGridReact } from 'ag-grid-react';
|
||||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||||
import { AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import type {
|
import {
|
||||||
VegaICellRendererParams,
|
type VegaICellRendererParams,
|
||||||
VegaValueFormatterParams,
|
type VegaValueFormatterParams,
|
||||||
} from '@vegaprotocol/datagrid';
|
} from '@vegaprotocol/datagrid';
|
||||||
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
|
||||||
import type { RowClickedEvent, ColDef } from 'ag-grid-community';
|
import { type ColDef } from 'ag-grid-community';
|
||||||
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import {
|
import {
|
||||||
@@ -43,11 +44,11 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
|
|||||||
const gridRef = useRef<AgGridReact>(null);
|
const gridRef = useRef<AgGridReact>(null);
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const showColumnsOnDesktop = () => {
|
const showColumnsOnDesktop = () => {
|
||||||
gridRef.current?.columnApi.setColumnsVisible(
|
gridRef.current?.api.setColumnsVisible(
|
||||||
['voting', 'cDate', 'eDate', 'type'],
|
['voting', 'cDate', 'eDate', 'type'],
|
||||||
window.innerWidth > BREAKPOINT_MD
|
window.innerWidth > BREAKPOINT_MD
|
||||||
);
|
);
|
||||||
gridRef.current?.columnApi.setColumnWidth(
|
gridRef.current?.api.setColumnWidth(
|
||||||
'actions',
|
'actions',
|
||||||
window.innerWidth > BREAKPOINT_MD ? 221 : 80
|
window.innerWidth > BREAKPOINT_MD ? 221 : 80
|
||||||
);
|
);
|
||||||
@@ -105,7 +106,7 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
|
|||||||
? new BigNumber(0)
|
? new BigNumber(0)
|
||||||
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-full pt-2 uppercase">
|
<div className="flex h-full items-center justify-center pt-2 uppercase">
|
||||||
<VoteProgress
|
<VoteProgress
|
||||||
threshold={requiredMajorityPercentage}
|
threshold={requiredMajorityPercentage}
|
||||||
progress={yesPercentage}
|
progress={yesPercentage}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../routes/types/block-explorer-response';
|
||||||
|
import {
|
||||||
|
CopyWithTooltip,
|
||||||
|
VegaIcon,
|
||||||
|
VegaIconNames,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
|
||||||
|
interface SignatureProps {
|
||||||
|
signature: BlockExplorerTransactionResult['signature'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const valueClass =
|
||||||
|
'font-mono px-2.5 py-0.5 text-xs max-w-[200px] cursor-pointer';
|
||||||
|
const valueClassClosed = 'text-ellipsis overflow-hidden';
|
||||||
|
const valueClassOpen = 'break-words text-left';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Viewer component for a vega signature. Featuers copy and pasting, truncation
|
||||||
|
*
|
||||||
|
* @param signature
|
||||||
|
*/
|
||||||
|
export const Signature = ({ signature }: SignatureProps) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
|
|
||||||
|
if (!signature || !signature.value || !signature.version || !signature.algo) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="inline-flex border rounded signature-component relative pr-[20px]">
|
||||||
|
<div
|
||||||
|
className="bg-gray-100 px-2.5 py-0.5 text-xs text-gray-500 select-none cursor-default"
|
||||||
|
title={`${signature.algo}`}
|
||||||
|
>
|
||||||
|
<span>v{signature.version}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={
|
||||||
|
isOpen
|
||||||
|
? `${valueClass} ${valueClassOpen}`
|
||||||
|
: `${valueClass} ${valueClassClosed}`
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<CopyWithTooltip text={signature.value}>
|
||||||
|
<span title={signature.value}>{signature.value}</span>
|
||||||
|
</CopyWithTooltip>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
|
className="absolute top-[-3px] right-0 pr-2"
|
||||||
|
title={t('Show full signature')}
|
||||||
|
>
|
||||||
|
<VegaIcon name={isOpen ? VegaIconNames.EYE_OFF : VegaIconNames.EYE} />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -15,6 +15,7 @@ import isUndefined from 'lodash/isUndefined';
|
|||||||
import type { BlockExplorerTransactionResult } from '../../../../routes/types/block-explorer-response';
|
import type { BlockExplorerTransactionResult } from '../../../../routes/types/block-explorer-response';
|
||||||
import { TxDetailsChainEventWithdrawal } from './tx-erc20-withdrawal';
|
import { TxDetailsChainEventWithdrawal } from './tx-erc20-withdrawal';
|
||||||
import { TxDetailsChainEventErc20AssetDelist } from './tx-erc20-asset-delist';
|
import { TxDetailsChainEventErc20AssetDelist } from './tx-erc20-asset-delist';
|
||||||
|
import { TxDetailsContractCall } from './tx-contract-call';
|
||||||
|
|
||||||
interface ChainEventProps {
|
interface ChainEventProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -38,7 +39,7 @@ export const ChainEvent = ({ txData }: ChainEventProps) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { builtin, erc20, erc20Multisig, stakingEvent } =
|
const { builtin, erc20, erc20Multisig, stakingEvent, contractCall } =
|
||||||
txData.command.chainEvent;
|
txData.command.chainEvent;
|
||||||
|
|
||||||
// Builtin Asset events
|
// Builtin Asset events
|
||||||
@@ -140,6 +141,10 @@ export const ChainEvent = ({ txData }: ChainEventProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (contractCall) {
|
||||||
|
return <TxDetailsContractCall contractCall={contractCall} />;
|
||||||
|
}
|
||||||
|
|
||||||
// If we hit this return, tx-shared-details should give a basic overview
|
// If we hit this return, tx-shared-details should give a basic overview
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { decodeEthCallResult } from './tx-contract-call';
|
||||||
|
import { base64 } from 'ethers/lib/utils';
|
||||||
|
import { defaultAbiCoder } from '@ethersproject/abi';
|
||||||
|
import { BigNumber } from '@ethersproject/bignumber';
|
||||||
|
|
||||||
|
describe('decodeEthCallResult', () => {
|
||||||
|
it('should decode contractData correctly (mocked)', () => {
|
||||||
|
const mockContractData = base64.encode(
|
||||||
|
defaultAbiCoder.encode(['int256'], [BigNumber.from(123)])
|
||||||
|
);
|
||||||
|
const result = decodeEthCallResult(mockContractData);
|
||||||
|
expect(result).toBe('123');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should decode contractData correctly (known data)', () => {
|
||||||
|
const mockContractData = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADH8cueyY=';
|
||||||
|
const result = decodeEthCallResult(mockContractData);
|
||||||
|
expect(result).toBe('3435020581670');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return "-" when an error occurs', () => {
|
||||||
|
const mockContractData = 'invalid_data';
|
||||||
|
const result = decodeEthCallResult(mockContractData);
|
||||||
|
expect(result).toBe('-');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
import { TableCell, TableRow } from '../../../table';
|
||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import {
|
||||||
|
EthExplorerLink,
|
||||||
|
EthExplorerLinkTypes,
|
||||||
|
} from '../../../links/eth-explorer-link/eth-explorer-link';
|
||||||
|
import type { components } from '../../../../../types/explorer';
|
||||||
|
import { defaultAbiCoder, base64 } from 'ethers/lib/utils';
|
||||||
|
import { BigNumber } from 'ethers';
|
||||||
|
import OracleLink from '../../../links/oracle-link/oracle-link';
|
||||||
|
import { useExplorerOracleSpecByIdQuery } from '../../../../routes/oracles/__generated__/Oracles';
|
||||||
|
import { OracleEthSource } from '../../../../routes/oracles/components/oracle-eth-source';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the b64/ABIcoded result from an eth cal
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function decodeEthCallResult(contractData: string): string {
|
||||||
|
try {
|
||||||
|
const rawResult = defaultAbiCoder.decode(
|
||||||
|
['int256'],
|
||||||
|
base64.decode(contractData)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Finally, convert the resulting BigNumber in to a string
|
||||||
|
const res = BigNumber.from(rawResult[0]).toString();
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TxDetailsContractCallProps {
|
||||||
|
contractCall: components['schemas']['vegaEthContractCallEvent'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TxDetailsContractCall = ({
|
||||||
|
contractCall,
|
||||||
|
}: TxDetailsContractCallProps) => {
|
||||||
|
const { data } = useExplorerOracleSpecByIdQuery({
|
||||||
|
variables: {
|
||||||
|
id: contractCall.specId || '1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!contractCall || !contractCall.result) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{contractCall.specId && (
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Oracle')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<OracleLink
|
||||||
|
id={contractCall.specId}
|
||||||
|
hasSeenOracleReports={true}
|
||||||
|
status={data?.oracleSpec?.dataSourceSpec.spec.status || '-'}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
{contractCall.blockHeight && (
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('ETH block')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<EthExplorerLink
|
||||||
|
id={contractCall.blockHeight}
|
||||||
|
type={EthExplorerLinkTypes.block}
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
)}
|
||||||
|
{data?.oracleSpec?.dataSourceSpec && (
|
||||||
|
<OracleEthSource
|
||||||
|
sourceType={data.oracleSpec.dataSourceSpec.spec.data.sourceType}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Result')}</TableCell>
|
||||||
|
<TableCell>{decodeEthCallResult(contractCall.result)}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
import * as Types from '@vegaprotocol/types';
|
||||||
|
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
const defaultOptions = {} as const;
|
||||||
|
export type ExplorerReferralCodeOwnerQueryVariables = Types.Exact<{
|
||||||
|
id: Types.Scalars['ID'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type ExplorerReferralCodeOwnerQuery = { __typename?: 'Query', referralSets: { __typename?: 'ReferralSetConnection', edges: Array<{ __typename?: 'ReferralSetEdge', node: { __typename?: 'ReferralSet', createdAt: any, updatedAt: any, referrer: string } } | null> } };
|
||||||
|
|
||||||
|
|
||||||
|
export const ExplorerReferralCodeOwnerDocument = gql`
|
||||||
|
query ExplorerReferralCodeOwner($id: ID!) {
|
||||||
|
referralSets(id: $id) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
referrer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useExplorerReferralCodeOwnerQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useExplorerReferralCodeOwnerQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useExplorerReferralCodeOwnerQuery` 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 } = useExplorerReferralCodeOwnerQuery({
|
||||||
|
* variables: {
|
||||||
|
* id: // value for 'id'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useExplorerReferralCodeOwnerQuery(baseOptions: Apollo.QueryHookOptions<ExplorerReferralCodeOwnerQuery, ExplorerReferralCodeOwnerQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<ExplorerReferralCodeOwnerQuery, ExplorerReferralCodeOwnerQueryVariables>(ExplorerReferralCodeOwnerDocument, options);
|
||||||
|
}
|
||||||
|
export function useExplorerReferralCodeOwnerLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ExplorerReferralCodeOwnerQuery, ExplorerReferralCodeOwnerQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<ExplorerReferralCodeOwnerQuery, ExplorerReferralCodeOwnerQueryVariables>(ExplorerReferralCodeOwnerDocument, options);
|
||||||
|
}
|
||||||
|
export type ExplorerReferralCodeOwnerQueryHookResult = ReturnType<typeof useExplorerReferralCodeOwnerQuery>;
|
||||||
|
export type ExplorerReferralCodeOwnerLazyQueryHookResult = ReturnType<typeof useExplorerReferralCodeOwnerLazyQuery>;
|
||||||
|
export type ExplorerReferralCodeOwnerQueryResult = Apollo.QueryResult<ExplorerReferralCodeOwnerQuery, ExplorerReferralCodeOwnerQueryVariables>;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
query ExplorerReferralCodeOwner($id: ID!) {
|
||||||
|
referralSets(id: $id) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
referrer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { render, waitFor } from '@testing-library/react';
|
||||||
|
import type { MockedResponse } from '@apollo/client/testing';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { ReferralCodeOwner } from './referral-code-owner';
|
||||||
|
import type { ReferralCodeOwnerProps } from './referral-code-owner';
|
||||||
|
import { ExplorerReferralCodeOwnerDocument } from './__generated__/code-owner';
|
||||||
|
const renderComponent = (
|
||||||
|
props: ReferralCodeOwnerProps,
|
||||||
|
mocks: MockedResponse[]
|
||||||
|
) => {
|
||||||
|
return render(
|
||||||
|
<MockedProvider mocks={mocks}>
|
||||||
|
<MemoryRouter>
|
||||||
|
<ReferralCodeOwner {...props} />
|
||||||
|
</MemoryRouter>
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('ReferralCodeOwner', () => {
|
||||||
|
it('should render loading state', () => {
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: ExplorerReferralCodeOwnerDocument,
|
||||||
|
variables: {
|
||||||
|
id: 'ABC123',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { getByText } = renderComponent({ code: 'ABC123' }, mocks);
|
||||||
|
|
||||||
|
expect(getByText('Loading...')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error state', async () => {
|
||||||
|
const errorMessage = 'Error fetching referrer: ABC123';
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: ExplorerReferralCodeOwnerDocument,
|
||||||
|
variables: {
|
||||||
|
id: 'ABC123',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
error: new Error('nope'),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const { getByText } = renderComponent({ code: 'ABC123' }, mocks);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByText(errorMessage)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render link to referring party', async () => {
|
||||||
|
const referrerId = 'DEF789';
|
||||||
|
|
||||||
|
const mocks = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: ExplorerReferralCodeOwnerDocument,
|
||||||
|
variables: {
|
||||||
|
id: 'ABC123',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: {
|
||||||
|
data: {
|
||||||
|
referralSets: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: {
|
||||||
|
__typename: 'ReferralSet',
|
||||||
|
referrer: referrerId,
|
||||||
|
createdAt: '123',
|
||||||
|
updatedAt: '456',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { getByText } = renderComponent({ code: 'ABC123' }, mocks);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByText(referrerId)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { TableCell } from '../../../table';
|
||||||
|
import { useExplorerReferralCodeOwnerQuery } from './__generated__/code-owner';
|
||||||
|
import { PartyLink } from '../../../links';
|
||||||
|
|
||||||
|
export interface ReferralCodeOwnerProps {
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the owner of a referral code
|
||||||
|
*/
|
||||||
|
export const ReferralCodeOwner = ({ code }: ReferralCodeOwnerProps) => {
|
||||||
|
const { data, error, loading } = useExplorerReferralCodeOwnerQuery({
|
||||||
|
variables: {
|
||||||
|
id: code,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const referrer = data?.referralSets.edges[0]?.node.referrer || '';
|
||||||
|
return (
|
||||||
|
<TableCell>
|
||||||
|
{loading && 'Loading...'}
|
||||||
|
{error && `Error fetching referrer: ${code}`}
|
||||||
|
{referrer.length > 0 && <PartyLink id={referrer} />}
|
||||||
|
</TableCell>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { render } from '@testing-library/react';
|
||||||
|
import { ReferralTeam } from './team';
|
||||||
|
import type { CreateReferralSet } from './team';
|
||||||
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
|
||||||
|
describe('ReferralTeam', () => {
|
||||||
|
const team = {
|
||||||
|
name: 'Test Team',
|
||||||
|
teamUrl: 'https://example.com/team',
|
||||||
|
avatarUrl: 'https://example.com/avatar',
|
||||||
|
closed: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockTx: CreateReferralSet = {
|
||||||
|
team,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockId = '123456';
|
||||||
|
const mockCreator = 'JohnDoe';
|
||||||
|
|
||||||
|
it('should render the team name', () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByText('Test Team')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the team ID', () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByText('Id')).toBeInTheDocument();
|
||||||
|
expect(getByText(mockId)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the creator', () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByText('Creator')).toBeInTheDocument();
|
||||||
|
expect(getByText(mockCreator)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the team URL', () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByText('Team URL')).toBeInTheDocument();
|
||||||
|
expect(getByText(team.teamUrl)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the avatar URL', () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByText('Avatar')).toBeInTheDocument();
|
||||||
|
expect(getByText(team.avatarUrl)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the open status as a tick if closed is falsy', () => {
|
||||||
|
const { getByTestId } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={mockTx} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByTestId('open-yes')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render the open status as a cross if it is truthy', () => {
|
||||||
|
const m = {
|
||||||
|
team: {
|
||||||
|
closed: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { getByTestId } = render(
|
||||||
|
<MockedProvider>
|
||||||
|
<ReferralTeam tx={m} id={mockId} creator={mockCreator} />
|
||||||
|
</MockedProvider>
|
||||||
|
);
|
||||||
|
expect(getByTestId('open-no')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import {
|
||||||
|
VegaIcon,
|
||||||
|
Icon,
|
||||||
|
KeyValueTable,
|
||||||
|
KeyValueTableRow,
|
||||||
|
VegaIconNames,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import type { components } from '../../../../../types/explorer';
|
||||||
|
import Hash from '../../../links/hash';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
import { PartyLink } from '../../../links';
|
||||||
|
|
||||||
|
export type CreateReferralSet = components['schemas']['v1CreateReferralSet'];
|
||||||
|
export type ReferralTeam = CreateReferralSet['team'];
|
||||||
|
|
||||||
|
export interface ReferralTeamProps {
|
||||||
|
tx: CreateReferralSet;
|
||||||
|
id: string;
|
||||||
|
creator: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the details for a team in a CreateReferralSet or UpdateReferralSet transaction.
|
||||||
|
*
|
||||||
|
* Intentionally does not render the avatar image or link to the team url.
|
||||||
|
*/
|
||||||
|
export const ReferralTeam = ({ tx, id, creator }: ReferralTeamProps) => {
|
||||||
|
if (!tx.team) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<div className="inline-block mr-2 leading-none">
|
||||||
|
<VegaIcon name={VegaIconNames.TEAM} />
|
||||||
|
</div>
|
||||||
|
{tx.team.name && (
|
||||||
|
<h3 className="inline-block leading-loose">{tx.team.name}</h3>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="min-w-fit max-w-2xl block">
|
||||||
|
<KeyValueTable>
|
||||||
|
<KeyValueTableRow>
|
||||||
|
{t('Id')}
|
||||||
|
<Hash text={id} truncate={false} />
|
||||||
|
</KeyValueTableRow>
|
||||||
|
<KeyValueTableRow>
|
||||||
|
{t('Creator')}
|
||||||
|
<PartyLink id={creator} truncate={false} />
|
||||||
|
</KeyValueTableRow>
|
||||||
|
{tx.team.teamUrl && (
|
||||||
|
<KeyValueTableRow>
|
||||||
|
{t('Team URL')}
|
||||||
|
<Hash text={tx.team.teamUrl} truncate={false} />
|
||||||
|
</KeyValueTableRow>
|
||||||
|
)}
|
||||||
|
{tx.team.avatarUrl && (
|
||||||
|
<KeyValueTableRow>
|
||||||
|
{t('Avatar')}
|
||||||
|
<Hash text={tx.team.avatarUrl} truncate={false} />
|
||||||
|
</KeyValueTableRow>
|
||||||
|
)}
|
||||||
|
<KeyValueTableRow>
|
||||||
|
{t('Open')}
|
||||||
|
<span data-testid={!tx.team.closed ? 'open-yes' : 'open-no'}>
|
||||||
|
{!tx.team.closed ? <Icon name="tick" /> : <Icon name="cross" />}
|
||||||
|
</span>
|
||||||
|
</KeyValueTableRow>
|
||||||
|
</KeyValueTable>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -9,6 +9,7 @@ import { Time } from '../../../time';
|
|||||||
import { ChainResponseCode } from '../chain-response-code/chain-reponse.code';
|
import { ChainResponseCode } from '../chain-response-code/chain-reponse.code';
|
||||||
import { TxDataView } from '../../tx-data-view';
|
import { TxDataView } from '../../tx-data-view';
|
||||||
import Hash from '../../../links/hash';
|
import Hash from '../../../links/hash';
|
||||||
|
import { Signature } from '../../../signature/signature';
|
||||||
|
|
||||||
interface TxDetailsSharedProps {
|
interface TxDetailsSharedProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -26,7 +27,8 @@ export const sharedHeaderProps = {
|
|||||||
className: 'align-top',
|
className: 'align-top',
|
||||||
};
|
};
|
||||||
|
|
||||||
const Labels: Record<BlockExplorerTransactionResult['type'], string> = {
|
// The incoming type field is usually the right thing to show. Exceptions are listed here
|
||||||
|
const LabelOverrides: Record<BlockExplorerTransactionResult['type'], string> = {
|
||||||
'Stop Orders Submission': 'Stop Order',
|
'Stop Orders Submission': 'Stop Order',
|
||||||
'Stop Orders Cancellation': 'Cancel Stop Order',
|
'Stop Orders Cancellation': 'Cancel Stop Order',
|
||||||
};
|
};
|
||||||
@@ -49,7 +51,7 @@ export const TxDetailsShared = ({
|
|||||||
const time: string = blockData?.result.block.header.time || '';
|
const time: string = blockData?.result.block.header.time || '';
|
||||||
const height: string = blockData?.result.block.header.height || txData.block;
|
const height: string = blockData?.result.block.header.height || txData.block;
|
||||||
|
|
||||||
const type = Labels[txData.type] || txData.type;
|
const type = LabelOverrides[txData.type] || txData.type;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -75,6 +77,12 @@ export const TxDetailsShared = ({
|
|||||||
<BlockLink height={height} />
|
<BlockLink height={height} />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell {...sharedHeaderProps}>{t('Signature')}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Signature signature={txData.signature} />
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
<TableCell {...sharedHeaderProps}>{t('Time')}</TableCell>
|
<TableCell {...sharedHeaderProps}>{t('Time')}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
import { ReferralCodeOwner } from './referrals/referral-code-owner';
|
||||||
|
|
||||||
|
interface TxDetailsApplyReferralCodeProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature can be turned in to an id with txSignatureToDeterministicId but
|
||||||
|
*/
|
||||||
|
export const TxDetailsApplyReferralCode = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsApplyReferralCodeProps) => {
|
||||||
|
if (!txData || !txData.command.applyReferralCode || !txData.signature) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const referralCode = txData.command.applyReferralCode.id;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
|
<TxDetailsShared
|
||||||
|
txData={txData}
|
||||||
|
pubKey={pubKey}
|
||||||
|
blockData={blockData}
|
||||||
|
/>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Applied Code')}</TableCell>
|
||||||
|
<TableCell>{referralCode}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Referrer')}</TableCell>
|
||||||
|
<ReferralCodeOwner code={referralCode} />
|
||||||
|
</TableRow>
|
||||||
|
</TableWithTbody>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,51 +1,11 @@
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { TxDetailsShared } from './shared/tx-details-shared';
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
import { TableWithTbody } from '../../table';
|
import { TableWithTbody } from '../../table';
|
||||||
import { defaultAbiCoder, base64 } from 'ethers/lib/utils';
|
|
||||||
import { ChainEvent } from './chain-events';
|
import { ChainEvent } from './chain-events';
|
||||||
import { BigNumber } from 'ethers';
|
|
||||||
|
|
||||||
import type { AbiType } from '../../../lib/encoders/abis/abi-types';
|
|
||||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
|
||||||
interface AbiOutput {
|
|
||||||
type: AbiType;
|
|
||||||
internalType: AbiType;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes the b64/ABIcoded result from an eth cal
|
|
||||||
* @param data
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function decodeEthCallResult(
|
|
||||||
data: BlockExplorerTransactionResult
|
|
||||||
): string {
|
|
||||||
const ethResult = data.command.chainEvent?.contractCall.result;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Decode the result string: base64 => uint8array
|
|
||||||
const data = base64.decode(ethResult);
|
|
||||||
|
|
||||||
// Parse the escaped ABI in to an object
|
|
||||||
const abi = JSON.parse(
|
|
||||||
'[{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"}]'
|
|
||||||
);
|
|
||||||
// Pull the expected types out of the Oracles ABI
|
|
||||||
const types: AbiType[] = abi[0].outputs.map((o: AbiOutput) => o.type);
|
|
||||||
|
|
||||||
const rawResult = defaultAbiCoder.decode(types, data);
|
|
||||||
|
|
||||||
// Finally, convert the resulting BigNumber in to a string
|
|
||||||
const res = BigNumber.from(rawResult[0]).toString();
|
|
||||||
return res;
|
|
||||||
} catch (e) {
|
|
||||||
return '-';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TxDetailsChainEventProps {
|
interface TxDetailsChainEventProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
pubKey: string | undefined;
|
pubKey: string | undefined;
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
|
||||||
|
import { ReferralTeam } from './referrals/team';
|
||||||
|
|
||||||
|
interface TxDetailsCreateReferralProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature can be turned in to an id with txSignatureToDeterministicId but
|
||||||
|
*/
|
||||||
|
export const TxDetailsCreateReferralSet = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsCreateReferralProps) => {
|
||||||
|
if (!txData || !txData.command.createReferralSet || !txData.signature) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = txSignatureToDeterministicId(txData.signature.value);
|
||||||
|
|
||||||
|
const isTeam = txData.command.createReferralSet.isTeam || false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
|
<TxDetailsShared
|
||||||
|
txData={txData}
|
||||||
|
pubKey={pubKey}
|
||||||
|
blockData={blockData}
|
||||||
|
/>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{isTeam ? t('Team ID') : t('Referral code')}</TableCell>
|
||||||
|
<TableCell>{id}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableWithTbody>
|
||||||
|
|
||||||
|
<ReferralTeam
|
||||||
|
tx={txData.command.createReferralSet}
|
||||||
|
id={id}
|
||||||
|
creator={txData.submitter}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -3,8 +3,8 @@ import { DATA_SOURCES } from '../../../config';
|
|||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import { TxDetailsOrder } from './tx-order';
|
import { TxDetailsOrder } from './tx-order';
|
||||||
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
import { type BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
import { type TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
import { TxDetailsHeartbeat } from './tx-hearbeat';
|
import { TxDetailsHeartbeat } from './tx-hearbeat';
|
||||||
import { TxDetailsGeneric } from './tx-generic';
|
import { TxDetailsGeneric } from './tx-generic';
|
||||||
import { TxDetailsBatch } from './tx-batch';
|
import { TxDetailsBatch } from './tx-batch';
|
||||||
@@ -28,6 +28,10 @@ import { TxProposal } from './tx-proposal';
|
|||||||
import { TxDetailsTransfer } from './tx-transfer';
|
import { TxDetailsTransfer } from './tx-transfer';
|
||||||
import { TxDetailsStopOrderSubmission } from './tx-stop-order-submission';
|
import { TxDetailsStopOrderSubmission } from './tx-stop-order-submission';
|
||||||
import { TxDetailsLiquiditySubmission } from './tx-liquidity-submission';
|
import { TxDetailsLiquiditySubmission } from './tx-liquidity-submission';
|
||||||
|
import { TxDetailsCreateReferralSet } from './tx-create-referral-set';
|
||||||
|
import { TxDetailsApplyReferralCode } from './tx-apply-referral-code';
|
||||||
|
import { TxDetailsUpdateReferralSet } from './tx-update-referral-set';
|
||||||
|
import { TxDetailsJoinTeam } from './tx-join-team';
|
||||||
|
|
||||||
interface TxDetailsWrapperProps {
|
interface TxDetailsWrapperProps {
|
||||||
txData: BlockExplorerTransactionResult | undefined;
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
@@ -121,6 +125,14 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
|
|||||||
return TxDetailsStopOrderSubmission;
|
return TxDetailsStopOrderSubmission;
|
||||||
case 'Transfer Funds':
|
case 'Transfer Funds':
|
||||||
return TxDetailsTransfer;
|
return TxDetailsTransfer;
|
||||||
|
case 'Create Referral Set':
|
||||||
|
return TxDetailsCreateReferralSet;
|
||||||
|
case 'Update Referral Set':
|
||||||
|
return TxDetailsUpdateReferralSet;
|
||||||
|
case 'Apply Referral Code':
|
||||||
|
return TxDetailsApplyReferralCode;
|
||||||
|
case 'Join Team':
|
||||||
|
return TxDetailsJoinTeam;
|
||||||
default:
|
default:
|
||||||
return TxDetailsGeneric;
|
return TxDetailsGeneric;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
import { ReferralCodeOwner } from './referrals/referral-code-owner';
|
||||||
|
|
||||||
|
interface TxDetailsJoinTeamProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature can be turned in to an id with txSignatureToDeterministicId but
|
||||||
|
*/
|
||||||
|
export const TxDetailsJoinTeam = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsJoinTeamProps) => {
|
||||||
|
if (!txData || !txData.command.joinTeam || !txData.signature) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const team = txData.command.joinTeam.id;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
|
<TxDetailsShared
|
||||||
|
txData={txData}
|
||||||
|
pubKey={pubKey}
|
||||||
|
blockData={blockData}
|
||||||
|
/>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Team')}</TableCell>
|
||||||
|
<TableCell>{team}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{t('Referrer')}</TableCell>
|
||||||
|
<ReferralCodeOwner code={team} />
|
||||||
|
</TableRow>
|
||||||
|
</TableWithTbody>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import { t } from '@vegaprotocol/i18n';
|
||||||
|
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
|
||||||
|
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
|
||||||
|
import { TxDetailsShared } from './shared/tx-details-shared';
|
||||||
|
import { TableCell, TableRow, TableWithTbody } from '../../table';
|
||||||
|
import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
|
||||||
|
import { ReferralTeam } from './referrals/team';
|
||||||
|
|
||||||
|
interface TxDetailsUpdateReferralProps {
|
||||||
|
txData: BlockExplorerTransactionResult | undefined;
|
||||||
|
pubKey: string | undefined;
|
||||||
|
blockData: TendermintBlocksResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A copy of create referral set, effectively.
|
||||||
|
* Updating a referral set without a team doesn't make sense,
|
||||||
|
* but is valid, so this component ignores sense.
|
||||||
|
*/
|
||||||
|
export const TxDetailsUpdateReferralSet = ({
|
||||||
|
txData,
|
||||||
|
pubKey,
|
||||||
|
blockData,
|
||||||
|
}: TxDetailsUpdateReferralProps) => {
|
||||||
|
if (!txData || !txData.command.updateReferralSet || !txData.signature) {
|
||||||
|
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = txSignatureToDeterministicId(txData.signature.value);
|
||||||
|
|
||||||
|
const isTeam = txData.command.updateReferralSet.isTeam || false;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TableWithTbody className="mb-8" allowWrap={true}>
|
||||||
|
<TxDetailsShared
|
||||||
|
txData={txData}
|
||||||
|
pubKey={pubKey}
|
||||||
|
blockData={blockData}
|
||||||
|
/>
|
||||||
|
<TableRow modifier="bordered">
|
||||||
|
<TableCell>{isTeam ? t('Team ID') : t('Referral code')}</TableCell>
|
||||||
|
<TableCell>{id}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableWithTbody>
|
||||||
|
|
||||||
|
<ReferralTeam
|
||||||
|
tx={txData.command.updateReferralSet}
|
||||||
|
id={id}
|
||||||
|
creator={txData.submitter}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -28,6 +28,7 @@ export type FilterOption =
|
|||||||
| 'Delegate'
|
| 'Delegate'
|
||||||
| 'Ethereum Key Rotate Submission'
|
| 'Ethereum Key Rotate Submission'
|
||||||
| 'Issue Signatures'
|
| 'Issue Signatures'
|
||||||
|
| 'Join Team'
|
||||||
| 'Key Rotate Submission'
|
| 'Key Rotate Submission'
|
||||||
| 'Liquidity Provision Order'
|
| 'Liquidity Provision Order'
|
||||||
| 'Node Signature'
|
| 'Node Signature'
|
||||||
@@ -47,45 +48,46 @@ export type FilterOption =
|
|||||||
| 'Vote on Proposal'
|
| 'Vote on Proposal'
|
||||||
| 'Withdraw';
|
| 'Withdraw';
|
||||||
|
|
||||||
// Alphabetised list of transaction types to appear at the top level
|
export const filterOptions: Record<string, FilterOption[]> = {
|
||||||
export const PrimaryFilterOptions: FilterOption[] = [
|
'Market Instructions': [
|
||||||
'Amend LiquidityProvision Order',
|
'Amend LiquidityProvision Order',
|
||||||
'Amend Order',
|
'Amend Order',
|
||||||
'Batch Market Instructions',
|
'Batch Market Instructions',
|
||||||
'Cancel LiquidityProvision Order',
|
'Cancel LiquidityProvision Order',
|
||||||
'Cancel Order',
|
'Cancel Order',
|
||||||
'Cancel Transfer Funds',
|
'Liquidity Provision Order',
|
||||||
'Delegate',
|
'Stop Orders Submission',
|
||||||
'Liquidity Provision Order',
|
'Stop Orders Cancellation',
|
||||||
'Proposal',
|
'Submit Order',
|
||||||
'Stop Orders Submission',
|
],
|
||||||
'Stop Orders Cancellation',
|
'Transfers and Withdrawals': [
|
||||||
'Submit Oracle Data',
|
'Transfer Funds',
|
||||||
'Submit Order',
|
'Cancel Transfer Funds',
|
||||||
'Transfer Funds',
|
'Withdraw',
|
||||||
'Undelegate',
|
],
|
||||||
'Vote on Proposal',
|
Governance: ['Delegate', 'Undelegate', 'Vote on Proposal', 'Proposal'],
|
||||||
'Withdraw',
|
Referrals: [
|
||||||
];
|
'Apply Referral Code',
|
||||||
|
'Create Referral Set',
|
||||||
|
'Join Team',
|
||||||
|
'Update Referral Set',
|
||||||
|
],
|
||||||
|
'External Data': ['Chain Event', 'Submit Oracle Data'],
|
||||||
|
Validators: [
|
||||||
|
'Ethereum Key Rotate Submission',
|
||||||
|
'Issue Signatures',
|
||||||
|
'Key Rotate Submission',
|
||||||
|
'Node Signature',
|
||||||
|
'Node Vote',
|
||||||
|
'Protocol Upgrade',
|
||||||
|
'Register new Node',
|
||||||
|
'State Variable Proposal',
|
||||||
|
'Validator Heartbeat',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
// Alphabetised list of transaction types to nest under a 'More...' submenu
|
export const AllFilterOptions: FilterOption[] =
|
||||||
export const SecondaryFilterOptions: FilterOption[] = [
|
Object.values(filterOptions).flat();
|
||||||
'Chain Event',
|
|
||||||
'Ethereum Key Rotate Submission',
|
|
||||||
'Issue Signatures',
|
|
||||||
'Key Rotate Submission',
|
|
||||||
'Node Signature',
|
|
||||||
'Node Vote',
|
|
||||||
'Protocol Upgrade',
|
|
||||||
'Register new Node',
|
|
||||||
'State Variable Proposal',
|
|
||||||
'Validator Heartbeat',
|
|
||||||
];
|
|
||||||
|
|
||||||
export const AllFilterOptions: FilterOption[] = [
|
|
||||||
...PrimaryFilterOptions,
|
|
||||||
...SecondaryFilterOptions,
|
|
||||||
];
|
|
||||||
|
|
||||||
export interface TxFilterProps {
|
export interface TxFilterProps {
|
||||||
filters: Set<FilterOption>;
|
filters: Set<FilterOption>;
|
||||||
@@ -122,46 +124,33 @@ export const TxsFilter = ({ filters, setFilters }: TxFilterProps) => {
|
|||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{PrimaryFilterOptions.map((f) => (
|
|
||||||
<DropdownMenuCheckboxItem
|
{Object.entries(filterOptions).map(([key, value]) => (
|
||||||
key={f}
|
<DropdownMenuSub key={key}>
|
||||||
checked={filters.has(f)}
|
<DropdownMenuSubTrigger>
|
||||||
onCheckedChange={() => {
|
{t(key)}
|
||||||
// NOTE: These act like radio buttons until the API supports multiple filters
|
<Icon name="chevron-right" />
|
||||||
setFilters(new Set([f]));
|
</DropdownMenuSubTrigger>
|
||||||
}}
|
<DropdownMenuSubContent>
|
||||||
id={`radio-${f}`}
|
{value.map((f) => (
|
||||||
>
|
<DropdownMenuCheckboxItem
|
||||||
{f}
|
key={f}
|
||||||
<DropdownMenuItemIndicator>
|
checked={filters.has(f)}
|
||||||
<Icon name="tick-circle" />
|
onCheckedChange={(checked) => {
|
||||||
</DropdownMenuItemIndicator>
|
// NOTE: These act like radio buttons until the API supports multiple filters
|
||||||
</DropdownMenuCheckboxItem>
|
setFilters(new Set([f]));
|
||||||
|
}}
|
||||||
|
id={`radio-${f}`}
|
||||||
|
>
|
||||||
|
{f}
|
||||||
|
<DropdownMenuItemIndicator>
|
||||||
|
<Icon name="tick-circle" className="inline" />
|
||||||
|
</DropdownMenuItemIndicator>
|
||||||
|
</DropdownMenuCheckboxItem>
|
||||||
|
))}
|
||||||
|
</DropdownMenuSubContent>
|
||||||
|
</DropdownMenuSub>
|
||||||
))}
|
))}
|
||||||
<DropdownMenuSub>
|
|
||||||
<DropdownMenuSubTrigger>
|
|
||||||
{t('More Types')}
|
|
||||||
<Icon name="chevron-right" />
|
|
||||||
</DropdownMenuSubTrigger>
|
|
||||||
<DropdownMenuSubContent>
|
|
||||||
{SecondaryFilterOptions.map((f) => (
|
|
||||||
<DropdownMenuCheckboxItem
|
|
||||||
key={f}
|
|
||||||
checked={filters.has(f)}
|
|
||||||
onCheckedChange={(checked) => {
|
|
||||||
// NOTE: These act like radio buttons until the API supports multiple filters
|
|
||||||
setFilters(new Set([f]));
|
|
||||||
}}
|
|
||||||
id={`radio-${f}`}
|
|
||||||
>
|
|
||||||
{f}
|
|
||||||
<DropdownMenuItemIndicator>
|
|
||||||
<Icon name="tick-circle" className="inline" />
|
|
||||||
</DropdownMenuItemIndicator>
|
|
||||||
</DropdownMenuCheckboxItem>
|
|
||||||
))}
|
|
||||||
</DropdownMenuSubContent>
|
|
||||||
</DropdownMenuSub>
|
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ const displayString: StringMap = {
|
|||||||
StopOrdersSubmission: 'Stop',
|
StopOrdersSubmission: 'Stop',
|
||||||
StopOrdersCancellation: 'Cancel stop',
|
StopOrdersCancellation: 'Cancel stop',
|
||||||
'Stop Orders Cancellation': 'Cancel stop',
|
'Stop Orders Cancellation': 'Cancel stop',
|
||||||
|
'Apply Referral Code': 'Referral',
|
||||||
|
'Create Referral Set': 'Create referral',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getLabelForStopOrderType(
|
export function getLabelForStopOrderType(
|
||||||
@@ -80,6 +82,12 @@ export function getLabelForOrderType(
|
|||||||
if (command.orderSubmission.icebergOpts) {
|
if (command.orderSubmission.icebergOpts) {
|
||||||
return 'Iceberg';
|
return 'Iceberg';
|
||||||
}
|
}
|
||||||
|
if (command.orderSubmission.type === 'TYPE_MARKET') {
|
||||||
|
return 'Market order';
|
||||||
|
}
|
||||||
|
if (command.orderSubmission.type === 'TYPE_LIMIT') {
|
||||||
|
return 'Limit order';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 'Order';
|
return 'Order';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ describe('TxDetailsTransfer', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value:
|
value:
|
||||||
'610c2e196a7d4fed4413b9e82af267b1ff3e30e943df3a3d28096fd60604d430d752fbaf6dd4f84d496be78885bb6118f40560bff7832c06bd7a3d67b718b700',
|
'610c2e196a7d4fed4413b9e82af267b1ff3e30e943df3a3d28096fd60604d430d752fbaf6dd4f84d496be78885bb6118f40560bff7832c06bd7a3d67b718b700',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ const generateTxs = (number: number): BlockExplorerTransactionResult[] => {
|
|||||||
'4b782482f587d291e8614219eb9a5ee9280fa2c58982dee71d976782a9be1964',
|
'4b782482f587d291e8614219eb9a5ee9280fa2c58982dee71d976782a9be1964',
|
||||||
type: 'Submit Order',
|
type: 'Submit Order',
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value: '123',
|
value: '123',
|
||||||
},
|
},
|
||||||
code: 0,
|
code: 0,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Table, TableRow } from '../table';
|
import { Table, TableRow } from '../table';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import type { BlockExplorerTransactions } from '../../routes/types/block-explorer-response';
|
import { type BlockExplorerTransactions } from '../../routes/types/block-explorer-response';
|
||||||
import { getTxsDataUrl } from '../../hooks/get-txs-data-url';
|
import { getTxsDataUrl } from '../../hooks/get-txs-data-url';
|
||||||
import { AsyncRenderer, Loader } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import EmptyList from '../empty-list/empty-list';
|
import EmptyList from '../empty-list/empty-list';
|
||||||
@@ -22,7 +22,7 @@ export const TxsPerBlock = ({ blockHeight, txCount }: TxsPerBlockProps) => {
|
|||||||
return (
|
return (
|
||||||
<AsyncRenderer data={data} error={error} loading={!!loading}>
|
<AsyncRenderer data={data} error={error} loading={!!loading}>
|
||||||
{data && data.transactions.length > 0 ? (
|
{data && data.transactions.length > 0 ? (
|
||||||
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
<div className="mb-28 overflow-x-auto whitespace-nowrap">
|
||||||
<Table>
|
<Table>
|
||||||
<thead>
|
<thead>
|
||||||
<TableRow modifier="bordered" className="font-mono">
|
<TableRow modifier="bordered" className="font-mono">
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import type { URLSearchParamsInit } from 'react-router-dom';
|
import { type URLSearchParamsInit } from 'react-router-dom';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||||
import type {
|
import {
|
||||||
BlockExplorerTransactionResult,
|
type BlockExplorerTransactionResult,
|
||||||
BlockExplorerTransactions,
|
type BlockExplorerTransactions,
|
||||||
} from '../routes/types/block-explorer-response';
|
} from '../routes/types/block-explorer-response';
|
||||||
import isNumber from 'lodash/isNumber';
|
import isNumber from 'lodash/isNumber';
|
||||||
import { AllFilterOptions } from '../components/txs/tx-filter';
|
import { AllFilterOptions } from '../components/txs/tx-filter';
|
||||||
import type { FilterOption } from '../components/txs/tx-filter';
|
import { type FilterOption } from '../components/txs/tx-filter';
|
||||||
import { BE_TXS_PER_REQUEST, getTxsDataUrl } from './get-txs-data-url';
|
import { BE_TXS_PER_REQUEST, getTxsDataUrl } from './get-txs-data-url';
|
||||||
|
|
||||||
export function getTypeFilters(filters?: Set<FilterOption>) {
|
export function getTypeFilters(filters?: Set<FilterOption>) {
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { PageTitle } from '../../components/page-helpers/page-title';
|
import { PageTitle } from '../../components/page-helpers/page-title';
|
||||||
|
|
||||||
|
type Params = { assetId: string };
|
||||||
|
|
||||||
export const AssetPage = () => {
|
export const AssetPage = () => {
|
||||||
useDocumentTitle(['Assets']);
|
useDocumentTitle(['Assets']);
|
||||||
useScrollToLocation();
|
useScrollToLocation();
|
||||||
|
|
||||||
const { assetId } = useParams<{ assetId: string }>();
|
const { assetId } = useParams<Params>();
|
||||||
const { data, loading, error } = useAssetDataProvider(assetId || '');
|
const { data, loading, error } = useAssetDataProvider(assetId || '');
|
||||||
|
|
||||||
const title = data ? data.name : error ? t('Asset not found') : '';
|
const title = data ? data.name : error ? t('Asset not found') : '';
|
||||||
@@ -41,7 +43,7 @@ export const AssetPage = () => {
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
error={error}
|
error={error}
|
||||||
>
|
>
|
||||||
<div className="h-full relative">
|
<div className="relative h-full">
|
||||||
<AssetDetailsTable asset={data as AssetFieldsFragment} />
|
<AssetDetailsTable asset={data as AssetFieldsFragment} />
|
||||||
</div>
|
</div>
|
||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import type {
|
import {
|
||||||
BlockMeta,
|
type BlockMeta,
|
||||||
TendermintBlockchainResponse,
|
type TendermintBlockchainResponse,
|
||||||
} from '../tendermint-blockchain-response';
|
} from '../tendermint-blockchain-response';
|
||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
import { BlocksRefetch } from '../../../components/blocks';
|
import { BlocksRefetch } from '../../../components/blocks';
|
||||||
|
|||||||
@@ -17,8 +17,10 @@ import { NodeLink } from '../../../components/links';
|
|||||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||||
import EmptyList from '../../../components/empty-list/empty-list';
|
import EmptyList from '../../../components/empty-list/empty-list';
|
||||||
|
|
||||||
|
type Params = { block: string };
|
||||||
|
|
||||||
const Block = () => {
|
const Block = () => {
|
||||||
const { block } = useParams<{ block: string }>();
|
const { block } = useParams<Params>();
|
||||||
useDocumentTitle(['Blocks', `Block #${block}`]);
|
useDocumentTitle(['Blocks', `Block #${block}`]);
|
||||||
const {
|
const {
|
||||||
state: { data: blockData, loading, error },
|
state: { data: blockData, loading, error },
|
||||||
@@ -29,7 +31,7 @@ const Block = () => {
|
|||||||
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
|
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
|
||||||
<AsyncRenderer data={blockData} error={error} loading={!!loading}>
|
<AsyncRenderer data={blockData} error={error} loading={!!loading}>
|
||||||
<>
|
<>
|
||||||
<div className="grid grid-cols-2 gap-2 mb-8">
|
<div className="mb-8 grid grid-cols-2 gap-2">
|
||||||
<Link
|
<Link
|
||||||
data-testid="previous-block"
|
data-testid="previous-block"
|
||||||
to={`/${Routes.BLOCKS}/${Number(block) - 1}`}
|
to={`/${Routes.BLOCKS}/${Number(block) - 1}`}
|
||||||
@@ -52,7 +54,7 @@ const Block = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{blockData && (
|
{blockData && 'result' in blockData && (
|
||||||
<>
|
<>
|
||||||
<TableWithTbody className="mb-8">
|
<TableWithTbody className="mb-8">
|
||||||
<TableRow modifier="bordered">
|
<TableRow modifier="bordered">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useFetch } from '@vegaprotocol/react-helpers';
|
|||||||
import { RouteTitle } from '../../components/route-title';
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
||||||
import { DATA_SOURCES } from '../../config';
|
import { DATA_SOURCES } from '../../config';
|
||||||
import type { TendermintGenesisResponse } from './tendermint-genesis-response';
|
import { type TendermintGenesisResponse } from './tendermint-genesis-response';
|
||||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||||
|
|
||||||
const Genesis = () => {
|
const Genesis = () => {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ export const Layout = () => {
|
|||||||
<ProtocolUpgradeInProgressNotification />
|
<ProtocolUpgradeInProgressNotification />
|
||||||
</div>
|
</div>
|
||||||
<div className={fixedWidthClasses}>
|
<div className={fixedWidthClasses}>
|
||||||
<main className="p-4">
|
<main className="md:p-4">
|
||||||
{!isHome && <BreadcrumbsContainer className="mb-4" />}
|
{!isHome && <BreadcrumbsContainer className="mb-4" />}
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ import { JsonViewerDialog } from '../../components/dialogs/json-viewer-dialog';
|
|||||||
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
|
import { marketInfoWithDataProvider } from '@vegaprotocol/markets';
|
||||||
import { PageTitle } from '../../components/page-helpers/page-title';
|
import { PageTitle } from '../../components/page-helpers/page-title';
|
||||||
|
|
||||||
|
type Params = { marketId: string };
|
||||||
|
|
||||||
export const MarketPage = () => {
|
export const MarketPage = () => {
|
||||||
useScrollToLocation();
|
useScrollToLocation();
|
||||||
|
|
||||||
const { marketId } = useParams<{ marketId: string }>();
|
const { marketId } = useParams<Params>();
|
||||||
|
|
||||||
const { data, loading, error } = useDataProvider({
|
const { data, loading, error } = useDataProvider({
|
||||||
dataProvider: marketInfoWithDataProvider,
|
dataProvider: marketInfoWithDataProvider,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { getNodes } from '@vegaprotocol/utils';
|
import { getNodes } from '@vegaprotocol/utils';
|
||||||
import { MarketLink } from '../../../components/links';
|
import { MarketLink } from '../../../components/links';
|
||||||
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
||||||
import type { ExplorerOracleForMarketsMarketFragment } from '../__generated__/OraclesForMarkets';
|
import {
|
||||||
import { useExplorerOracleFormMarketsQuery } from '../__generated__/OraclesForMarkets';
|
useExplorerOracleFormMarketsQuery,
|
||||||
|
type ExplorerOracleForMarketsMarketFragment,
|
||||||
|
} from '../__generated__/OraclesForMarkets';
|
||||||
|
|
||||||
interface OracleMarketsProps {
|
interface OracleMarketsProps {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ import { AsyncRenderer, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit';
|
|||||||
import filter from 'recursive-key-filter';
|
import filter from 'recursive-key-filter';
|
||||||
import { TruncateInline } from '../../../components/truncate/truncate';
|
import { TruncateInline } from '../../../components/truncate/truncate';
|
||||||
|
|
||||||
|
type Params = { id: string };
|
||||||
|
|
||||||
export const Oracle = () => {
|
export const Oracle = () => {
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<Params>();
|
||||||
|
|
||||||
useDocumentTitle(['Oracle', `Oracle #${truncateByChars(id || '1', 5, 5)}`]);
|
useDocumentTitle(['Oracle', `Oracle #${truncateByChars(id || '1', 5, 5)}`]);
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import { useDocumentTitle } from '../../../../hooks/use-document-title';
|
|||||||
|
|
||||||
import { PartyAccounts } from '../components/party-accounts';
|
import { PartyAccounts } from '../components/party-accounts';
|
||||||
|
|
||||||
|
type Params = { party: string };
|
||||||
|
|
||||||
const PartyAccountsByAsset = () => {
|
const PartyAccountsByAsset = () => {
|
||||||
const { party } = useParams<{ party: string }>();
|
const { party } = useParams<Params>();
|
||||||
|
|
||||||
useDocumentTitle(['Public keys', party || '-']);
|
useDocumentTitle(['Public keys', party || '-']);
|
||||||
const partyId = toNonHex(party ? party : '');
|
const partyId = toNonHex(party ? party : '');
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { AccountManager } from '@vegaprotocol/accounts';
|
import { useExplorerPartyAssetsQuery } from '../__generated__/Party-assets';
|
||||||
import { useCallback } from 'react';
|
import { AssetLink, MarketLink } from '../../../../components/links';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import AssetBalance from '../../../../components/asset-balance/asset-balance';
|
||||||
|
import { AccountTypeMapping } from '@vegaprotocol/types';
|
||||||
|
|
||||||
interface PartyAccountsProps {
|
interface PartyAccountsProps {
|
||||||
partyId: string;
|
partyId: string;
|
||||||
@@ -12,21 +13,71 @@ interface PartyAccountsProps {
|
|||||||
* appearing first and... tbd
|
* appearing first and... tbd
|
||||||
*/
|
*/
|
||||||
export const PartyAccounts = ({ partyId }: PartyAccountsProps) => {
|
export const PartyAccounts = ({ partyId }: PartyAccountsProps) => {
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
const { data } = useExplorerPartyAssetsQuery({
|
||||||
const onClickAsset = useCallback(
|
variables: { partyId },
|
||||||
(assetId?: string) => {
|
});
|
||||||
assetId && openAssetDetailsDialog(assetId);
|
|
||||||
},
|
const party = data?.partiesConnection?.edges[0]?.node;
|
||||||
[openAssetDetailsDialog]
|
const accounts =
|
||||||
);
|
party?.accountsConnection?.edges?.filter((edge) => edge?.node) || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="block min-h-44 h-60 4 w-full border-red-800 relative">
|
<div className="block min-h-44 h-60 4 w-full border-red-800 relative">
|
||||||
<AccountManager
|
<table>
|
||||||
partyId={partyId}
|
<thead>
|
||||||
onClickAsset={onClickAsset}
|
<tr>
|
||||||
isReadOnly={true}
|
<th className="text-right px-4">Balance</th>
|
||||||
/>
|
<th className="text-left px-4">Type</th>
|
||||||
|
<th className="text-left px-4">Market</th>
|
||||||
|
<th className="text-left px-4">Asset</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{accounts
|
||||||
|
.sort((a, b) => {
|
||||||
|
// Sort by asset id, then market id, with general accounts first
|
||||||
|
if (!a) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!b) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (a.node.asset.id !== b.node.asset.id) {
|
||||||
|
return a.node.asset.id.localeCompare(b.node.asset.id);
|
||||||
|
}
|
||||||
|
if (a.node.type === 'ACCOUNT_TYPE_GENERAL') return -1;
|
||||||
|
if (b.node.type === 'ACCOUNT_TYPE_GENERAL') return 1;
|
||||||
|
if (a.node.market && b.node.market) {
|
||||||
|
return a.node.market.id.localeCompare(b.node.market.id);
|
||||||
|
} else {
|
||||||
|
return a.node.type.localeCompare(b.node.type);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map((e) => {
|
||||||
|
if (!e) return null;
|
||||||
|
const { type, asset, balance, market } = e.node;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<tr className="border-t border-neutral-300 dark:border-neutral-600">
|
||||||
|
<td className="px-4 text-right">
|
||||||
|
<AssetBalance
|
||||||
|
assetId={asset.id}
|
||||||
|
price={balance}
|
||||||
|
showAssetSymbol={true}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
<td className="px-4">{AccountTypeMapping[type]}</td>
|
||||||
|
<td className="px-4">
|
||||||
|
{market?.id ? <MarketLink id={market.id} /> : '-'}
|
||||||
|
</td>
|
||||||
|
<td className="px-4">
|
||||||
|
<AssetLink assetId={asset.id} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ import type { FilterOption } from '../../../components/txs/tx-filter';
|
|||||||
import { AllFilterOptions, TxsFilter } from '../../../components/txs/tx-filter';
|
import { AllFilterOptions, TxsFilter } from '../../../components/txs/tx-filter';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
|
type Params = { party: string };
|
||||||
|
|
||||||
const Party = () => {
|
const Party = () => {
|
||||||
const [params] = useSearchParams();
|
const [params] = useSearchParams();
|
||||||
|
|
||||||
const [filters, setFilters] = useState(new Set(AllFilterOptions));
|
const [filters, setFilters] = useState(new Set(AllFilterOptions));
|
||||||
const { party } = useParams<{ party: string }>();
|
const { party } = useParams<Params>();
|
||||||
|
|
||||||
useDocumentTitle(['Public keys', party || '-']);
|
useDocumentTitle(['Public keys', party || '-']);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -60,7 +62,7 @@ const Party = () => {
|
|||||||
|
|
||||||
if (!isValidPartyId(partyId)) {
|
if (!isValidPartyId(partyId)) {
|
||||||
return (
|
return (
|
||||||
<div className="max-w-sm mx-auto">
|
<div className="mx-auto max-w-sm">
|
||||||
<Notification
|
<Notification
|
||||||
message={t('Invalid party ID')}
|
message={t('Invalid party ID')}
|
||||||
intent={Intent.Danger}
|
intent={Intent.Danger}
|
||||||
@@ -84,7 +86,7 @@ const Party = () => {
|
|||||||
truncateEnd={visibleChars}
|
truncateEnd={visibleChars}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="grid md:grid-flow-col grid-flow-row md:space-x-4 grid-cols-1 md:grid-cols-2 w-full">
|
<div className="grid w-full grid-flow-row grid-cols-1 md:grid-flow-col md:grid-cols-2 md:space-x-4">
|
||||||
<PartyBlockAccounts
|
<PartyBlockAccounts
|
||||||
accountError={AccountError}
|
accountError={AccountError}
|
||||||
accountLoading={AccountLoading}
|
accountLoading={AccountLoading}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import { t } from '@vegaprotocol/i18n';
|
|||||||
import { Routes } from './route-names';
|
import { Routes } from './route-names';
|
||||||
import { NetworkParameters } from './network-parameters';
|
import { NetworkParameters } from './network-parameters';
|
||||||
import type { Params, RouteObject } from 'react-router-dom';
|
import type { Params, RouteObject } from 'react-router-dom';
|
||||||
import { createBrowserRouter } from 'react-router-dom';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { MarketPage, MarketsPage } from './markets';
|
import { MarketPage, MarketsPage } from './markets';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
@@ -29,7 +28,7 @@ import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { remove0x } from '@vegaprotocol/utils';
|
import { remove0x } from '@vegaprotocol/utils';
|
||||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
import { PartyAccountsByAsset } from './parties/id/accounts';
|
||||||
import { Disclaimer } from './pages/disclaimer';
|
import { Disclaimer } from './pages/disclaimer';
|
||||||
import { FLAGS } from '@vegaprotocol/environment';
|
import { useFeatureFlags } from '@vegaprotocol/environment';
|
||||||
import RestrictedPage from './restricted';
|
import RestrictedPage from './restricted';
|
||||||
|
|
||||||
export type Navigable = {
|
export type Navigable = {
|
||||||
@@ -60,311 +59,315 @@ type Route = RouteItem & {
|
|||||||
children?: RouteItem[];
|
children?: RouteItem[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const partiesRoutes: Route[] = FLAGS.EXPLORER_PARTIES
|
export const useRouterConfig = () => {
|
||||||
? [
|
const featureFlags = useFeatureFlags((state) => state.flags);
|
||||||
{
|
|
||||||
path: Routes.PARTIES,
|
|
||||||
element: <Party />,
|
|
||||||
handle: {
|
|
||||||
name: t('Parties'),
|
|
||||||
text: t('Parties'),
|
|
||||||
breadcrumb: () => <Link to={Routes.PARTIES}>{t('Parties')}</Link>,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Parties />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':party',
|
|
||||||
element: <Party />,
|
|
||||||
|
|
||||||
children: [
|
const partiesRoutes: Route[] = featureFlags.EXPLORER_PARTIES
|
||||||
{
|
? [
|
||||||
index: true,
|
{
|
||||||
element: <PartySingle />,
|
path: Routes.PARTIES,
|
||||||
handle: {
|
element: <Party />,
|
||||||
breadcrumb: (params: Params<string>) => (
|
handle: {
|
||||||
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
name: t('Parties'),
|
||||||
{truncateMiddle(params.party as string)}
|
text: t('Parties'),
|
||||||
</Link>
|
breadcrumb: () => <Link to={Routes.PARTIES}>{t('Parties')}</Link>,
|
||||||
),
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <Parties />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':party',
|
||||||
|
element: <Party />,
|
||||||
|
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <PartySingle />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: (params: Params<string>) => (
|
||||||
|
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
||||||
|
{truncateMiddle(params.party as string)}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
path: 'assets',
|
||||||
path: 'assets',
|
element: <Party />,
|
||||||
element: <Party />,
|
handle: {
|
||||||
handle: {
|
breadcrumb: (params: Params<string>) => (
|
||||||
breadcrumb: (params: Params<string>) => (
|
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
||||||
<Link to={linkTo(Routes.PARTIES, params.party)}>
|
{truncateMiddle(params.party as string)}
|
||||||
{truncateMiddle(params.party as string)}
|
</Link>
|
||||||
</Link>
|
),
|
||||||
),
|
},
|
||||||
},
|
children: [
|
||||||
children: [
|
{
|
||||||
{
|
index: true,
|
||||||
index: true,
|
element: <PartyAccountsByAsset />,
|
||||||
element: <PartyAccountsByAsset />,
|
handle: {
|
||||||
handle: {
|
breadcrumb: () => {
|
||||||
breadcrumb: () => {
|
return t('Assets');
|
||||||
return t('Assets');
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const assetsRoutes: Route[] = featureFlags.EXPLORER_ASSETS
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
path: Routes.ASSETS,
|
||||||
|
handle: {
|
||||||
|
name: t('Assets'),
|
||||||
|
text: t('Assets'),
|
||||||
|
breadcrumb: () => <Link to={Routes.ASSETS}>{t('Assets')}</Link>,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <AssetsPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':assetId',
|
||||||
|
element: <AssetPage />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: (params: Params<string>) => (
|
||||||
|
<AssetLink assetId={params.assetId as string} />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
],
|
},
|
||||||
},
|
],
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const assetsRoutes: Route[] = FLAGS.EXPLORER_ASSETS
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
path: Routes.ASSETS,
|
|
||||||
handle: {
|
|
||||||
name: t('Assets'),
|
|
||||||
text: t('Assets'),
|
|
||||||
breadcrumb: () => <Link to={Routes.ASSETS}>{t('Assets')}</Link>,
|
|
||||||
},
|
},
|
||||||
children: [
|
]
|
||||||
{
|
: [];
|
||||||
index: true,
|
|
||||||
element: <AssetsPage />,
|
const genesisRoutes: Route[] = featureFlags.EXPLORER_GENESIS
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
path: Routes.GENESIS,
|
||||||
|
handle: {
|
||||||
|
name: t('Genesis'),
|
||||||
|
text: t('Genesis Parameters'),
|
||||||
|
breadcrumb: () => (
|
||||||
|
<Link to={Routes.GENESIS}>{t('Genesis Parameters')}</Link>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
|
element: <Genesis />,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const governanceRoutes: Route[] = featureFlags.EXPLORER_GOVERNANCE
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
path: Routes.GOVERNANCE,
|
||||||
|
handle: {
|
||||||
|
name: t('Governance proposals'),
|
||||||
|
text: t('Governance Proposals'),
|
||||||
|
breadcrumb: () => (
|
||||||
|
<Link to={Routes.GOVERNANCE}>{t('Governance Proposals')}</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
element: <Proposals />,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const marketsRoutes: Route[] = featureFlags.EXPLORER_MARKETS
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
path: Routes.MARKETS,
|
||||||
|
handle: {
|
||||||
|
name: t('Markets'),
|
||||||
|
text: t('Markets'),
|
||||||
|
breadcrumb: () => <Link to={Routes.MARKETS}>{t('Markets')}</Link>,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <MarketsPage />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ':marketId',
|
||||||
|
element: <MarketPage />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: (params: Params<string>) => (
|
||||||
|
<MarketLink id={params.marketId as string} />
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const networkParametersRoutes: Route[] =
|
||||||
|
featureFlags.EXPLORER_NETWORK_PARAMETERS
|
||||||
|
? [
|
||||||
{
|
{
|
||||||
path: ':assetId',
|
path: Routes.NETWORK_PARAMETERS,
|
||||||
element: <AssetPage />,
|
|
||||||
handle: {
|
handle: {
|
||||||
breadcrumb: (params: Params<string>) => (
|
name: t('NetworkParameters'),
|
||||||
<AssetLink assetId={params.assetId as string} />
|
text: t('Network Parameters'),
|
||||||
|
breadcrumb: () => (
|
||||||
|
<Link to={Routes.NETWORK_PARAMETERS}>
|
||||||
|
{t('Network Parameters')}
|
||||||
|
</Link>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
element: <NetworkParameters />,
|
||||||
},
|
},
|
||||||
],
|
]
|
||||||
},
|
: [];
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const genesisRoutes: Route[] = FLAGS.EXPLORER_GENESIS
|
const validators: Route[] = featureFlags.EXPLORER_VALIDATORS
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
path: Routes.GENESIS,
|
path: Routes.VALIDATORS,
|
||||||
handle: {
|
handle: {
|
||||||
name: t('Genesis'),
|
name: t('Validators'),
|
||||||
text: t('Genesis Parameters'),
|
text: t('Validators'),
|
||||||
breadcrumb: () => (
|
breadcrumb: () => (
|
||||||
<Link to={Routes.GENESIS}>{t('Genesis Parameters')}</Link>
|
<Link to={Routes.VALIDATORS}>{t('Validators')}</Link>
|
||||||
),
|
),
|
||||||
},
|
|
||||||
element: <Genesis />,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const governanceRoutes: Route[] = FLAGS.EXPLORER_GOVERNANCE
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
path: Routes.GOVERNANCE,
|
|
||||||
handle: {
|
|
||||||
name: t('Governance proposals'),
|
|
||||||
text: t('Governance Proposals'),
|
|
||||||
breadcrumb: () => (
|
|
||||||
<Link to={Routes.GOVERNANCE}>{t('Governance Proposals')}</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
element: <Proposals />,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const marketsRoutes: Route[] = FLAGS.EXPLORER_MARKETS
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
path: Routes.MARKETS,
|
|
||||||
handle: {
|
|
||||||
name: t('Markets'),
|
|
||||||
text: t('Markets'),
|
|
||||||
breadcrumb: () => <Link to={Routes.MARKETS}>{t('Markets')}</Link>,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <MarketsPage />,
|
|
||||||
},
|
},
|
||||||
{
|
element: <ValidatorsPage />,
|
||||||
path: ':marketId',
|
},
|
||||||
element: <MarketPage />,
|
]
|
||||||
handle: {
|
: [];
|
||||||
breadcrumb: (params: Params<string>) => (
|
|
||||||
<MarketLink id={params.marketId as string} />
|
const linkTo = (...segments: (string | undefined)[]) =>
|
||||||
),
|
compact(segments).join('/');
|
||||||
|
|
||||||
|
const routerConfig: Route[] = [
|
||||||
|
{
|
||||||
|
path: Routes.HOME,
|
||||||
|
element: <Layout />,
|
||||||
|
handle: {
|
||||||
|
name: t('Home'),
|
||||||
|
text: t('Home'),
|
||||||
|
breadcrumb: () => <Link to={Routes.HOME}>{t('Home')}</Link>,
|
||||||
|
},
|
||||||
|
errorElement: <ErrorBoundary />,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <Home />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: Routes.TX,
|
||||||
|
handle: {
|
||||||
|
name: t('Txs'),
|
||||||
|
text: t('Transactions'),
|
||||||
|
breadcrumb: () => <Link to={Routes.TX}>{t('Transactions')}</Link>,
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: ':txHash',
|
||||||
|
element: <Tx />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: (params: Params<string>) => (
|
||||||
|
<Link to={linkTo(Routes.TX, params.txHash)}>
|
||||||
|
{truncateMiddle(remove0x(params.txHash as string))}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
index: true,
|
||||||
|
element: <TxsList />,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: Routes.BLOCKS,
|
||||||
|
handle: {
|
||||||
|
name: t('Blocks'),
|
||||||
|
text: t('Blocks'),
|
||||||
|
breadcrumb: () => <Link to={Routes.BLOCKS}>{t('Blocks')}</Link>,
|
||||||
},
|
},
|
||||||
],
|
element: <BlockPage />,
|
||||||
},
|
children: [
|
||||||
]
|
{
|
||||||
: [];
|
index: true,
|
||||||
|
element: <Blocks />,
|
||||||
const networkParametersRoutes: Route[] = FLAGS.EXPLORER_NETWORK_PARAMETERS
|
},
|
||||||
? [
|
{
|
||||||
{
|
path: ':block',
|
||||||
path: Routes.NETWORK_PARAMETERS,
|
element: <Block />,
|
||||||
handle: {
|
handle: {
|
||||||
name: t('NetworkParameters'),
|
breadcrumb: (params: Params<string>) => (
|
||||||
text: t('Network Parameters'),
|
<Link to={linkTo(Routes.BLOCKS, params.block)}>
|
||||||
breadcrumb: () => (
|
{params.block}
|
||||||
<Link to={Routes.NETWORK_PARAMETERS}>
|
</Link>
|
||||||
{t('Network Parameters')}
|
),
|
||||||
</Link>
|
},
|
||||||
),
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
element: <NetworkParameters />,
|
{
|
||||||
},
|
path: Routes.ORACLES,
|
||||||
]
|
handle: {
|
||||||
: [];
|
name: t('Oracles'),
|
||||||
|
text: t('Oracles'),
|
||||||
const validators: Route[] = FLAGS.EXPLORER_VALIDATORS
|
breadcrumb: () => <Link to={Routes.ORACLES}>{t('Oracles')}</Link>,
|
||||||
? [
|
},
|
||||||
{
|
element: <OraclePage />,
|
||||||
path: Routes.VALIDATORS,
|
children: [
|
||||||
handle: {
|
{
|
||||||
name: t('Validators'),
|
index: true,
|
||||||
text: t('Validators'),
|
element: <Oracles />,
|
||||||
breadcrumb: () => (
|
},
|
||||||
<Link to={Routes.VALIDATORS}>{t('Validators')}</Link>
|
{
|
||||||
),
|
path: ':id',
|
||||||
|
element: <Oracle />,
|
||||||
|
handle: {
|
||||||
|
breadcrumb: (params: Params<string>) => (
|
||||||
|
<Link to={linkTo(Routes.ORACLES, params.id)}>
|
||||||
|
{truncateMiddle(params.id as string)}
|
||||||
|
</Link>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
element: <ValidatorsPage />,
|
{
|
||||||
},
|
path: Routes.DISCLAIMER,
|
||||||
]
|
element: <Disclaimer />,
|
||||||
: [];
|
handle: {
|
||||||
|
name: t('Disclaimer'),
|
||||||
const linkTo = (...segments: (string | undefined)[]) =>
|
text: t('Disclaimer'),
|
||||||
compact(segments).join('/');
|
breadcrumb: () => (
|
||||||
|
<Link to={Routes.DISCLAIMER}>{t('Disclaimer')}</Link>
|
||||||
export const routerConfig: Route[] = [
|
),
|
||||||
{
|
},
|
||||||
path: Routes.HOME,
|
},
|
||||||
element: <Layout />,
|
...partiesRoutes,
|
||||||
handle: {
|
...assetsRoutes,
|
||||||
name: t('Home'),
|
...genesisRoutes,
|
||||||
text: t('Home'),
|
...governanceRoutes,
|
||||||
breadcrumb: () => <Link to={Routes.HOME}>{t('Home')}</Link>,
|
...marketsRoutes,
|
||||||
|
...networkParametersRoutes,
|
||||||
|
...validators,
|
||||||
|
],
|
||||||
},
|
},
|
||||||
errorElement: <ErrorBoundary />,
|
{
|
||||||
children: [
|
path: Routes.RESTRICTED,
|
||||||
{
|
element: <RestrictedPage />,
|
||||||
index: true,
|
handle: {
|
||||||
element: <Home />,
|
name: t('Restricted'),
|
||||||
|
text: t('Restricted'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: Routes.TX,
|
|
||||||
handle: {
|
|
||||||
name: t('Txs'),
|
|
||||||
text: t('Transactions'),
|
|
||||||
breadcrumb: () => <Link to={Routes.TX}>{t('Transactions')}</Link>,
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: ':txHash',
|
|
||||||
element: <Tx />,
|
|
||||||
handle: {
|
|
||||||
breadcrumb: (params: Params<string>) => (
|
|
||||||
<Link to={linkTo(Routes.TX, params.txHash)}>
|
|
||||||
{truncateMiddle(remove0x(params.txHash as string))}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <TxsList />,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: Routes.BLOCKS,
|
|
||||||
handle: {
|
|
||||||
name: t('Blocks'),
|
|
||||||
text: t('Blocks'),
|
|
||||||
breadcrumb: () => <Link to={Routes.BLOCKS}>{t('Blocks')}</Link>,
|
|
||||||
},
|
|
||||||
element: <BlockPage />,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Blocks />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':block',
|
|
||||||
element: <Block />,
|
|
||||||
handle: {
|
|
||||||
breadcrumb: (params: Params<string>) => (
|
|
||||||
<Link to={linkTo(Routes.BLOCKS, params.block)}>
|
|
||||||
{params.block}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: Routes.ORACLES,
|
|
||||||
handle: {
|
|
||||||
name: t('Oracles'),
|
|
||||||
text: t('Oracles'),
|
|
||||||
breadcrumb: () => <Link to={Routes.ORACLES}>{t('Oracles')}</Link>,
|
|
||||||
},
|
|
||||||
element: <OraclePage />,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
index: true,
|
|
||||||
element: <Oracles />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ':id',
|
|
||||||
element: <Oracle />,
|
|
||||||
handle: {
|
|
||||||
breadcrumb: (params: Params<string>) => (
|
|
||||||
<Link to={linkTo(Routes.ORACLES, params.id)}>
|
|
||||||
{truncateMiddle(params.id as string)}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: Routes.DISCLAIMER,
|
|
||||||
element: <Disclaimer />,
|
|
||||||
handle: {
|
|
||||||
name: t('Disclaimer'),
|
|
||||||
text: t('Disclaimer'),
|
|
||||||
breadcrumb: () => (
|
|
||||||
<Link to={Routes.DISCLAIMER}>{t('Disclaimer')}</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...partiesRoutes,
|
|
||||||
...assetsRoutes,
|
|
||||||
...genesisRoutes,
|
|
||||||
...governanceRoutes,
|
|
||||||
...marketsRoutes,
|
|
||||||
...networkParametersRoutes,
|
|
||||||
...validators,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: Routes.RESTRICTED,
|
|
||||||
element: <RestrictedPage />,
|
|
||||||
handle: {
|
|
||||||
name: t('Restricted'),
|
|
||||||
text: t('Restricted'),
|
|
||||||
},
|
},
|
||||||
},
|
];
|
||||||
];
|
return routerConfig;
|
||||||
|
};
|
||||||
export const router = createBrowserRouter(routerConfig);
|
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ import { useFetch } from '@vegaprotocol/react-helpers';
|
|||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import { RenderFetched } from '../../../components/render-fetched';
|
import { RenderFetched } from '../../../components/render-fetched';
|
||||||
import { TxDetails } from './tx-details';
|
import { TxDetails } from './tx-details';
|
||||||
import type { BlockExplorerTransaction } from '../../../routes/types/block-explorer-response';
|
import { type BlockExplorerTransaction } from '../../../routes/types/block-explorer-response';
|
||||||
import { toNonHex } from '../../../components/search/detect-search';
|
import { toNonHex } from '../../../components/search/detect-search';
|
||||||
import { PageHeader } from '../../../components/page-header';
|
import { PageHeader } from '../../../components/page-header';
|
||||||
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
import { useDocumentTitle } from '../../../hooks/use-document-title';
|
||||||
|
|
||||||
|
type Params = { txHash: string };
|
||||||
|
|
||||||
const Tx = () => {
|
const Tx = () => {
|
||||||
const { txHash } = useParams<{ txHash: string }>();
|
const { txHash } = useParams<Params>();
|
||||||
const hash = txHash ? toNonHex(txHash) : '';
|
const hash = txHash ? toNonHex(txHash) : '';
|
||||||
let errorMessage: string | undefined = undefined;
|
let errorMessage: string | undefined = undefined;
|
||||||
|
|
||||||
@@ -29,6 +31,10 @@ const Tx = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data || !data?.transaction) {
|
||||||
|
errorMessage = 'Transaction not found';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<PageHeader
|
<PageHeader
|
||||||
@@ -47,7 +53,7 @@ const Tx = () => {
|
|||||||
<TxDetails
|
<TxDetails
|
||||||
className="mb-28"
|
className="mb-28"
|
||||||
txData={data?.transaction}
|
txData={data?.transaction}
|
||||||
pubKey={data?.transaction.submitter}
|
pubKey={data?.transaction?.submitter}
|
||||||
/>
|
/>
|
||||||
</RenderFetched>
|
</RenderFetched>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ const txData: BlockExplorerTransactionResult = {
|
|||||||
type: 'type',
|
type: 'type',
|
||||||
command: {} as ValidatorHeartbeat,
|
command: {} as ValidatorHeartbeat,
|
||||||
signature: {
|
signature: {
|
||||||
|
version: '1',
|
||||||
|
algo: 'vega/ed25519',
|
||||||
value: '123',
|
value: '123',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ interface TxDetailsProps {
|
|||||||
export const txDetailsTruncateLength = 30;
|
export const txDetailsTruncateLength = 30;
|
||||||
|
|
||||||
export const TxDetails = ({ txData, pubKey }: TxDetailsProps) => {
|
export const TxDetails = ({ txData, pubKey }: TxDetailsProps) => {
|
||||||
if (!txData) {
|
if (!txData || !pubKey) {
|
||||||
return <>{t('Awaiting Block Explorer transaction details')}</>;
|
return <>{t('Transaction could not be found')}</>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<section className="mb-10" key={txData.hash}>
|
<section className="mb-10" key={txData.hash}>
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export interface BlockExplorerTransactionResult {
|
|||||||
cursor: string;
|
cursor: string;
|
||||||
command: components['schemas']['blockexplorerv1transaction'];
|
command: components['schemas']['blockexplorerv1transaction'];
|
||||||
signature: {
|
signature: {
|
||||||
|
version: string;
|
||||||
|
algo: string;
|
||||||
value: string;
|
value: string;
|
||||||
};
|
};
|
||||||
error?: string;
|
error?: string;
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
// expect(element).toHaveTextContent(/react/i)
|
// expect(element).toHaveTextContent(/react/i)
|
||||||
// learn more: https://github.com/testing-library/jest-dom
|
// learn more: https://github.com/testing-library/jest-dom
|
||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
|
import { locales } from '@vegaprotocol/i18n';
|
||||||
|
import i18n from 'i18next';
|
||||||
|
import { initReactI18next } from 'react-i18next';
|
||||||
|
|
||||||
Object.defineProperty(window, 'ResizeObserver', {
|
Object.defineProperty(window, 'ResizeObserver', {
|
||||||
writable: false,
|
writable: false,
|
||||||
@@ -13,3 +16,14 @@ Object.defineProperty(window, 'ResizeObserver', {
|
|||||||
disconnect: jest.fn(),
|
disconnect: jest.fn(),
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set up i18n instance so that components have the correct default
|
||||||
|
// en translations
|
||||||
|
i18n.use(initReactI18next).init({
|
||||||
|
// we init with resources
|
||||||
|
resources: locales,
|
||||||
|
fallbackLng: 'en',
|
||||||
|
nsSeparator: false,
|
||||||
|
ns: ['explorer'],
|
||||||
|
defaultNS: 'explorer',
|
||||||
|
});
|
||||||
|
|||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../libs/i18n/src/locales
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import type { Module } from 'i18next';
|
||||||
|
import i18n from 'i18next';
|
||||||
|
import HttpBackend from 'i18next-http-backend';
|
||||||
|
import LocizeBackend from 'i18next-locize-backend';
|
||||||
|
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||||
|
import { initReactI18next } from 'react-i18next';
|
||||||
|
|
||||||
|
const isInDev = process.env.NODE_ENV === 'development';
|
||||||
|
const useLocize = isInDev && !!process.env.NX_USE_LOCIZE;
|
||||||
|
|
||||||
|
const backend = useLocize
|
||||||
|
? {
|
||||||
|
projectId: '96ac1231-4bdd-455a-b9d7-f5322a2e7430',
|
||||||
|
apiKey: process.env.NX_LOCIZE_API_KEY,
|
||||||
|
referenceLng: 'en',
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
loadPath: '/assets/locales/{{lng}}/{{ns}}.json',
|
||||||
|
};
|
||||||
|
|
||||||
|
const Backend: Module = useLocize ? LocizeBackend : HttpBackend;
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(Backend)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.use(initReactI18next)
|
||||||
|
.init({
|
||||||
|
lng: 'en',
|
||||||
|
fallbackLng: 'en',
|
||||||
|
supportedLngs: ['en'],
|
||||||
|
load: 'languageOnly',
|
||||||
|
debug: isInDev,
|
||||||
|
// have a common namespace used around the full app
|
||||||
|
ns: ['explorer'],
|
||||||
|
defaultNS: 'explorer',
|
||||||
|
keySeparator: false, // we use content as keys
|
||||||
|
nsSeparator: false,
|
||||||
|
backend,
|
||||||
|
saveMissing: useLocize && !!process.env.NX_LOCIZE_API_KEY,
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
||||||
+2
-2
@@ -8,13 +8,13 @@ type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
|||||||
type XOR<T, U> = T | U extends object
|
type XOR<T, U> = T | U extends object
|
||||||
? (Without<T, U> & U) | (Without<U, T> & T)
|
? (Without<T, U> & U) | (Without<U, T> & T)
|
||||||
: T | U;
|
: T | U;
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
type OneOf<T extends any[]> = T extends [infer Only]
|
type OneOf<T extends any[]> = T extends [infer Only]
|
||||||
? Only
|
? Only
|
||||||
: T extends [infer A, infer B, ...infer Rest]
|
: T extends [infer A, infer B, ...infer Rest]
|
||||||
? OneOf<[XOR<A, B>, ...Rest]>
|
? OneOf<[XOR<A, B>, ...Rest]>
|
||||||
: never;
|
: never;
|
||||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
export interface paths {
|
export interface paths {
|
||||||
'/info': {
|
'/info': {
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
"extends": "./tsconfig.json",
|
"extends": "./tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../../dist/out-tsc",
|
"outDir": "../../dist/out-tsc",
|
||||||
"types": ["node"]
|
"types": [
|
||||||
|
"node",
|
||||||
|
"@nx/react/typings/cssmodule.d.ts",
|
||||||
|
"@nx/react/typings/image.d.ts"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
|
"../../node_modules/@nx/react/typings/cssmodule.d.ts",
|
||||||
|
|||||||
@@ -3,7 +3,13 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../../dist/out-tsc",
|
"outDir": "../../dist/out-tsc",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"types": ["jest", "node", "@testing-library/jest-dom"]
|
"types": [
|
||||||
|
"jest",
|
||||||
|
"node",
|
||||||
|
"@testing-library/jest-dom",
|
||||||
|
"@nx/react/typings/cssmodule.d.ts",
|
||||||
|
"@nx/react/typings/image.d.ts"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"**/*.test.ts",
|
"**/*.test.ts",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
{
|
{
|
||||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
||||||
"ignorePatterns": ["!**/*"],
|
"ignorePatterns": ["!**/*", "cypress"],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
"rules": {}
|
"rules": {
|
||||||
|
"cypress/unsafe-to-chain-command": 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lint": {
|
"lint": {
|
||||||
"executor": "@nx/linter:eslint",
|
"executor": "@nx/eslint:lint",
|
||||||
"outputs": ["{options.outputFile}"],
|
"outputs": ["{options.outputFile}"],
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["apps/governance-e2e/**/*.{js,ts}"]
|
"lintFilePatterns": ["apps/governance-e2e/**/*.{js,ts}"]
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import {
|
|||||||
switchVegaWalletPubKey,
|
switchVegaWalletPubKey,
|
||||||
vegaWalletSetSpecifiedApprovalAmount,
|
vegaWalletSetSpecifiedApprovalAmount,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-functions';
|
||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import { type testFreeformProposal } from '../../support/common-interfaces';
|
||||||
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
import { formatDateWithLocalTimezone } from '@vegaprotocol/utils';
|
||||||
import {
|
import {
|
||||||
createGovernanceTransferProposalTxBody,
|
createGovernanceTransferProposalTxBody,
|
||||||
@@ -61,6 +61,7 @@ const marketProposalType = 'proposal-type';
|
|||||||
describe(
|
describe(
|
||||||
'Governance flow for proposal details',
|
'Governance flow for proposal details',
|
||||||
{ tags: '@slow' },
|
{ tags: '@slow' },
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
function () {
|
function () {
|
||||||
before('connect wallets and set approval limit', function () {
|
before('connect wallets and set approval limit', function () {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
@@ -78,6 +79,7 @@ describe(
|
|||||||
getProposalInformationFromTable('ID').invoke('text').as('parentMarketId');
|
getProposalInformationFromTable('ID').invoke('text').as('parentMarketId');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit proposals tab', function () {
|
beforeEach('visit proposals tab', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -323,6 +325,7 @@ describe(
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
cy.VegaWalletSubmitProposal(
|
cy.VegaWalletSubmitProposal(
|
||||||
|
// @ts-ignore this is any
|
||||||
createSuccessorMarketProposalTxBody(this.parentMarketId)
|
createSuccessorMarketProposalTxBody(this.parentMarketId)
|
||||||
);
|
);
|
||||||
navigateTo(navigation.proposals);
|
navigateTo(navigation.proposals);
|
||||||
@@ -334,6 +337,7 @@ describe(
|
|||||||
cy.getByTestId(proposalTermsToggle).click();
|
cy.getByTestId(proposalTermsToggle).click();
|
||||||
cy.get('.language-json').within(() => {
|
cy.get('.language-json').within(() => {
|
||||||
cy.get('.hljs-attr').should('contain.text', 'parentMarketId');
|
cy.get('.hljs-attr').should('contain.text', 'parentMarketId');
|
||||||
|
// @ts-ignore this is any
|
||||||
cy.get('.hljs-string').should('contain.text', this.parentMarketId);
|
cy.get('.hljs-string').should('contain.text', this.parentMarketId);
|
||||||
cy.get('.hljs-attr').should('contain.text', 'insurancePoolFraction');
|
cy.get('.hljs-attr').should('contain.text', 'insurancePoolFraction');
|
||||||
cy.get('.hljs-string').should('contain.text', '0.75');
|
cy.get('.hljs-string').should('contain.text', '0.75');
|
||||||
@@ -352,6 +356,7 @@ describe(
|
|||||||
validateProposalDetailsDiff(
|
validateProposalDetailsDiff(
|
||||||
'Parent Market ID',
|
'Parent Market ID',
|
||||||
proposalChangeType.ADDED,
|
proposalChangeType.ADDED,
|
||||||
|
// @ts-ignore this is any
|
||||||
this.parentMarketId
|
this.parentMarketId
|
||||||
);
|
);
|
||||||
validateProposalDetailsDiff(
|
validateProposalDetailsDiff(
|
||||||
@@ -450,6 +455,7 @@ describe(
|
|||||||
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
||||||
submitUniqueRawProposal({
|
submitUniqueRawProposal({
|
||||||
proposalBody: proposalPath,
|
proposalBody: proposalPath,
|
||||||
|
// @ts-ignore this is any
|
||||||
updateMarketId: this.parentMarketId,
|
updateMarketId: this.parentMarketId,
|
||||||
enactmentTimestamp: enactmentTimestamp,
|
enactmentTimestamp: enactmentTimestamp,
|
||||||
closingTimestamp: closingTimestamp,
|
closingTimestamp: closingTimestamp,
|
||||||
@@ -466,6 +472,7 @@ describe(
|
|||||||
cy.getByTestId('proposal-update-market-state').within(() => {
|
cy.getByTestId('proposal-update-market-state').within(() => {
|
||||||
getProposalInformationFromTable('Market ID')
|
getProposalInformationFromTable('Market ID')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
|
// @ts-ignore this is any
|
||||||
.and('eq', this.parentMarketId);
|
.and('eq', this.parentMarketId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -476,6 +483,7 @@ describe(
|
|||||||
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
||||||
submitUniqueRawProposal({
|
submitUniqueRawProposal({
|
||||||
proposalBody: proposalPath,
|
proposalBody: proposalPath,
|
||||||
|
// @ts-ignore this is any
|
||||||
updateMarketId: this.parentMarketId,
|
updateMarketId: this.parentMarketId,
|
||||||
enactmentTimestamp: enactmentTimestamp,
|
enactmentTimestamp: enactmentTimestamp,
|
||||||
closingTimestamp: closingTimestamp,
|
closingTimestamp: closingTimestamp,
|
||||||
@@ -489,6 +497,7 @@ describe(
|
|||||||
cy.getByTestId('proposal-update-market-state').within(() => {
|
cy.getByTestId('proposal-update-market-state').within(() => {
|
||||||
getProposalInformationFromTable('Market ID')
|
getProposalInformationFromTable('Market ID')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
|
// @ts-ignore this is any
|
||||||
.and('eq', this.parentMarketId);
|
.and('eq', this.parentMarketId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -499,6 +508,7 @@ describe(
|
|||||||
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
const closingTimestamp = createTenDigitUnixTimeStampForSpecifiedDays(2);
|
||||||
submitUniqueRawProposal({
|
submitUniqueRawProposal({
|
||||||
proposalBody: proposalPath,
|
proposalBody: proposalPath,
|
||||||
|
// @ts-ignore this is any
|
||||||
updateMarketId: this.parentMarketId,
|
updateMarketId: this.parentMarketId,
|
||||||
enactmentTimestamp: enactmentTimestamp,
|
enactmentTimestamp: enactmentTimestamp,
|
||||||
closingTimestamp: closingTimestamp,
|
closingTimestamp: closingTimestamp,
|
||||||
@@ -518,6 +528,7 @@ describe(
|
|||||||
cy.getByTestId('proposal-update-market-state').within(() => {
|
cy.getByTestId('proposal-update-market-state').within(() => {
|
||||||
getProposalInformationFromTable('Market ID')
|
getProposalInformationFromTable('Market ID')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
|
// @ts-ignore this is any
|
||||||
.and('eq', this.parentMarketId);
|
.and('eq', this.parentMarketId);
|
||||||
getProposalDetailsValue('Termination Price').should(
|
getProposalDetailsValue('Termination Price').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ context(
|
|||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit proposals', function () {
|
beforeEach('visit proposals', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import {
|
|||||||
vegaWalletTeardown,
|
vegaWalletTeardown,
|
||||||
} from '../../support/wallet-functions';
|
} from '../../support/wallet-functions';
|
||||||
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
import { ethereumWalletConnect } from '../../support/wallet-eth.functions';
|
||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import { type testFreeformProposal } from '../../support/common-interfaces';
|
||||||
|
|
||||||
const vegaWalletStakedBalances = 'vega-wallet-balance-staked-validators';
|
const vegaWalletStakedBalances = 'vega-wallet-balance-staked-validators';
|
||||||
const vegaWalletAssociatedBalance = 'associated-amount';
|
const vegaWalletAssociatedBalance = 'associated-amount';
|
||||||
@@ -78,6 +78,7 @@ context(
|
|||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit governance tab', function () {
|
beforeEach('visit governance tab', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -301,6 +302,7 @@ context(
|
|||||||
cy.getByTestId(voteButtons).should('not.exist');
|
cy.getByTestId(voteButtons).should('not.exist');
|
||||||
cy.getByTestId('min-proposal-requirements').should(
|
cy.getByTestId('min-proposal-requirements').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
|
// @ts-ignore this is any
|
||||||
`You must have at least ${this.minVoterBalance} VEGA associated to vote on this proposal`
|
`You must have at least ${this.minVoterBalance} VEGA associated to vote on this proposal`
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ context(
|
|||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit governance tab', function () {
|
beforeEach('visit governance tab', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -216,6 +217,7 @@ context(
|
|||||||
// 3003-PMAN-001
|
// 3003-PMAN-001
|
||||||
it(
|
it(
|
||||||
'Able to submit valid new market proposal',
|
'Able to submit valid new market proposal',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
const proposalTitle = 'Test new market proposal';
|
const proposalTitle = 'Test new market proposal';
|
||||||
@@ -631,6 +633,7 @@ context(
|
|||||||
);
|
);
|
||||||
cy.fixture('/proposals/successor-market').then((newMarketProposal) => {
|
cy.fixture('/proposals/successor-market').then((newMarketProposal) => {
|
||||||
newMarketProposal.changes.successor.parentMarketId =
|
newMarketProposal.changes.successor.parentMarketId =
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
this.parentMarketId;
|
this.parentMarketId;
|
||||||
const newMarketPayload = JSON.stringify(newMarketProposal);
|
const newMarketPayload = JSON.stringify(newMarketProposal);
|
||||||
cy.getByTestId(newProposalTerms).type(newMarketPayload, {
|
cy.getByTestId(newProposalTerms).type(newMarketPayload, {
|
||||||
@@ -658,6 +661,7 @@ context(
|
|||||||
.should('have.text', 'Successor market to: TEST.24h')
|
.should('have.text', 'Successor market to: TEST.24h')
|
||||||
.find('a')
|
.find('a')
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
.and('contain', this.parentMarketId);
|
.and('contain', this.parentMarketId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { testFreeformProposal } from '../../support/common-interfaces';
|
import { type testFreeformProposal } from '../../support/common-interfaces';
|
||||||
import {
|
import {
|
||||||
navigateTo,
|
navigateTo,
|
||||||
navigation,
|
navigation,
|
||||||
@@ -33,12 +33,14 @@ const voteMajorityNotMet = 'token-majority-not-met';
|
|||||||
const voteMajorityMet = 'token-majority-met';
|
const voteMajorityMet = 'token-majority-met';
|
||||||
const votesForPercentage = 'votes-for-percentage';
|
const votesForPercentage = 'votes-for-percentage';
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
||||||
before('connect wallets and set approval limit', function () {
|
before('connect wallets and set approval limit', function () {
|
||||||
vegaWalletSetSpecifiedApprovalAmount('1000');
|
vegaWalletSetSpecifiedApprovalAmount('1000');
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit proposals tab', function () {
|
beforeEach('visit proposals tab', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -106,6 +108,7 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () {
|
|||||||
it('Newly created proposals list - shows open proposals in an open state', function () {
|
it('Newly created proposals list - shows open proposals in an open state', function () {
|
||||||
// 3001-VOTE-004
|
// 3001-VOTE-004
|
||||||
// 3001-VOTE-035
|
// 3001-VOTE-035
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
createRawProposal(this.minProposerBalance);
|
createRawProposal(this.minProposerBalance);
|
||||||
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
cy.get<testFreeformProposal>('@rawProposal').then((rawProposal) => {
|
||||||
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
getProposalFromTitle(rawProposal.rationale.title).within(() => {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ context(
|
|||||||
|
|
||||||
describe('Eth wallet - contains VEGA tokens', function () {
|
describe('Eth wallet - contains VEGA tokens', function () {
|
||||||
beforeEach(
|
beforeEach(
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
'teardown wallet & drill into a specific validator',
|
'teardown wallet & drill into a specific validator',
|
||||||
function () {
|
function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
@@ -237,6 +238,7 @@ context(
|
|||||||
// 1002-STKE-041 1002-STKE-053
|
// 1002-STKE-041 1002-STKE-053
|
||||||
it(
|
it(
|
||||||
'Able to remove part of a stake against a validator',
|
'Able to remove part of a stake against a validator',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
ensureSpecifiedUnstakedTokensAreAssociated('4');
|
ensureSpecifiedUnstakedTokensAreAssociated('4');
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ context(
|
|||||||
|
|
||||||
describe('Eth wallet - contains VEGA tokens', function () {
|
describe('Eth wallet - contains VEGA tokens', function () {
|
||||||
beforeEach(
|
beforeEach(
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
'teardown wallet & drill into a specific validator',
|
'teardown wallet & drill into a specific validator',
|
||||||
function () {
|
function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
@@ -67,6 +68,7 @@ context(
|
|||||||
|
|
||||||
it(
|
it(
|
||||||
'Able to associate tokens - from wallet',
|
'Able to associate tokens - from wallet',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
//1004-ASSO-003
|
//1004-ASSO-003
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ context(
|
|||||||
depositAsset(usdcEthAddress, '1000', 5);
|
depositAsset(usdcEthAddress, '1000', 5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('Navigate to withdrawal page', function () {
|
beforeEach('Navigate to withdrawal page', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -101,6 +102,7 @@ context(
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
it.skip(
|
it.skip(
|
||||||
'Able to withdraw asset: -eth wallet connected -withdraw funds button',
|
'Able to withdraw asset: -eth wallet connected -withdraw funds button',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
// fill in withdrawal form
|
// fill in withdrawal form
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
beforeEach('visit home page', function () {
|
beforeEach('visit home page', function () {
|
||||||
cy.clearLocalStorage();
|
cy.clearLocalStorage();
|
||||||
turnTelemetryOff();
|
turnTelemetryOff();
|
||||||
@@ -46,7 +47,7 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
|||||||
.and('contain.text', 'USDC (fake)');
|
.and('contain.text', 'USDC (fake)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Unable to submit proposal with public key', function () {
|
it.skip('Unable to submit proposal with public key', function () {
|
||||||
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
const expectedErrorTxt = `You are connected in a view only state for public key: ${vegaWalletPubKey}. In order to send transactions you must connect to a real wallet.`;
|
||||||
|
|
||||||
goToMakeNewProposal(governanceProposalType.RAW);
|
goToMakeNewProposal(governanceProposalType.RAW);
|
||||||
@@ -54,7 +55,10 @@ context('View functionality with public key', { tags: '@smoke' }, function () {
|
|||||||
cy.getByTestId('dialog-content')
|
cy.getByTestId('dialog-content')
|
||||||
.first()
|
.first()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.get('h1').should('have.text', 'Transaction failed');
|
cy.getByTestId('dialog-title').should(
|
||||||
|
'have.text',
|
||||||
|
'Transaction failed'
|
||||||
|
);
|
||||||
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
cy.getByTestId('Error').should('have.text', expectedErrorTxt);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ context(
|
|||||||
.invoke('text')
|
.invoke('text')
|
||||||
.then(($newPageNumber) => {
|
.then(($newPageNumber) => {
|
||||||
const newPageNumber = Number($newPageNumber.slice(5));
|
const newPageNumber = Number($newPageNumber.slice(5));
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
expect(newPageNumber).to.be.greaterThan(currentPageNumber);
|
expect(newPageNumber).to.be.greaterThan(currentPageNumber);
|
||||||
cy.getByTestId('goto-previous-page').click();
|
cy.getByTestId('goto-previous-page').click();
|
||||||
cy.getByTestId('page-info').should(
|
cy.getByTestId('page-info').should(
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ context('Validators Page - verify elements on page', function () {
|
|||||||
cy.mockChainId();
|
cy.mockChainId();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
describe('with wallets disconnected', { tags: '@smoke' }, function () {
|
||||||
it('Should have validators tab highlighted', function () {
|
it('Should have validators tab highlighted', function () {
|
||||||
verifyTabHighlighted(navigation.validators);
|
verifyTabHighlighted(navigation.validators);
|
||||||
@@ -76,6 +77,7 @@ context('Validators Page - verify elements on page', function () {
|
|||||||
describe(
|
describe(
|
||||||
'Should be able to see validator list from the staking page',
|
'Should be able to see validator list from the staking page',
|
||||||
{ tags: '@regression' },
|
{ tags: '@regression' },
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
function () {
|
function () {
|
||||||
// 1002-STKE-050
|
// 1002-STKE-050
|
||||||
it('Should be able to see validator names', function () {
|
it('Should be able to see validator names', function () {
|
||||||
@@ -180,6 +182,7 @@ context('Validators Page - verify elements on page', function () {
|
|||||||
describe(
|
describe(
|
||||||
'Should be able to see static information about a validator',
|
'Should be able to see static information about a validator',
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
function () {
|
function () {
|
||||||
before('connect wallets and click on validator', function () {
|
before('connect wallets and click on validator', function () {
|
||||||
cy.mockChainId();
|
cy.mockChainId();
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ context(
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
expect(parseFloat(this.value).toFixed(1)).to.equal(
|
expect(parseFloat(this.value).toFixed(1)).to.equal(
|
||||||
(Math.round((this.locked + this.unlocked) * 100) / 100).toFixed(
|
(Math.round((this.locked + this.unlocked) * 100) / 100).toFixed(
|
||||||
1
|
1
|
||||||
@@ -270,6 +271,7 @@ context(
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
expect(this.value).to.equal(this.locked + this.unlocked);
|
expect(this.value).to.equal(this.locked + this.unlocked);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ context(
|
|||||||
// 0002-WCON-008
|
// 0002-WCON-008
|
||||||
it(
|
it(
|
||||||
'should have truncated account number visible',
|
'should have truncated account number visible',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
cy.get(walletContainer).within(() => {
|
cy.get(walletContainer).within(() => {
|
||||||
@@ -125,6 +126,7 @@ context(
|
|||||||
|
|
||||||
it(
|
it(
|
||||||
'should have Vega Associated currency value visible',
|
'should have Vega Associated currency value visible',
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
{ tags: '@smoke' },
|
{ tags: '@smoke' },
|
||||||
function () {
|
function () {
|
||||||
cy.get(walletContainer).within(() => {
|
cy.get(walletContainer).within(() => {
|
||||||
@@ -135,14 +137,19 @@ context(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it('should have Unstaked value visible', { tags: '@smoke' }, function () {
|
it(
|
||||||
cy.get(walletContainer).within(() => {
|
'should have Unstaked value visible',
|
||||||
cy.get(vegaUnstaked)
|
// @ts-ignore clash between jest and cypress
|
||||||
.should('be.visible')
|
{ tags: '@smoke' },
|
||||||
.invoke('text')
|
function () {
|
||||||
.and('not.be.empty');
|
cy.get(walletContainer).within(() => {
|
||||||
});
|
cy.get(vegaUnstaked)
|
||||||
});
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.and('not.be.empty');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it('should have Governance button visible', function () {
|
it('should have Governance button visible', function () {
|
||||||
cy.get(walletContainer).within(() => {
|
cy.get(walletContainer).within(() => {
|
||||||
@@ -295,13 +302,17 @@ context(
|
|||||||
|
|
||||||
cy.getByTestId(vegaWalletCurrencyTitle)
|
cy.getByTestId(vegaWalletCurrencyTitle)
|
||||||
.contains(name)
|
.contains(name)
|
||||||
.parent()
|
.parent() // back to currency-title
|
||||||
.siblings(txTimeout)
|
.parent() // back to container
|
||||||
.should((elementAmount) => {
|
.within(() => {
|
||||||
const displayedAmount = parseFloat(elementAmount.text());
|
cy.get(
|
||||||
expect(displayedAmount).be.gte(expectedAmount);
|
'[data-account-type="account_type_general"] [data-value]'
|
||||||
|
).should((elementAmount) => {
|
||||||
|
const displayedAmount = parseFloat(elementAmount.text());
|
||||||
|
// @ts-ignore clash between jest and cypress
|
||||||
|
expect(displayedAmount).be.gte(expectedAmount);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.getByTestId(vegaWalletCurrencyTitle)
|
cy.getByTestId(vegaWalletCurrencyTitle)
|
||||||
.contains(name)
|
.contains(name)
|
||||||
.parent()
|
.parent()
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ export function createNewMarketProposalTxBody(): ProposalSubmissionBody {
|
|||||||
performanceHysteresisEpochs: 2,
|
performanceHysteresisEpochs: 2,
|
||||||
slaCompetitionFactor: '0.1',
|
slaCompetitionFactor: '0.1',
|
||||||
},
|
},
|
||||||
|
// FIXME: workaround because of https://github.com/vegaprotocol/vega/issues/10343
|
||||||
quadraticSlippageFactor: '0',
|
quadraticSlippageFactor: '0',
|
||||||
instrument: {
|
instrument: {
|
||||||
name: 'Token test market',
|
name: 'Token test market',
|
||||||
@@ -196,6 +197,7 @@ export function createNewMarketProposalTxBody(): ProposalSubmissionBody {
|
|||||||
timeWindow: '3600',
|
timeWindow: '3600',
|
||||||
scalingFactor: 10,
|
scalingFactor: 10,
|
||||||
},
|
},
|
||||||
|
// FIXME: workaround because of https://github.com/vegaprotocol/vega/issues/10343
|
||||||
triggeringRatio: '0.7',
|
triggeringRatio: '0.7',
|
||||||
auctionExtension: '1',
|
auctionExtension: '1',
|
||||||
},
|
},
|
||||||
@@ -240,6 +242,7 @@ export function createSuccessorMarketProposalTxBody(
|
|||||||
decimalPlaces: '5',
|
decimalPlaces: '5',
|
||||||
positionDecimalPlaces: '5',
|
positionDecimalPlaces: '5',
|
||||||
linearSlippageFactor: '0.001',
|
linearSlippageFactor: '0.001',
|
||||||
|
// FIXME: workaround because of https://github.com/vegaprotocol/vega/issues/10343
|
||||||
quadraticSlippageFactor: '0',
|
quadraticSlippageFactor: '0',
|
||||||
liquiditySlaParameters: {
|
liquiditySlaParameters: {
|
||||||
priceRange: '0.5',
|
priceRange: '0.5',
|
||||||
@@ -334,6 +337,7 @@ export function createSuccessorMarketProposalTxBody(
|
|||||||
timeWindow: '3600',
|
timeWindow: '3600',
|
||||||
scalingFactor: 10,
|
scalingFactor: 10,
|
||||||
},
|
},
|
||||||
|
// FIXME: workaround because of https://github.com/vegaprotocol/vega/issues/10343
|
||||||
triggeringRatio: '0.7',
|
triggeringRatio: '0.7',
|
||||||
auctionExtension: '1',
|
auctionExtension: '1',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -256,10 +256,7 @@ export function validateWalletCurrency(
|
|||||||
.parent()
|
.parent()
|
||||||
.parent()
|
.parent()
|
||||||
.within(() => {
|
.within(() => {
|
||||||
cy.getByTestId('currency-value', txTimeout).should(
|
cy.get('[data-value]', txTimeout).should('have.text', expectedAmount);
|
||||||
'have.text',
|
|
||||||
expectedAmount
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ CYPRESS_FAIRGROUND=false
|
|||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
NX_PRODUCT_PERPETUALS=true
|
NX_PRODUCT_PERPETUALS=true
|
||||||
NX_UPDATE_MARKET_STATE=true
|
NX_UPDATE_MARKET_STATE=true
|
||||||
NX_REFERRALS=true
|
NX_REFERRALS=true
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
|||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
NX_PRODUCT_PERPETUALS=true
|
NX_PRODUCT_PERPETUALS=true
|
||||||
NX_UPDATE_MARKET_STATE=true
|
NX_UPDATE_MARKET_STATE=true
|
||||||
NX_REFERRALS=true
|
NX_REFERRALS=true
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
|
|||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
NX_PRODUCT_PERPETUALS=true
|
NX_PRODUCT_PERPETUALS=true
|
||||||
NX_UPDATE_MARKET_STATE=true
|
NX_UPDATE_MARKET_STATE=true
|
||||||
NX_REFERRALS=true
|
NX_REFERRALS=true
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
|
|||||||
|
|
||||||
# Cosmic elevator flags
|
# Cosmic elevator flags
|
||||||
NX_SUCCESSOR_MARKETS=true
|
NX_SUCCESSOR_MARKETS=true
|
||||||
NX_METAMASK_SNAPS=false
|
NX_METAMASK_SNAPS=true
|
||||||
NX_PRODUCT_PERPETUALS=true
|
NX_PRODUCT_PERPETUALS=true
|
||||||
NX_UPDATE_MARKET_STATE=true
|
NX_UPDATE_MARKET_STATE=true
|
||||||
NX_REFERRALS=true
|
NX_REFERRALS=true
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user