Merge remote-tracking branch 'origin/master' into feat/75-link-like-button
This commit is contained in:
commit
9b4a41be07
@ -25,6 +25,13 @@
|
|||||||
"case": "kebabCase",
|
"case": "kebabCase",
|
||||||
"ignore": ["\\[[a-zA-Z]+\\]\\.page"]
|
"ignore": ["\\[[a-zA-Z]+\\]\\.page"]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"no-restricted-imports": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"name": "lodash",
|
||||||
|
"message": "Import the specific methods you need from lodash e.g. `import get from 'lodash/get'`. This helps with bundle sizing."
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,23 +1,3 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"
|
||||||
|
@ -1,23 +1,3 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
|
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
|
||||||
@ -28,7 +8,6 @@ NX_VEGA_URL = "https://api.token.vega.xyz/query"
|
|||||||
NX_EXPLORER_ASSETS = 1
|
NX_EXPLORER_ASSETS = 1
|
||||||
NX_EXPLORER_GENESIS = 1
|
NX_EXPLORER_GENESIS = 1
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
NX_EXPLORER_GOVERNANCE = 1
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
||||||
NX_EXPLORER_PARTIES = 1
|
NX_EXPLORER_PARTIES = 1
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
NX_EXPLORER_VALIDATORS = 1
|
||||||
|
@ -1,30 +1,9 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
|
||||||
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
|
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
|
||||||
|
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS = 1
|
NX_EXPLORER_ASSETS = 1
|
||||||
NX_EXPLORER_GENESIS = 1
|
NX_EXPLORER_GENESIS = 1
|
||||||
|
@ -1,23 +1,3 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"
|
||||||
|
@ -1,23 +1,3 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
||||||
|
@ -1,4 +1,23 @@
|
|||||||
Feature: Home page
|
Feature: Home page
|
||||||
|
|
||||||
Scenario: Visit Home page
|
Scenario Outline: Succesfful search for specific id by <IdType>
|
||||||
Given I am on the homepage
|
Given I am on the homepage
|
||||||
|
When I search for '<Id>'
|
||||||
|
Then I am redirected to page containing id '<Id>'
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| IdType | Id |
|
||||||
|
| Block Id | 973624 |
|
||||||
|
| Tx Hash | 9ED3718AA8308E7E08EC588EE7AADAF49711D2138860D8914B4D81A2054D9FB8 |
|
||||||
|
| Tx Id | 0x61DCCEBB955087F50D0B85382DAE138EDA9631BF1A4F92E563D528904AA38898 |
|
||||||
|
|
||||||
|
Scenario Outline: Error message displayed when invalid search by <invalidType>
|
||||||
|
Given I am on the homepage
|
||||||
|
When I search for '<Id>'
|
||||||
|
Then search error message "<errorMessage>" is displayed
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| invalidType | Id | errorMessage |
|
||||||
|
| wrong string length | 9ED3718AA8308E7E08EC588EE7AADAF497D2138860D8914B4D81A2054D9FB8 | Something doesn't look right |
|
||||||
|
| invalid hash | 9ED3718AA8308E7E08ECht8EE753DAF49711D2138860D8914B4D81A2054D9FB8 | Transaction is not hexadecimal |
|
||||||
|
| empty search | | Search required |
|
||||||
|
@ -9,7 +9,9 @@ export default class BasePage {
|
|||||||
networkParametersUrl = '/network-parameters';
|
networkParametersUrl = '/network-parameters';
|
||||||
validatorsUrl = '/validators';
|
validatorsUrl = '/validators';
|
||||||
blockExplorerHeader = 'explorer-header';
|
blockExplorerHeader = 'explorer-header';
|
||||||
searchField = 'search-input';
|
searchField = 'search';
|
||||||
|
searchButton = 'search-button';
|
||||||
|
searchError = 'search-error';
|
||||||
|
|
||||||
navigateToTxs() {
|
navigateToTxs() {
|
||||||
cy.get(`a[href='${this.transactionsUrl}']`).click();
|
cy.get(`a[href='${this.transactionsUrl}']`).click();
|
||||||
@ -48,17 +50,31 @@ export default class BasePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
search(searchText) {
|
search(searchText) {
|
||||||
cy.getByTestId(this.searchField).type(searchText);
|
if (searchText) {
|
||||||
|
cy.getByTestId(this.searchField).type(searchText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clickSearch() {
|
||||||
|
cy.getByTestId(this.searchButton).click();
|
||||||
|
}
|
||||||
|
|
||||||
|
validateUrl(expectedUrl) {
|
||||||
|
cy.url().should('include', expectedUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateSearchDisplayed() {
|
validateSearchDisplayed() {
|
||||||
cy.getByTestId(this.blockExplorerHeader).should(
|
cy.getByTestId(this.blockExplorerHeader).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Vega Block Explorer'
|
'Vega Explorer'
|
||||||
);
|
);
|
||||||
cy.getByTestId(this.searchField).should('be.visible');
|
cy.getByTestId(this.searchField).should('be.visible');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateSearchErrorDisplayed(errorMessage) {
|
||||||
|
cy.getByTestId(this.searchError).should('have.text', errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
validateBlockDataDisplayed(headerTestId) {
|
validateBlockDataDisplayed(headerTestId) {
|
||||||
cy.getByTestId(headerTestId).then(($assetHeaders) => {
|
cy.getByTestId(headerTestId).then(($assetHeaders) => {
|
||||||
const headersAmount = parseInt($assetHeaders.length);
|
const headersAmount = parseInt($assetHeaders.length);
|
||||||
@ -68,7 +84,7 @@ export default class BasePage {
|
|||||||
});
|
});
|
||||||
|
|
||||||
cy.get('.language-json')
|
cy.get('.language-json')
|
||||||
.each(($asset, index, $list) => {
|
.each(($asset) => {
|
||||||
expect($asset).to.not.be.empty;
|
expect($asset).to.not.be.empty;
|
||||||
})
|
})
|
||||||
.then(($list) => {
|
.then(($list) => {
|
||||||
|
@ -7,7 +7,7 @@ export default class NetworkParametersPage extends BasePage {
|
|||||||
verifyNetworkParametersDisplayed() {
|
verifyNetworkParametersDisplayed() {
|
||||||
cy.getByTestId(this.networkParametersHeader).should(
|
cy.getByTestId(this.networkParametersHeader).should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'NetworkParameters'
|
'Network Parameters'
|
||||||
);
|
);
|
||||||
cy.getByTestId(this.parameters).should('not.be.empty');
|
cy.getByTestId(this.parameters).should('not.be.empty');
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,6 @@ export default class TransactionsPage extends BasePage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clickOnTopTransaction() {
|
clickOnTopTransaction() {
|
||||||
cy.getByTestId(this.transactionRow).first().find('a').click();
|
cy.getByTestId(this.transactionRow).first().find('a').first().click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||||
|
import BasePage from '../pages/base-page';
|
||||||
|
const basePage = new BasePage();
|
||||||
|
|
||||||
Given('I am on the homepage', () => {
|
Given('I am on the homepage', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
When('I search for {string}', (searchText) => {
|
||||||
|
basePage.search(searchText);
|
||||||
|
basePage.clickSearch();
|
||||||
|
});
|
||||||
|
|
||||||
|
Then('I am redirected to page containing id {string}', (expectedUrl) => {
|
||||||
|
basePage.validateUrl(expectedUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
Then('search error message {string} is displayed', (expectedErrorMsg) => {
|
||||||
|
basePage.validateSearchErrorDisplayed(expectedErrorMsg);
|
||||||
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
||||||
import NetworkPage from '../pages/network-page';
|
import NetworkPage from '../pages/network-page';
|
||||||
const networkPage = new NetworkPage();
|
const networkPage = new NetworkPage();
|
||||||
|
|
||||||
|
@ -18,17 +18,10 @@ NX_URL=$URL
|
|||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
NX_DEPLOY_URL=$DEPLOY_URL
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
||||||
|
|
||||||
# App configuration variables
|
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
|
||||||
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
|
|
||||||
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
|
||||||
|
|
||||||
# App flags
|
# App flags
|
||||||
NX_EXPLORER_ASSETS = 1
|
NX_EXPLORER_ASSETS = 1
|
||||||
NX_EXPLORER_GENESIS = 1
|
NX_EXPLORER_GENESIS = 1
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
NX_EXPLORER_GOVERNANCE = 1
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
||||||
NX_EXPLORER_PARTIES = 1
|
NX_EXPLORER_PARTIES = 1
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
NX_EXPLORER_VALIDATORS = 1
|
||||||
|
@ -1,34 +1,5 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n04.d.vega.xyz/tm"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://n04.d.vega.xyz/tm/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://n04.d.vega.xyz/tm/websocket"
|
||||||
NX_VEGA_URL = "https://n04.d.vega.xyz/query"
|
NX_VEGA_URL = "https://n04.d.vega.xyz/query"
|
||||||
|
|
||||||
# App flags
|
|
||||||
NX_EXPLORER_ASSETS = 1
|
|
||||||
NX_EXPLORER_GENESIS = 1
|
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
|
||||||
NX_EXPLORER_PARTIES = 1
|
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
|
||||||
|
14
apps/explorer/.env.local
Normal file
14
apps/explorer/.env.local
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# App configuration variables
|
||||||
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
|
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
||||||
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
|
||||||
|
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
||||||
|
|
||||||
|
# App flags
|
||||||
|
NX_EXPLORER_ASSETS = 1
|
||||||
|
NX_EXPLORER_GENESIS = 1
|
||||||
|
NX_EXPLORER_GOVERNANCE = 1
|
||||||
|
NX_EXPLORER_MARKETS = 1
|
||||||
|
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
||||||
|
NX_EXPLORER_PARTIES = 1
|
||||||
|
NX_EXPLORER_VALIDATORS = 1
|
@ -1,34 +1,5 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
|
NX_TENDERMINT_URL = "https://mainnet-observer-proxy01.ops.vega.xyz/"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://mainnet-observer-proxy01.ops.vega.xyz/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://mainnet-observer-proxy01.ops.vega.xyz/websocket"
|
||||||
NX_VEGA_URL = "https://api.token.vega.xyz/query"
|
NX_VEGA_URL = "https://api.token.vega.xyz/query"
|
||||||
|
|
||||||
# App flags
|
|
||||||
NX_EXPLORER_ASSETS = 1
|
|
||||||
NX_EXPLORER_GENESIS = 1
|
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
|
||||||
NX_EXPLORER_PARTIES = 1
|
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
|
||||||
|
@ -1,35 +1,5 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n03.s.vega.xyz/tm"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.s.vega.xyz/tm/websocket"
|
||||||
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
|
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
|
||||||
|
|
||||||
|
|
||||||
# App flags
|
|
||||||
NX_EXPLORER_ASSETS = 1
|
|
||||||
NX_EXPLORER_GENESIS = 1
|
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
|
||||||
NX_EXPLORER_PARTIES = 1
|
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
|
||||||
|
@ -1,34 +1,5 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://n03.stagnet2.vega.xyz/tm"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.stagnet2.vega.xyz/tm/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://n03.stagnet2.vega.xyz/tm/websocket"
|
||||||
NX_VEGA_URL = "https://n03.stagnet2.vega.xyz/query"
|
NX_VEGA_URL = "https://n03.stagnet2.vega.xyz/query"
|
||||||
|
|
||||||
# App flags
|
|
||||||
NX_EXPLORER_ASSETS = 1
|
|
||||||
NX_EXPLORER_GENESIS = 1
|
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
|
||||||
NX_EXPLORER_PARTIES = 1
|
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
|
||||||
|
@ -1,34 +1,5 @@
|
|||||||
# React Environment Variables
|
|
||||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
|
||||||
|
|
||||||
# Netlify Environment Variables
|
|
||||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
|
||||||
NX_VERSION=$npm_package_version
|
|
||||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
|
||||||
NX_BRANCH=$BRANCH
|
|
||||||
NX_PULL_REQUEST=$PULL_REQUEST
|
|
||||||
NX_HEAD=$HEAD
|
|
||||||
NX_COMMIT_REF=$COMMIT_REF
|
|
||||||
NX_CONTEXT=$CONTEXT
|
|
||||||
NX_REVIEW_ID=$REVIEW_ID
|
|
||||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
|
||||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
|
||||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
|
||||||
NX_URL=$URL
|
|
||||||
NX_DEPLOY_URL=$DEPLOY_URL
|
|
||||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
|
||||||
|
|
||||||
# App configuration variables
|
# App configuration variables
|
||||||
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
NX_CHAIN_EXPLORER_URL = "https://explorer.vega.trading/.netlify/functions/chain-explorer-api"
|
||||||
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
NX_TENDERMINT_URL = "https://lb.testnet.vega.xyz/tm"
|
||||||
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
|
NX_TENDERMINT_WEBSOCKET_URL = "wss://lb.testnet.vega.xyz/tm/websocket"
|
||||||
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
||||||
|
|
||||||
# App flags
|
|
||||||
NX_EXPLORER_ASSETS = 1
|
|
||||||
NX_EXPLORER_GENESIS = 1
|
|
||||||
NX_EXPLORER_GOVERNANCE = 1
|
|
||||||
NX_EXPLORER_MARKETS = 1
|
|
||||||
NX_EXPLORER_NETWORK_PARAMETERS = 1
|
|
||||||
NX_EXPLORER_PARTIES = 1
|
|
||||||
NX_EXPLORER_VALIDATORS = 1
|
|
||||||
|
@ -7,5 +7,5 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
coverageDirectory: '../../coverage/apps/explorer',
|
coverageDirectory: '../../coverage/apps/explorer',
|
||||||
setupFilesAfterEnv: ['./src/app/setupTests.ts'],
|
setupFilesAfterEnv: ['./src/app/setup-tests.ts'],
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@import './styles/colors';
|
@import './styles/colors';
|
||||||
@import './styles/fonts';
|
@import './styles/fonts';
|
||||||
@import './styles/reset';
|
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body,
|
body,
|
||||||
@ -39,18 +38,23 @@ body,
|
|||||||
padding: 20px;
|
padding: 20px;
|
||||||
grid-column-start: 1;
|
grid-column-start: 1;
|
||||||
grid-column-end: 1;
|
grid-column-end: 1;
|
||||||
grid-row-start: 1;
|
grid-row-start: 2;
|
||||||
grid-row-end: 3;
|
grid-row-end: 3;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
padding: 20px;
|
|
||||||
border-bottom: 1px solid $white;
|
border-bottom: 1px solid $white;
|
||||||
grid-column-start: 2;
|
grid-column-start: 1;
|
||||||
grid-column-end: 2;
|
grid-column-end: 3;
|
||||||
grid-row-start: 1;
|
grid-row-start: 1;
|
||||||
grid-row-end: 2;
|
grid-row-end: 2;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: $font-alpa-lyrae;
|
||||||
|
font-feature-settings: 'calt';
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import App from './App';
|
import App from './app';
|
||||||
|
|
||||||
describe('App', () => {
|
describe('App', () => {
|
||||||
it('should exist', () => {
|
it('should exist', () => {
|
||||||
|
@ -4,7 +4,6 @@ import { ApolloProvider } from '@apollo/client';
|
|||||||
|
|
||||||
import { createClient } from './lib/apollo-client';
|
import { createClient } from './lib/apollo-client';
|
||||||
import { Nav } from './components/nav';
|
import { Nav } from './components/nav';
|
||||||
import { Footer } from './components/footer';
|
|
||||||
import { Header } from './components/header';
|
import { Header } from './components/header';
|
||||||
import { Main } from './components/main';
|
import { Main } from './components/main';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@ -24,7 +23,6 @@ function App() {
|
|||||||
<Nav />
|
<Nav />
|
||||||
<Header />
|
<Header />
|
||||||
<Main />
|
<Main />
|
||||||
<Footer />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ApolloProvider>
|
</ApolloProvider>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
// import packageJson from "../../../package.json";
|
|
||||||
|
|
||||||
export const Footer = () => {
|
|
||||||
return (
|
|
||||||
<footer>
|
|
||||||
<section>
|
|
||||||
<div>Reading Vega Fairground data from </div>
|
|
||||||
<div>
|
|
||||||
{/* Version/commit hash: {packageJson.version} / */}
|
|
||||||
{process.env['NX_COMMIT_REF'] || 'dev'}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</footer>
|
|
||||||
);
|
|
||||||
};
|
|
28
apps/explorer/src/app/components/header/header.spec.tsx
Normal file
28
apps/explorer/src/app/components/header/header.spec.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import { Header } from './header';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
|
||||||
|
jest.mock('../search', () => ({
|
||||||
|
Search: () => <div data-testid="search">OrderList</div>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const renderComponent = () => (
|
||||||
|
<MemoryRouter>
|
||||||
|
<Header />
|
||||||
|
</MemoryRouter>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('Header', () => {
|
||||||
|
it('should render heading', () => {
|
||||||
|
render(renderComponent());
|
||||||
|
|
||||||
|
expect(screen.getByTestId('explorer-header')).toHaveTextContent(
|
||||||
|
'Vega Explorer'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render search', () => {
|
||||||
|
render(renderComponent());
|
||||||
|
|
||||||
|
expect(screen.getByTestId('search')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
12
apps/explorer/src/app/components/header/header.tsx
Normal file
12
apps/explorer/src/app/components/header/header.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Search } from '../search';
|
||||||
|
|
||||||
|
export const Header = () => {
|
||||||
|
return (
|
||||||
|
<header className="flex px-16 pt-16 pb-8">
|
||||||
|
<h1 className="text-h3" data-testid="explorer-header">
|
||||||
|
Vega Explorer
|
||||||
|
</h1>
|
||||||
|
<Search />
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
@ -1,9 +1 @@
|
|||||||
import Search from "../search";
|
export * from './header';
|
||||||
|
|
||||||
export const Header = () => {
|
|
||||||
return (
|
|
||||||
<header>
|
|
||||||
<Search />
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Routes } from '../../routes/router-config';
|
||||||
|
|
||||||
export const JumpToBlock = () => {
|
export const JumpToBlock = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -14,7 +15,7 @@ export const JumpToBlock = () => {
|
|||||||
const blockNumber = target.blockNumber.value;
|
const blockNumber = target.blockNumber.value;
|
||||||
|
|
||||||
if (blockNumber) {
|
if (blockNumber) {
|
||||||
navigate(`/blocks/${blockNumber}`);
|
navigate(`/${Routes.BLOCKS}/${blockNumber}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,15 +29,15 @@ export const JumpToBlock = () => {
|
|||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="block-input"
|
id="block-input"
|
||||||
type="tel"
|
type="number"
|
||||||
name={'blockNumber'}
|
name="blockNumber"
|
||||||
placeholder={'Block number'}
|
placeholder="Block number"
|
||||||
className="bg-white-25 border-white border px-8 py-4 placeholder-white-60"
|
className="bg-white-25 border-white border px-8 py-4 placeholder-white-60"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
className="border-white border px-28 py-4 cursor-pointer"
|
className="border-white border px-28 py-4 cursor-pointer"
|
||||||
type={'submit'}
|
type="submit"
|
||||||
value={'Go'}
|
value="Go"
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -14,7 +14,7 @@ export const Nav = () => {
|
|||||||
}`
|
}`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{r.name}
|
{r.text}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import React from 'react';
|
import React, { HTMLAttributes } from 'react';
|
||||||
|
|
||||||
interface RouteTitleProps {
|
interface RouteTitleProps extends HTMLAttributes<HTMLHeadingElement> {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RouteTitle = ({ children, className }: RouteTitleProps) => {
|
export const RouteTitle = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: RouteTitleProps) => {
|
||||||
const classes = classnames(
|
const classes = classnames(
|
||||||
'font-alpha',
|
'font-alpha',
|
||||||
'text-h3',
|
'text-h3',
|
||||||
@ -15,5 +19,9 @@ export const RouteTitle = ({ children, className }: RouteTitleProps) => {
|
|||||||
'mb-28',
|
'mb-28',
|
||||||
className
|
className
|
||||||
);
|
);
|
||||||
return <h1 className={classes}>{children}</h1>;
|
return (
|
||||||
|
<h1 className={classes} {...props}>
|
||||||
|
{children}
|
||||||
|
</h1>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,108 +1 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
export * from './search';
|
||||||
import React from 'react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
import debounce from 'lodash.debounce';
|
|
||||||
import { Guess, GuessVariables } from '@vegaprotocol/graphql';
|
|
||||||
|
|
||||||
const TX_LENGTH = 64;
|
|
||||||
|
|
||||||
enum PossibleIdTypes {
|
|
||||||
Block = 'Block',
|
|
||||||
Tx = 'Tx',
|
|
||||||
Party = 'Party',
|
|
||||||
Market = 'Market',
|
|
||||||
Unknown = 'Unknown',
|
|
||||||
}
|
|
||||||
|
|
||||||
const GUESS_QUERY = gql`
|
|
||||||
query Guess($guess: ID!) {
|
|
||||||
party(id: $guess) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
market(id: $guess) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const usePossibleType = (search: string) => {
|
|
||||||
const [possibleType, setPossibleType] = useState<PossibleIdTypes>();
|
|
||||||
const { data, loading, error } = useQuery<Guess, GuessVariables>(
|
|
||||||
GUESS_QUERY,
|
|
||||||
{
|
|
||||||
variables: {
|
|
||||||
guess: search,
|
|
||||||
},
|
|
||||||
skip: !search,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (!isNaN(Number(search))) {
|
|
||||||
setPossibleType(PossibleIdTypes.Block);
|
|
||||||
} else if (data?.party) {
|
|
||||||
setPossibleType(PossibleIdTypes.Party);
|
|
||||||
} else if (data?.market) {
|
|
||||||
setPossibleType(PossibleIdTypes.Market);
|
|
||||||
} else if (search.replace('0x', '').length === TX_LENGTH) {
|
|
||||||
setPossibleType(PossibleIdTypes.Tx);
|
|
||||||
} else {
|
|
||||||
setPossibleType(PossibleIdTypes.Unknown);
|
|
||||||
}
|
|
||||||
}, [data?.market, data?.party, search, setPossibleType]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
possibleType,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const useGuess = () => {
|
|
||||||
const [search, setSearch] = useState<string>('');
|
|
||||||
const [debouncedSearch, setDebouncedSearch] = useState<string>('');
|
|
||||||
const { loading, error, possibleType } = usePossibleType(debouncedSearch);
|
|
||||||
const debouncedSearchSet = React.useMemo(
|
|
||||||
() => debounce(setDebouncedSearch, 1000),
|
|
||||||
[setDebouncedSearch]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onChange = React.useCallback(
|
|
||||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
const search = event.target.value;
|
|
||||||
setSearch(search);
|
|
||||||
debouncedSearchSet(search);
|
|
||||||
},
|
|
||||||
[debouncedSearchSet]
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
onChange,
|
|
||||||
search,
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
possibleType,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const Search = () => {
|
|
||||||
const { search, onChange } = useGuess();
|
|
||||||
return (
|
|
||||||
<section>
|
|
||||||
<h1 data-testid="explorer-header">Vega Block Explorer</h1>
|
|
||||||
<fieldset>
|
|
||||||
<label htmlFor="search">Search: </label>
|
|
||||||
<input
|
|
||||||
data-testid="search-field"
|
|
||||||
name="search"
|
|
||||||
value={search}
|
|
||||||
onChange={(e) => onChange(e)}
|
|
||||||
/>
|
|
||||||
</fieldset>
|
|
||||||
</section>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Search;
|
|
||||||
|
140
apps/explorer/src/app/components/search/search.spec.tsx
Normal file
140
apps/explorer/src/app/components/search/search.spec.tsx
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
||||||
|
import { Search } from './search';
|
||||||
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { Routes } from '../../routes/router-config';
|
||||||
|
|
||||||
|
const mockedNavigate = jest.fn();
|
||||||
|
|
||||||
|
jest.mock('react-router-dom', () => ({
|
||||||
|
...jest.requireActual('react-router-dom'),
|
||||||
|
useNavigate: () => mockedNavigate,
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockedNavigate.mockClear();
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderComponent = () => (
|
||||||
|
<MemoryRouter>
|
||||||
|
<Search />
|
||||||
|
</MemoryRouter>
|
||||||
|
);
|
||||||
|
|
||||||
|
const getInputs = () => ({
|
||||||
|
input: screen.getByTestId('search'),
|
||||||
|
button: screen.getByTestId('search-button'),
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Search', () => {
|
||||||
|
it('should render search input and button', () => {
|
||||||
|
render(renderComponent());
|
||||||
|
expect(screen.getByTestId('search')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId('search-button')).toHaveTextContent('Search');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error if input is not known', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, { target: { value: 'asd' } });
|
||||||
|
fireEvent.click(button);
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('search-error')).toHaveTextContent(
|
||||||
|
"Something doesn't look right"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should render error if no input is given', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button } = getInputs();
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('search-error')).toHaveTextContent(
|
||||||
|
'Search required'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error if transaction is not hex', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, {
|
||||||
|
target: {
|
||||||
|
value:
|
||||||
|
'0x123456789012345678901234567890123456789012345678901234567890123Q',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('search-error')).toHaveTextContent(
|
||||||
|
'Transaction is not hexadecimal'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render error if transaction is not hex and does not have leading 0x', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, {
|
||||||
|
target: {
|
||||||
|
value:
|
||||||
|
'123456789012345678901234567890123456789012345678901234567890123Q',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('search-error')).toHaveTextContent(
|
||||||
|
'Transaction is not hexadecimal'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to transactions page', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, {
|
||||||
|
target: {
|
||||||
|
value:
|
||||||
|
'0x1234567890123456789012345678901234567890123456789012345678901234',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockedNavigate).toBeCalledWith(
|
||||||
|
`${Routes.TX}/0x1234567890123456789012345678901234567890123456789012345678901234`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to transactions page without proceeding 0x', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, {
|
||||||
|
target: {
|
||||||
|
value:
|
||||||
|
'1234567890123456789012345678901234567890123456789012345678901234',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockedNavigate).toBeCalledWith(
|
||||||
|
`${Routes.TX}/0x1234567890123456789012345678901234567890123456789012345678901234`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should redirect to blocks page if passed a number', async () => {
|
||||||
|
render(renderComponent());
|
||||||
|
const { button, input } = getInputs();
|
||||||
|
fireEvent.change(input, {
|
||||||
|
target: {
|
||||||
|
value: '123',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockedNavigate).toBeCalledWith(`${Routes.BLOCKS}/123`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
84
apps/explorer/src/app/components/search/search.tsx
Normal file
84
apps/explorer/src/app/components/search/search.tsx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { FormGroup, Input, InputError, Button } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import React from 'react';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Routes } from '../../routes/router-config';
|
||||||
|
|
||||||
|
const TX_LENGTH = 64;
|
||||||
|
|
||||||
|
interface FormFields {
|
||||||
|
search: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isPrependedTransaction = (search: string) =>
|
||||||
|
search.startsWith('0x') && search.length === 2 + TX_LENGTH;
|
||||||
|
|
||||||
|
const isTransaction = (search: string) =>
|
||||||
|
!search.startsWith('0x') && search.length === TX_LENGTH;
|
||||||
|
|
||||||
|
const isBlock = (search: string) => !Number.isNaN(Number(search));
|
||||||
|
|
||||||
|
export const Search = () => {
|
||||||
|
const { register, handleSubmit } = useForm<FormFields>();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [error, setError] = React.useState<Error | null>(null);
|
||||||
|
const onSubmit = React.useCallback(
|
||||||
|
(fields: FormFields) => {
|
||||||
|
setError(null);
|
||||||
|
|
||||||
|
const search = fields.search;
|
||||||
|
if (!search) {
|
||||||
|
setError(new Error('Search required'));
|
||||||
|
} else if (isPrependedTransaction(search)) {
|
||||||
|
if (Number.isNaN(Number(search))) {
|
||||||
|
setError(new Error('Transaction is not hexadecimal'));
|
||||||
|
} else {
|
||||||
|
navigate(`${Routes.TX}/${search}`);
|
||||||
|
}
|
||||||
|
} else if (isTransaction(search)) {
|
||||||
|
if (Number.isNaN(Number(`0x${search}`))) {
|
||||||
|
setError(new Error('Transaction is not hexadecimal'));
|
||||||
|
} else {
|
||||||
|
navigate(`${Routes.TX}/0x${search}`);
|
||||||
|
}
|
||||||
|
} else if (isBlock(search)) {
|
||||||
|
navigate(`${Routes.BLOCKS}/${Number(search)}`);
|
||||||
|
} else {
|
||||||
|
setError(new Error("Something doesn't look right"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[navigate]
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit(onSubmit)}
|
||||||
|
className="flex-1 flex ml-16 justify-end"
|
||||||
|
>
|
||||||
|
<FormGroup className="w-2/3 mb-0">
|
||||||
|
<Input
|
||||||
|
{...register('search')}
|
||||||
|
id="search"
|
||||||
|
data-testid="search"
|
||||||
|
hasError={Boolean(error?.message)}
|
||||||
|
type="text"
|
||||||
|
autoFocus={true}
|
||||||
|
placeholder="Enter block number or transaction hash"
|
||||||
|
/>
|
||||||
|
{error?.message ? (
|
||||||
|
<InputError
|
||||||
|
data-testid="search-error"
|
||||||
|
intent="danger"
|
||||||
|
className="flex-1 w-full"
|
||||||
|
>
|
||||||
|
{error.message}
|
||||||
|
</InputError>
|
||||||
|
) : (
|
||||||
|
<div className="h-28"></div>
|
||||||
|
)}
|
||||||
|
</FormGroup>
|
||||||
|
<Button type="submit" variant="secondary" data-testid="search-button">
|
||||||
|
Search
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
27
apps/explorer/src/app/components/sub-heading/index.tsx
Normal file
27
apps/explorer/src/app/components/sub-heading/index.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import classnames from 'classnames';
|
||||||
|
import { HTMLAttributes } from 'react';
|
||||||
|
|
||||||
|
interface SubHeadingProps extends HTMLAttributes<HTMLHeadingElement> {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SubHeading = ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: SubHeadingProps) => {
|
||||||
|
const classes = classnames(
|
||||||
|
'font-alpha',
|
||||||
|
'text-h4',
|
||||||
|
'uppercase',
|
||||||
|
'mt-12',
|
||||||
|
'mb-12',
|
||||||
|
className
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<h2 {...props} className={classes}>
|
||||||
|
{children}
|
||||||
|
</h2>
|
||||||
|
);
|
||||||
|
};
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { TendermintBlockchainResponse } from '../../../routes/blocks/tendermint-blockchain-response';
|
import { TendermintBlockchainResponse } from '../../routes/blocks/tendermint-blockchain-response';
|
||||||
import { BlockData } from '../../blocks';
|
import { BlockData } from '../blocks';
|
||||||
import { TxsPerBlock } from '../txs-per-block';
|
import { TxsPerBlock } from './txs-per-block';
|
||||||
|
|
||||||
interface TxsProps {
|
interface TxsProps {
|
||||||
data: TendermintBlockchainResponse | undefined;
|
data: TendermintBlockchainResponse | undefined;
|
@ -1,4 +1,3 @@
|
|||||||
export { TxDetails } from './id/tx-details';
|
export { TxList } from './tx-list';
|
||||||
export { TxContent } from './id/tx-content';
|
export { BlockTxsData } from './block-txs-data';
|
||||||
export { TxList } from './pending/tx-list';
|
export { TxOrderType } from './tx-order-type';
|
||||||
export { BlockTxsData } from './home/block-txs-data';
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { TendermintUnconfirmedTransactionsResponse } from '../../../routes/txs/tendermint-unconfirmed-transactions-response.d';
|
import { TendermintUnconfirmedTransactionsResponse } from '../../routes/txs/tendermint-unconfirmed-transactions-response.d';
|
||||||
|
|
||||||
interface TxsProps {
|
interface TxsProps {
|
||||||
data: TendermintUnconfirmedTransactionsResponse | undefined;
|
data: TendermintUnconfirmedTransactionsResponse | undefined;
|
@ -1,11 +1,11 @@
|
|||||||
import useFetch from '../../../hooks/use-fetch';
|
import useFetch from '../../hooks/use-fetch';
|
||||||
import { ChainExplorerTxResponse } from '../../../routes/types/chain-explorer-response';
|
import { ChainExplorerTxResponse } from '../../routes/types/chain-explorer-response';
|
||||||
import { Routes } from '../../../routes/router-config';
|
import { Routes } from '../../routes/router-config';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../config';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { RenderFetched } from '../../render-fetched';
|
import { RenderFetched } from '../render-fetched';
|
||||||
import { TruncateInline } from '../../truncate/truncate';
|
import { TruncateInline } from '../truncate/truncate';
|
||||||
import { TxOrderType } from '../tx-order-type';
|
import { TxOrderType } from './tx-order-type';
|
||||||
|
|
||||||
interface TxsPerBlockProps {
|
interface TxsPerBlockProps {
|
||||||
blockHeight: string | undefined;
|
blockHeight: string | undefined;
|
||||||
@ -31,20 +31,20 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderFetched error={error} loading={loading} className="text-body-large">
|
<RenderFetched error={error} loading={loading} className="text-body-large">
|
||||||
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
{decodedBlockData && decodedBlockData.length ? (
|
||||||
<table className="w-full">
|
<div className="overflow-x-auto whitespace-nowrap mb-28">
|
||||||
<thead>
|
<table className="w-full">
|
||||||
<tr className="font-mono">
|
<thead>
|
||||||
<td>Transaction</td>
|
<tr className="font-mono">
|
||||||
<td>From</td>
|
<td>Transaction</td>
|
||||||
<td>Type</td>
|
<td>From</td>
|
||||||
</tr>
|
<td>Type</td>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{decodedBlockData &&
|
<tbody>
|
||||||
decodedBlockData.map(({ TxHash, PubKey, Type }) => {
|
{decodedBlockData.map(({ TxHash, PubKey, Type }) => {
|
||||||
return (
|
return (
|
||||||
<tr data-testid="transaction-row" key={TxHash}>
|
<tr key={TxHash} data-testid="transaction-row">
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/${Routes.TX}/${TxHash}`}>
|
<Link to={`/${Routes.TX}/${TxHash}`}>
|
||||||
<TruncateInline
|
<TruncateInline
|
||||||
@ -56,12 +56,14 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<TruncateInline
|
<Link to={`/${Routes.PARTIES}/${PubKey}`}>
|
||||||
text={PubKey}
|
<TruncateInline
|
||||||
startChars={truncateLength}
|
text={PubKey}
|
||||||
endChars={truncateLength}
|
startChars={truncateLength}
|
||||||
className="font-mono"
|
endChars={truncateLength}
|
||||||
/>
|
className="text-vega-yellow font-mono"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<TxOrderType className="mb-4" orderType={Type} />
|
<TxOrderType className="mb-4" orderType={Type} />
|
||||||
@ -69,9 +71,14 @@ export const TxsPerBlock = ({ blockHeight }: TxsPerBlockProps) => {
|
|||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="font-mono mb-28">
|
||||||
|
No transactions in block {blockHeight}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</RenderFetched>
|
</RenderFetched>
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -57,7 +57,7 @@ function useFetch<T = unknown>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = (await response.json()) as T;
|
const data = (await response.json()) as T;
|
||||||
if ('error' in data) {
|
if (data && 'error' in data) {
|
||||||
// @ts-ignore - data.error
|
// @ts-ignore - data.error
|
||||||
throw new Error(data.error);
|
throw new Error(data.error);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
import { SubHeading } from '../../components/sub-heading';
|
||||||
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
import { AssetsQuery } from '@vegaprotocol/graphql';
|
import { AssetsQuery } from '@vegaprotocol/graphql';
|
||||||
|
|
||||||
@ -35,12 +37,12 @@ const Assets = () => {
|
|||||||
if (!data || !data.assets) return null;
|
if (!data || !data.assets) return null;
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Assets</h1>
|
<RouteTitle data-testid="assets-header">Assets</RouteTitle>
|
||||||
{data?.assets.map((a) => (
|
{data?.assets.map((a) => (
|
||||||
<React.Fragment key={a.id}>
|
<React.Fragment key={a.id}>
|
||||||
<h2 data-testid="asset-header">
|
<SubHeading data-testid="asset-header">
|
||||||
{a.name} ({a.symbol})
|
{a.name} ({a.symbol})
|
||||||
</h2>
|
</SubHeading>
|
||||||
<SyntaxHighlighter data={a} />
|
<SyntaxHighlighter data={a} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
@ -4,7 +4,6 @@ import { DATA_SOURCES } from '../../../config';
|
|||||||
import useFetch from '../../../hooks/use-fetch';
|
import useFetch from '../../../hooks/use-fetch';
|
||||||
import { TendermintBlocksResponse } from '../tendermint-blocks-response';
|
import { TendermintBlocksResponse } from '../tendermint-blocks-response';
|
||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
|
|
||||||
import { SecondsAgo } from '../../../components/seconds-ago';
|
import { SecondsAgo } from '../../../components/seconds-ago';
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
@ -12,6 +11,7 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableCell,
|
TableCell,
|
||||||
} from '../../../components/table';
|
} from '../../../components/table';
|
||||||
|
import { TxsPerBlock } from '../../../components/txs/txs-per-block';
|
||||||
|
|
||||||
const Block = () => {
|
const Block = () => {
|
||||||
const { block } = useParams<{ block: string }>();
|
const { block } = useParams<{ block: string }>();
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
import { DATA_SOURCES } from '../../config';
|
import { DATA_SOURCES } from '../../config';
|
||||||
import useFetch from '../../hooks/use-fetch';
|
import useFetch from '../../hooks/use-fetch';
|
||||||
@ -12,7 +13,7 @@ const Genesis = () => {
|
|||||||
if (!genesis?.result.genesis) return null;
|
if (!genesis?.result.genesis) return null;
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1 data-testid="genesis-header">Genesis</h1>
|
<RouteTitle data-testid="genesis-header">Genesis</RouteTitle>
|
||||||
<SyntaxHighlighter data={genesis?.result.genesis} />
|
<SyntaxHighlighter data={genesis?.result.genesis} />
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
import { SubHeading } from '../../components/sub-heading';
|
||||||
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
import {
|
import {
|
||||||
ProposalsQuery,
|
ProposalsQuery,
|
||||||
@ -100,14 +102,13 @@ const PROPOSAL_QUERY = gql`
|
|||||||
const Governance = () => {
|
const Governance = () => {
|
||||||
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY);
|
const { data } = useQuery<ProposalsQuery>(PROPOSAL_QUERY);
|
||||||
|
|
||||||
if (!data || !data.proposals) return null;
|
if (!data) return null;
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Governance</h1>
|
<RouteTitle data-testid="governance-header">Governance</RouteTitle>
|
||||||
{data.proposals.map((p) => (
|
{data.proposals?.map((p) => (
|
||||||
<React.Fragment key={p.id}>
|
<React.Fragment key={p.id}>
|
||||||
{/* TODO get proposal name generator from console */}
|
<SubHeading>{getProposalName(p.terms.change)}</SubHeading>
|
||||||
<h2>{getProposalName(p.terms.change)}</h2>
|
|
||||||
<SyntaxHighlighter data={p} />
|
<SyntaxHighlighter data={p} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
|
import { StatsManager } from '@vegaprotocol/mainnet-stats-manager';
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Home page content</h1>
|
<StatsManager className="mt-12 grid grid-cols-1 lg:grid-cols-2 lg:gap-16" />
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,8 @@ import { MarketsQuery } from '@vegaprotocol/graphql';
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
import { SubHeading } from '../../components/sub-heading';
|
||||||
|
|
||||||
const MARKETS_QUERY = gql`
|
const MARKETS_QUERY = gql`
|
||||||
query MarketsQuery {
|
query MarketsQuery {
|
||||||
@ -148,14 +150,17 @@ const Markets = () => {
|
|||||||
|
|
||||||
if (!data || !data.markets) return null;
|
if (!data || !data.markets) return null;
|
||||||
return (
|
return (
|
||||||
<section className="px-8 py-12">
|
<section>
|
||||||
<h1>Markets</h1>
|
<RouteTitle data-testid="markets-heading">Markets</RouteTitle>
|
||||||
{data.markets.map((m) => (
|
|
||||||
<React.Fragment key={m.id}>
|
{data
|
||||||
<h2 data-testid="markets-header">{m.name}</h2>
|
? data.markets.map((m) => (
|
||||||
<SyntaxHighlighter data={m} />
|
<React.Fragment key={m.id}>
|
||||||
</React.Fragment>
|
<SubHeading data-testid="markets-header">{m.name}</SubHeading>
|
||||||
))}
|
<SyntaxHighlighter data={m} />
|
||||||
|
</React.Fragment>
|
||||||
|
))
|
||||||
|
: null}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
import { NetworkParametersQuery } from '@vegaprotocol/graphql';
|
import { NetworkParametersQuery } from '@vegaprotocol/graphql';
|
||||||
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
|
|
||||||
export const NETWORK_PARAMETERS_QUERY = gql`
|
export const NETWORK_PARAMETERS_QUERY = gql`
|
||||||
query NetworkParametersQuery {
|
query NetworkParametersQuery {
|
||||||
@ -14,8 +16,10 @@ const NetworkParameters = () => {
|
|||||||
const { data } = useQuery<NetworkParametersQuery>(NETWORK_PARAMETERS_QUERY);
|
const { data } = useQuery<NetworkParametersQuery>(NETWORK_PARAMETERS_QUERY);
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1 data-testid="network-param-header">NetworkParameters</h1>
|
<RouteTitle data-testid="network-param-header">
|
||||||
<pre data-testid="parameters">{JSON.stringify(data, null, ' ')}</pre>
|
Network Parameters
|
||||||
|
</RouteTitle>
|
||||||
|
{data ? <SyntaxHighlighter data={data} /> : null}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,57 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
|
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Routes } from '../../router-config';
|
||||||
|
|
||||||
|
export const JumpToParty = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleSubmit = React.useCallback(
|
||||||
|
() => (e: React.SyntheticEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const target = e.target as typeof e.target & {
|
||||||
|
partyId: { value: number };
|
||||||
|
};
|
||||||
|
|
||||||
|
const partyId = target.partyId.value;
|
||||||
|
|
||||||
|
if (partyId) {
|
||||||
|
navigate(`/${Routes.PARTIES}/${partyId}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[navigate]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<label
|
||||||
|
htmlFor="block-input"
|
||||||
|
className="block uppercase text-h5 font-bold"
|
||||||
|
>
|
||||||
|
Go to party
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="block-input"
|
||||||
|
name="partyId"
|
||||||
|
placeholder="Party id"
|
||||||
|
className="bg-white-25 border-white border px-8 py-4 placeholder-white-60"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
className="border-white border px-28 py-4 cursor-pointer"
|
||||||
|
type="submit"
|
||||||
|
value="Go"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Parties = () => {
|
const Parties = () => {
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Parties</h1>
|
<RouteTitle data-testid="parties-header">Parties</RouteTitle>
|
||||||
<h2>
|
<JumpToParty />
|
||||||
Not sure what to do with this page? Could show all parties but would
|
|
||||||
eventually need to be rewritten. But that's not very useful either
|
|
||||||
</h2>
|
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,9 @@ import { useQuery } from '@apollo/client';
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
|
import { SubHeading } from '../../../components/sub-heading';
|
||||||
|
import { SyntaxHighlighter } from '../../../components/syntax-highlighter';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import useFetch from '../../../hooks/use-fetch';
|
import useFetch from '../../../hooks/use-fetch';
|
||||||
import { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
|
import { TendermintSearchTransactionResponse } from '../tendermint-transaction-response';
|
||||||
@ -47,10 +50,13 @@ const PARTY_ASSETS_QUERY = gql`
|
|||||||
|
|
||||||
const Party = () => {
|
const Party = () => {
|
||||||
const { party } = useParams<{ party: string }>();
|
const { party } = useParams<{ party: string }>();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
state: { data: partyData },
|
state: { data: partyData },
|
||||||
} = useFetch<TendermintSearchTransactionResponse>(
|
} = useFetch<TendermintSearchTransactionResponse>(
|
||||||
`${DATA_SOURCES.tendermintWebsocketUrl}/tx_search?query="tx.submitter=%27${party}%27"`
|
`${
|
||||||
|
DATA_SOURCES.tendermintUrl
|
||||||
|
}/tx_search?query="tx.submitter='${party?.replace('0x', '')}'"`
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data } = useQuery<PartyAssetsQuery, PartyAssetsQueryVariables>(
|
const { data } = useQuery<PartyAssetsQuery, PartyAssetsQueryVariables>(
|
||||||
@ -65,11 +71,20 @@ const Party = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Party</h1>
|
<RouteTitle data-testid="parties-header">Party</RouteTitle>
|
||||||
<h2>Tendermint Data</h2>
|
{data ? (
|
||||||
<pre>{JSON.stringify(partyData, null, ' ')}</pre>
|
<>
|
||||||
<h2>Asset data</h2>
|
<SubHeading>Asset data</SubHeading>
|
||||||
<pre>{JSON.stringify(data, null, ' ')}</pre>
|
<SyntaxHighlighter data={data} />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{partyData ? (
|
||||||
|
<>
|
||||||
|
<SubHeading>Tendermint Data</SubHeading>
|
||||||
|
<SyntaxHighlighter data={partyData} />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ import { DATA_SOURCES } from '../../config';
|
|||||||
import useFetch from '../../hooks/use-fetch';
|
import useFetch from '../../hooks/use-fetch';
|
||||||
import { TendermintUnconfirmedTransactionsResponse } from '../txs/tendermint-unconfirmed-transactions-response.d';
|
import { TendermintUnconfirmedTransactionsResponse } from '../txs/tendermint-unconfirmed-transactions-response.d';
|
||||||
import { TxList } from '../../components/txs';
|
import { TxList } from '../../components/txs';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
|
||||||
const PendingTxs = () => {
|
const PendingTxs = () => {
|
||||||
const {
|
const {
|
||||||
@ -13,7 +14,9 @@ const PendingTxs = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Unconfirmed transactions</h1>
|
<RouteTitle data-testid="unconfirmed-transactions-header">
|
||||||
|
Unconfirmed transactions
|
||||||
|
</RouteTitle>
|
||||||
https://lb.testnet.vega.xyz/tm/unconfirmed_txs
|
https://lb.testnet.vega.xyz/tm/unconfirmed_txs
|
||||||
<br />
|
<br />
|
||||||
<div>Number: {unconfirmedTransactions?.result?.n_txs || 0}</div>
|
<div>Number: {unconfirmedTransactions?.result?.n_txs || 0}</div>
|
||||||
|
@ -34,6 +34,7 @@ const partiesRoutes = flags.parties
|
|||||||
{
|
{
|
||||||
path: Routes.PARTIES,
|
path: Routes.PARTIES,
|
||||||
name: 'Parties',
|
name: 'Parties',
|
||||||
|
text: 'Parties',
|
||||||
element: <Party />,
|
element: <Party />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -53,6 +54,7 @@ const assetsRoutes = flags.assets
|
|||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
path: Routes.ASSETS,
|
path: Routes.ASSETS,
|
||||||
|
text: 'Assets',
|
||||||
name: 'Assets',
|
name: 'Assets',
|
||||||
element: <Assets />,
|
element: <Assets />,
|
||||||
},
|
},
|
||||||
@ -64,6 +66,7 @@ const genesisRoutes = flags.genesis
|
|||||||
{
|
{
|
||||||
path: Routes.GENESIS,
|
path: Routes.GENESIS,
|
||||||
name: 'Genesis',
|
name: 'Genesis',
|
||||||
|
text: 'Genesis Parameters',
|
||||||
element: <Genesis />,
|
element: <Genesis />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -74,6 +77,7 @@ const governanceRoutes = flags.governance
|
|||||||
{
|
{
|
||||||
path: Routes.GOVERNANCE,
|
path: Routes.GOVERNANCE,
|
||||||
name: 'Governance',
|
name: 'Governance',
|
||||||
|
text: 'Proposals',
|
||||||
element: <Governance />,
|
element: <Governance />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -84,6 +88,7 @@ const marketsRoutes = flags.markets
|
|||||||
{
|
{
|
||||||
path: Routes.MARKETS,
|
path: Routes.MARKETS,
|
||||||
name: 'Markets',
|
name: 'Markets',
|
||||||
|
text: 'Markets',
|
||||||
element: <Markets />,
|
element: <Markets />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -94,6 +99,7 @@ const networkParametersRoutes = flags.networkParameters
|
|||||||
{
|
{
|
||||||
path: Routes.NETWORK_PARAMETERS,
|
path: Routes.NETWORK_PARAMETERS,
|
||||||
name: 'NetworkParameters',
|
name: 'NetworkParameters',
|
||||||
|
text: 'Network Parameters',
|
||||||
element: <NetworkParameters />,
|
element: <NetworkParameters />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -103,6 +109,7 @@ const validators = flags.validators
|
|||||||
{
|
{
|
||||||
path: Routes.VALIDATORS,
|
path: Routes.VALIDATORS,
|
||||||
name: 'Validators',
|
name: 'Validators',
|
||||||
|
text: 'Validators',
|
||||||
element: <Validators />,
|
element: <Validators />,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -112,12 +119,14 @@ const routerConfig = [
|
|||||||
{
|
{
|
||||||
path: Routes.HOME,
|
path: Routes.HOME,
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
|
text: 'Home',
|
||||||
element: <Home />,
|
element: <Home />,
|
||||||
index: true,
|
index: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: Routes.TX,
|
path: Routes.TX,
|
||||||
name: 'Txs',
|
name: 'Txs',
|
||||||
|
text: 'Transactions',
|
||||||
element: <Txs />,
|
element: <Txs />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -137,6 +146,7 @@ const routerConfig = [
|
|||||||
{
|
{
|
||||||
path: Routes.BLOCKS,
|
path: Routes.BLOCKS,
|
||||||
name: 'Blocks',
|
name: 'Blocks',
|
||||||
|
text: 'Blocks',
|
||||||
element: <BlockPage />,
|
element: <BlockPage />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -4,9 +4,10 @@ import useFetch from '../../../hooks/use-fetch';
|
|||||||
import { TendermintTransactionResponse } from '../tendermint-transaction-response.d';
|
import { TendermintTransactionResponse } from '../tendermint-transaction-response.d';
|
||||||
import { ChainExplorerTxResponse } from '../../types/chain-explorer-response';
|
import { ChainExplorerTxResponse } from '../../types/chain-explorer-response';
|
||||||
import { DATA_SOURCES } from '../../../config';
|
import { DATA_SOURCES } from '../../../config';
|
||||||
import { TxContent, TxDetails } from '../../../components/txs';
|
|
||||||
import { RouteTitle } from '../../../components/route-title';
|
import { RouteTitle } from '../../../components/route-title';
|
||||||
import { RenderFetched } from '../../../components/render-fetched';
|
import { RenderFetched } from '../../../components/render-fetched';
|
||||||
|
import { TxContent } from './tx-content';
|
||||||
|
import { TxDetails } from './tx-details';
|
||||||
|
|
||||||
const Tx = () => {
|
const Tx = () => {
|
||||||
const { txHash } = useParams<{ txHash: string }>();
|
const { txHash } = useParams<{ txHash: string }>();
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
|
import { StatusMessage } from '../../../components/status-message';
|
||||||
|
import { SyntaxHighlighter } from '../../../components/syntax-highlighter';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '../../../components/table';
|
||||||
|
import { TxOrderType } from '../../../components/txs';
|
||||||
import { ChainExplorerTxResponse } from '../../../routes/types/chain-explorer-response';
|
import { ChainExplorerTxResponse } from '../../../routes/types/chain-explorer-response';
|
||||||
import { SyntaxHighlighter } from '../../syntax-highlighter';
|
|
||||||
import { Table, TableRow, TableHeader, TableCell } from '../../table';
|
|
||||||
import { TxOrderType } from '../tx-order-type';
|
|
||||||
import { StatusMessage } from '../../status-message';
|
|
||||||
|
|
||||||
interface TxContentProps {
|
interface TxContentProps {
|
||||||
data: ChainExplorerTxResponse | undefined;
|
data: ChainExplorerTxResponse | undefined;
|
@ -1,8 +1,13 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableCell,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from '../../../components/table';
|
||||||
|
import { TruncateInline } from '../../../components/truncate/truncate';
|
||||||
import { Routes } from '../../../routes/router-config';
|
import { Routes } from '../../../routes/router-config';
|
||||||
import { Result } from '../../../routes/txs/tendermint-transaction-response.d';
|
import { Result } from '../../../routes/txs/tendermint-transaction-response.d';
|
||||||
import { Table, TableRow, TableCell, TableHeader } from '../../table';
|
|
||||||
import { TruncateInline } from '../../truncate/truncate';
|
|
||||||
|
|
||||||
interface TxDetailsProps {
|
interface TxDetailsProps {
|
||||||
txData: Result | undefined;
|
txData: Result | undefined;
|
@ -1,5 +1,8 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { RouteTitle } from '../../components/route-title';
|
||||||
|
import { SubHeading } from '../../components/sub-heading';
|
||||||
|
import { SyntaxHighlighter } from '../../components/syntax-highlighter';
|
||||||
import { DATA_SOURCES } from '../../config';
|
import { DATA_SOURCES } from '../../config';
|
||||||
import useFetch from '../../hooks/use-fetch';
|
import useFetch from '../../hooks/use-fetch';
|
||||||
import { TendermintValidatorsResponse } from './tendermint-validator-response';
|
import { TendermintValidatorsResponse } from './tendermint-validator-response';
|
||||||
@ -41,13 +44,21 @@ const Validators = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
<h1>Validators</h1>
|
<RouteTitle data-testid="validators-header">Validators</RouteTitle>
|
||||||
<h2 data-testid="tendermint-header">Tendermint data</h2>
|
{data ? (
|
||||||
<pre data-testid="tendermint-data">
|
<>
|
||||||
{JSON.stringify(validators, null, ' ')}
|
<SubHeading data-testid="vega-header">Vega data</SubHeading>
|
||||||
</pre>
|
<SyntaxHighlighter data-testid="vega-data" data={data} />
|
||||||
<h2 data-testid="vega-header">Vega data</h2>
|
</>
|
||||||
<pre data-testid="vega-data">{JSON.stringify(data, null, ' ')}</pre>
|
) : null}
|
||||||
|
{validators ? (
|
||||||
|
<>
|
||||||
|
<SubHeading data-testid="tendermint-header">
|
||||||
|
Tendermint data
|
||||||
|
</SubHeading>
|
||||||
|
<SyntaxHighlighter data-testid="tendermint-data" data={validators} />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
fieldset {
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
@ -3,7 +3,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "../../dist/out-tsc",
|
"outDir": "../../dist/out-tsc",
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"types": ["jest", "node"]
|
"types": ["jest", "node", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"**/*.test.ts",
|
"**/*.test.ts",
|
||||||
|
10
apps/stats-mainnet-e2e/.eslintrc.json
Normal file
10
apps/stats-mainnet-e2e/.eslintrc.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
14
apps/stats-mainnet-e2e/cypress.json
Normal file
14
apps/stats-mainnet-e2e/cypress.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"baseUrl": "http://localhost:3010",
|
||||||
|
"projectId": "et4snf",
|
||||||
|
"fileServerFolder": ".",
|
||||||
|
"fixturesFolder": "./src/fixtures",
|
||||||
|
"integrationFolder": "./src/integration",
|
||||||
|
"modifyObstructiveCode": false,
|
||||||
|
"supportFile": "./src/support/index.ts",
|
||||||
|
"pluginsFile": false,
|
||||||
|
"video": true,
|
||||||
|
"videosFolder": "../../dist/cypress/apps/stats-mainnet-e2e/videos",
|
||||||
|
"screenshotsFolder": "../../dist/cypress/apps/stats-mainnet-e2e/screenshots",
|
||||||
|
"chromeWebSecurity": false
|
||||||
|
}
|
28
apps/stats-mainnet-e2e/project.json
Normal file
28
apps/stats-mainnet-e2e/project.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"root": "apps/stats-mainnet-e2e",
|
||||||
|
"sourceRoot": "apps/stats-mainnet-e2e/src",
|
||||||
|
"projectType": "application",
|
||||||
|
"targets": {
|
||||||
|
"e2e": {
|
||||||
|
"executor": "@nrwl/cypress:cypress",
|
||||||
|
"options": {
|
||||||
|
"cypressConfig": "apps/stats-mainnet-e2e/cypress.json",
|
||||||
|
"devServerTarget": "stats-mainnet:serve"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"devServerTarget": "stats-mainnet:serve:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nrwl/linter:eslint",
|
||||||
|
"outputs": ["{options.outputFile}"],
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["apps/stats-mainnet-e2e/**/*.{js,ts}"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [],
|
||||||
|
"implicitDependencies": ["stats-mainnet"]
|
||||||
|
}
|
4
apps/stats-mainnet-e2e/src/fixtures/example.json
Normal file
4
apps/stats-mainnet-e2e/src/fixtures/example.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "Using fixtures to represent data",
|
||||||
|
"email": "hello@cypress.io"
|
||||||
|
}
|
7
apps/stats-mainnet-e2e/src/integration/app.spec.ts
Normal file
7
apps/stats-mainnet-e2e/src/integration/app.spec.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
describe('stats-mainnet', () => {
|
||||||
|
beforeEach(() => cy.visit('/'));
|
||||||
|
|
||||||
|
it('should display header', () => {
|
||||||
|
cy.get('h3').should('have.text', '/ Mainnet');
|
||||||
|
});
|
||||||
|
});
|
33
apps/stats-mainnet-e2e/src/support/commands.ts
Normal file
33
apps/stats-mainnet-e2e/src/support/commands.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||||
|
declare namespace Cypress {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
interface Chainable<Subject> {
|
||||||
|
login(email: string, password: string): void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
Cypress.Commands.add('login', (email, password) => {
|
||||||
|
console.log('Custom command example: Login', email, password);
|
||||||
|
});
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
17
apps/stats-mainnet-e2e/src/support/index.ts
Normal file
17
apps/stats-mainnet-e2e/src/support/index.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands';
|
10
apps/stats-mainnet-e2e/tsconfig.json
Normal file
10
apps/stats-mainnet-e2e/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"sourceMap": false,
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"allowJs": true,
|
||||||
|
"types": ["cypress", "node"]
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.js"]
|
||||||
|
}
|
11
apps/stats-mainnet/.babelrc
Normal file
11
apps/stats-mainnet/.babelrc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@nrwl/react/babel",
|
||||||
|
{
|
||||||
|
"runtime": "automatic"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": []
|
||||||
|
}
|
16
apps/stats-mainnet/.browserslistrc
Normal file
16
apps/stats-mainnet/.browserslistrc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# This file is used by:
|
||||||
|
# 1. autoprefixer to adjust CSS to support the below specified browsers
|
||||||
|
# 2. babel preset-env to adjust included polyfills
|
||||||
|
#
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
#
|
||||||
|
# If you need to support different browsers in production, you may tweak the list below.
|
||||||
|
|
||||||
|
last 1 Chrome version
|
||||||
|
last 1 Firefox version
|
||||||
|
last 2 Edge major versions
|
||||||
|
last 2 Safari major version
|
||||||
|
last 2 iOS major versions
|
||||||
|
Firefox ESR
|
||||||
|
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
18
apps/stats-mainnet/.eslintrc.json
Normal file
18
apps/stats-mainnet/.eslintrc.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
apps/stats-mainnet/jest.config.js
Normal file
11
apps/stats-mainnet/jest.config.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
displayName: 'stats-mainnet',
|
||||||
|
preset: '../../jest.preset.js',
|
||||||
|
transform: {
|
||||||
|
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
|
||||||
|
'^.+\\.[tj]sx?$': 'babel-jest',
|
||||||
|
},
|
||||||
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
|
coverageDirectory: '../../coverage/apps/stats-mainnet',
|
||||||
|
setupFilesAfterEnv: ['./src/setup-tests.ts'],
|
||||||
|
};
|
10
apps/stats-mainnet/postcss.config.js
Normal file
10
apps/stats-mainnet/postcss.config.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const { join } = require('path');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {
|
||||||
|
config: join(__dirname, 'tailwind.config.js'),
|
||||||
|
},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
74
apps/stats-mainnet/project.json
Normal file
74
apps/stats-mainnet/project.json
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"root": "apps/stats-mainnet",
|
||||||
|
"sourceRoot": "apps/stats-mainnet/src",
|
||||||
|
"projectType": "application",
|
||||||
|
"targets": {
|
||||||
|
"build": {
|
||||||
|
"executor": "@nrwl/web:webpack",
|
||||||
|
"outputs": ["{options.outputPath}"],
|
||||||
|
"defaultConfiguration": "production",
|
||||||
|
"options": {
|
||||||
|
"compiler": "babel",
|
||||||
|
"outputPath": "dist/apps/stats-mainnet",
|
||||||
|
"index": "apps/stats-mainnet/src/index.html",
|
||||||
|
"baseHref": "/",
|
||||||
|
"main": "apps/stats-mainnet/src/main.tsx",
|
||||||
|
"polyfills": "apps/stats-mainnet/src/polyfills.ts",
|
||||||
|
"tsConfig": "apps/stats-mainnet/tsconfig.app.json",
|
||||||
|
"assets": [
|
||||||
|
"apps/stats-mainnet/src/assets/favicon.ico",
|
||||||
|
"apps/stats-mainnet/src/assets"
|
||||||
|
],
|
||||||
|
"styles": ["apps/stats-mainnet/src/styles/styles.css"],
|
||||||
|
"scripts": [],
|
||||||
|
"webpackConfig": "@nrwl/react/plugins/webpack"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "apps/stats-mainnet/src/environments/environment.ts",
|
||||||
|
"with": "apps/stats-mainnet/src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"namedChunks": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"executor": "@nrwl/web:dev-server",
|
||||||
|
"options": {
|
||||||
|
"port": 3010,
|
||||||
|
"buildTarget": "stats-mainnet:build",
|
||||||
|
"hmr": true
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "stats-mainnet:build:production",
|
||||||
|
"hmr": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"executor": "@nrwl/linter:eslint",
|
||||||
|
"outputs": ["{options.outputFile}"],
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["apps/stats-mainnet/**/*.{ts,tsx,js,jsx}"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"executor": "@nrwl/jest:jest",
|
||||||
|
"outputs": ["coverage/apps/stats-mainnet"],
|
||||||
|
"options": {
|
||||||
|
"jestConfig": "apps/stats-mainnet/jest.config.js",
|
||||||
|
"passWithNoTests": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": []
|
||||||
|
}
|
24
apps/stats-mainnet/src/app.tsx
Normal file
24
apps/stats-mainnet/src/app.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Header } from './components/header';
|
||||||
|
import { StatsManager } from '@vegaprotocol/mainnet-stats-manager';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [darkMode, setDarkMode] = useState<boolean>(
|
||||||
|
document.documentElement.classList.contains('dark-mode-preferred')
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-screen min-h-screen grid pb-24 ${
|
||||||
|
darkMode ? 'bg-black text-white-80' : 'bg-white text-black-95'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="layout-grid w-screen justify-self-center">
|
||||||
|
<Header darkMode={darkMode} setDarkMode={setDarkMode} />
|
||||||
|
<StatsManager className="max-w-3xl px-24" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
BIN
apps/stats-mainnet/src/assets/apple-touch-icon.png
Normal file
BIN
apps/stats-mainnet/src/assets/apple-touch-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
apps/stats-mainnet/src/assets/favicon.ico
Normal file
BIN
apps/stats-mainnet/src/assets/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
BIN
apps/stats-mainnet/src/assets/logo.png
Normal file
BIN
apps/stats-mainnet/src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 547 B |
BIN
apps/stats-mainnet/src/assets/logo192.png
Normal file
BIN
apps/stats-mainnet/src/assets/logo192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
20
apps/stats-mainnet/src/assets/manifest.json
Normal file
20
apps/stats-mainnet/src/assets/manifest.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"short_name": "Mainnet Stats",
|
||||||
|
"name": "Vega Mainnet statistics",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "favicon.ico",
|
||||||
|
"sizes": "64x64 32x32 24x24 16x16",
|
||||||
|
"type": "image/x-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "logo192.png",
|
||||||
|
"type": "image/png",
|
||||||
|
"sizes": "192x192"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start_url": ".",
|
||||||
|
"display": "standalone",
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#ffffff"
|
||||||
|
}
|
3
apps/stats-mainnet/src/assets/robots.txt
Normal file
3
apps/stats-mainnet/src/assets/robots.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
32
apps/stats-mainnet/src/components/header/header.tsx
Normal file
32
apps/stats-mainnet/src/components/header/header.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { VegaLogo } from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { LightModeToggle, DarkModeToggle } from '../images';
|
||||||
|
import { VegaBackgroundVideo } from '../videos';
|
||||||
|
import { DarkModeState } from '../../config/types';
|
||||||
|
|
||||||
|
export const Header = ({ darkMode, setDarkMode }: DarkModeState) => {
|
||||||
|
return (
|
||||||
|
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
|
||||||
|
<VegaBackgroundVideo />
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`relative flex justify-center px-8 ${
|
||||||
|
darkMode ? 'bg-black' : 'bg-white'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
|
||||||
|
<VegaLogo />
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setDarkMode(!darkMode)}
|
||||||
|
aria-label="Switch theme color"
|
||||||
|
className={`transition-colors rounded-full cursor-pointer ${
|
||||||
|
darkMode ? 'hover:bg-neutral-900' : 'hover:bg-neutral-200'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{darkMode ? <LightModeToggle /> : <DarkModeToggle />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
};
|
1
apps/stats-mainnet/src/components/header/index.ts
Normal file
1
apps/stats-mainnet/src/components/header/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { Header } from './header';
|
@ -0,0 +1,18 @@
|
|||||||
|
export const DarkModeToggle = () => {
|
||||||
|
return (
|
||||||
|
<svg width="45" height="45">
|
||||||
|
<g>
|
||||||
|
<path
|
||||||
|
d="M22.5 27.79a5.29 5.29 0 1 0 0-10.58 5.29 5.29 0 0 0 0 10.58Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M15.01 22.5H10M35 22.5h-5.01M22.5 29.99V35M22.5 10v5.01M17.21 27.79l-3.55 3.55M31.34 13.66l-3.55 3.55M27.79 27.79l3.55 3.55M13.66 13.66l3.55 3.55"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth="1.3"
|
||||||
|
strokeMiterlimit="10"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
2
apps/stats-mainnet/src/components/images/index.ts
Normal file
2
apps/stats-mainnet/src/components/images/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export { DarkModeToggle } from './dark-mode-toggle';
|
||||||
|
export { LightModeToggle } from './light-mode-toggle';
|
@ -0,0 +1,10 @@
|
|||||||
|
export const LightModeToggle = () => {
|
||||||
|
return (
|
||||||
|
<svg width="45" height="45">
|
||||||
|
<path
|
||||||
|
d="M28.75 11.69A12.39 12.39 0 0 0 22.5 10a12.5 12.5 0 1 0 0 25c2.196 0 4.353-.583 6.25-1.69A12.46 12.46 0 0 0 35 22.5a12.46 12.46 0 0 0-6.25-10.81Zm-6.25 22a11.21 11.21 0 0 1-11.2-11.2 11.21 11.21 0 0 1 11.2-11.2c1.246 0 2.484.209 3.66.62a13.861 13.861 0 0 0-5 10.58 13.861 13.861 0 0 0 5 10.58 11.078 11.078 0 0 1-3.66.63v-.01Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
1
apps/stats-mainnet/src/components/videos/index.ts
Normal file
1
apps/stats-mainnet/src/components/videos/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { VegaBackgroundVideo } from './vega-background-video';
|
@ -0,0 +1,16 @@
|
|||||||
|
export const VegaBackgroundVideo = () => {
|
||||||
|
return (
|
||||||
|
<video
|
||||||
|
autoPlay
|
||||||
|
muted
|
||||||
|
loop
|
||||||
|
playsInline
|
||||||
|
className="absolute left-0 top-0 w-full h-auto"
|
||||||
|
>
|
||||||
|
<source
|
||||||
|
src="https://d33wubrfki0l68.cloudfront.net/2500bc5ef1b96927e0220eeb2bef0b22b87bcda1/3e0d3/static/moshed-aa65f0933af9abe9afb5e5663c9b3f68.mp4"
|
||||||
|
type="video/mp4"
|
||||||
|
/>
|
||||||
|
</video>
|
||||||
|
);
|
||||||
|
};
|
4
apps/stats-mainnet/src/config/types.ts
Normal file
4
apps/stats-mainnet/src/config/types.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface DarkModeState {
|
||||||
|
darkMode: boolean;
|
||||||
|
setDarkMode: (arg0: boolean) => void;
|
||||||
|
}
|
52
apps/stats-mainnet/src/index.html
Normal file
52
apps/stats-mainnet/src/index.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="assets/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta name="description" content="Health check for Vega's mainnet" />
|
||||||
|
<link rel="apple-touch-icon" href="assets/apple-touch-icon.png" />
|
||||||
|
<!--
|
||||||
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
|
-->
|
||||||
|
<link rel="manifest" href="assets/manifest.json" />
|
||||||
|
<!--
|
||||||
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
|
|
||||||
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||||
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
|
-->
|
||||||
|
<title>Vega Mainnet Stats</title>
|
||||||
|
<script>
|
||||||
|
// Set dark mode preference indicator here to avoid FOUC
|
||||||
|
if (
|
||||||
|
localStorage.theme === 'dark' ||
|
||||||
|
(!('theme' in localStorage) &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
) {
|
||||||
|
document.documentElement.classList.add('dark-mode-preferred');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark-mode-preferred');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
|
This HTML file is a template.
|
||||||
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file.
|
||||||
|
The build step will place the bundled scripts into the <body> tag.
|
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
|
-->
|
||||||
|
</body>
|
||||||
|
</html>
|
17
apps/stats-mainnet/src/main.tsx
Normal file
17
apps/stats-mainnet/src/main.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import './styles/styles.css';
|
||||||
|
import App from './app';
|
||||||
|
import reportWebVitals from './report-web-vitals';
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
|
||||||
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
// to log results (for example: reportWebVitals(console.log))
|
||||||
|
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||||
|
reportWebVitals();
|
7
apps/stats-mainnet/src/polyfills.ts
Normal file
7
apps/stats-mainnet/src/polyfills.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
|
||||||
|
*
|
||||||
|
* See: https://github.com/zloirock/core-js#babel
|
||||||
|
*/
|
||||||
|
import 'core-js/stable';
|
||||||
|
import 'regenerator-runtime/runtime';
|
1
apps/stats-mainnet/src/react-app-env.d.ts
vendored
Normal file
1
apps/stats-mainnet/src/react-app-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="react-scripts" />
|
15
apps/stats-mainnet/src/report-web-vitals.ts
Normal file
15
apps/stats-mainnet/src/report-web-vitals.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ReportHandler } from 'web-vitals';
|
||||||
|
|
||||||
|
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||||
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
|
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||||
|
getCLS(onPerfEntry);
|
||||||
|
getFID(onPerfEntry);
|
||||||
|
getFCP(onPerfEntry);
|
||||||
|
getLCP(onPerfEntry);
|
||||||
|
getTTFB(onPerfEntry);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default reportWebVitals;
|
5
apps/stats-mainnet/src/setup-tests.ts
Normal file
5
apps/stats-mainnet/src/setup-tests.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||||
|
// allows you to do things like:
|
||||||
|
// expect(element).toHaveTextContent(/react/i)
|
||||||
|
// learn more: https://github.com/testing-library/jest-dom
|
||||||
|
import '@testing-library/jest-dom';
|
BIN
apps/stats-mainnet/src/styles/AlphaLyrae-Medium.woff
Normal file
BIN
apps/stats-mainnet/src/styles/AlphaLyrae-Medium.woff
Normal file
Binary file not shown.
39
apps/stats-mainnet/src/styles/styles.css
Normal file
39
apps/stats-mainnet/src/styles/styles.css
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'AlphaLyrae-Medium';
|
||||||
|
src: url('./AlphaLyrae-Medium.woff');
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: repeat(2, auto) 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-grid {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.stats-grid {
|
||||||
|
grid-template-columns: 18rem 1fr;
|
||||||
|
grid-column-gap: 1.25rem;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
.promoted-stats {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.promoted-stats {
|
||||||
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@tailwind utilities;
|
12
apps/stats-mainnet/tailwind.config.js
Normal file
12
apps/stats-mainnet/tailwind.config.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const { join } = require('path');
|
||||||
|
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
|
||||||
|
const theme = require('../../libs/tailwindcss-config/src/theme');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
join(__dirname, 'src/**/*.{js,ts,jsx,tsx}'),
|
||||||
|
...createGlobPatternsForDependencies(__dirname),
|
||||||
|
],
|
||||||
|
theme,
|
||||||
|
plugins: [],
|
||||||
|
};
|
22
apps/stats-mainnet/tsconfig.app.json
Normal file
22
apps/stats-mainnet/tsconfig.app.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||||
|
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.test.ts",
|
||||||
|
"**/*.spec.tsx",
|
||||||
|
"**/*.test.tsx",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.test.js",
|
||||||
|
"**/*.spec.jsx",
|
||||||
|
"**/*.test.jsx"
|
||||||
|
],
|
||||||
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||||
|
}
|
25
apps/stats-mainnet/tsconfig.json
Normal file
25
apps/stats-mainnet/tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noPropertyAccessFromIndexSignature": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"files": [],
|
||||||
|
"include": [],
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.app.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "./tsconfig.spec.json"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
apps/stats-mainnet/tsconfig.spec.json
Normal file
23
apps/stats-mainnet/tsconfig.spec.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"module": "commonjs",
|
||||||
|
"types": ["jest", "node"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"**/*.test.ts",
|
||||||
|
"**/*.spec.ts",
|
||||||
|
"**/*.test.tsx",
|
||||||
|
"**/*.spec.tsx",
|
||||||
|
"**/*.test.js",
|
||||||
|
"**/*.spec.js",
|
||||||
|
"**/*.test.jsx",
|
||||||
|
"**/*.spec.jsx",
|
||||||
|
"**/*.d.ts"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||||
|
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||||
|
]
|
||||||
|
}
|
24
apps/trading/.env
Normal file
24
apps/trading/.env
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# React Environment Variables
|
||||||
|
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
||||||
|
|
||||||
|
# Netlify Environment Variables
|
||||||
|
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
||||||
|
NX_VERSION=$npm_package_version
|
||||||
|
NX_REPOSITORY_URL=$REPOSITORY_URL
|
||||||
|
NX_BRANCH=$BRANCH
|
||||||
|
NX_PULL_REQUEST=$PULL_REQUEST
|
||||||
|
NX_HEAD=$HEAD
|
||||||
|
NX_COMMIT_REF=$COMMIT_REF
|
||||||
|
NX_CONTEXT=$CONTEXT
|
||||||
|
NX_REVIEW_ID=$REVIEW_ID
|
||||||
|
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
||||||
|
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
||||||
|
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
||||||
|
NX_URL=$URL
|
||||||
|
NX_DEPLOY_URL=$DEPLOY_URL
|
||||||
|
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
||||||
|
|
||||||
|
# App configuration variables
|
||||||
|
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
||||||
|
NX_ETHEREUM_CHAIN_ID = 3
|
||||||
|
NX_INFURA_ID = "4f846e79e13f44d1b51bbd7ed9edefb8";
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user