Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c687d1a275 | ||
|
|
6dc9c006b3 | ||
|
|
e431ae8968 |
@@ -48,8 +48,7 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
id: ${{ github.event.release.id }}
|
||||
body: |
|
||||
|
||||
___
|
||||
---
|
||||
|
||||
# Deployments
|
||||
* https://explorer.vega.xyz
|
||||
|
||||
@@ -98,37 +98,36 @@ jobs:
|
||||
# See affected apps
|
||||
- name: See affected apps
|
||||
run: |
|
||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
|
||||
echo ">>>> debug"
|
||||
echo "NX_BASE: ${{ env.NX_BASE }}"
|
||||
echo "NX_HEAD: ${{ env.NX_HEAD }}"
|
||||
echo "Affected: ${affected}"
|
||||
echo "Branch slug: ${branch_slug}"
|
||||
echo ">>>> eof debug"
|
||||
|
||||
affected="$(yarn nx print-affected --base=${{ env.NX_BASE }} --head=${{ env.NX_HEAD }} --select=projects)"
|
||||
|
||||
branch_slug="$(echo '${{ github.head_ref || github.ref_name }}' | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | cut -c 1-50 )"
|
||||
projects_e2e=""
|
||||
preview_governance="not deployed"
|
||||
preview_trading="not deployed"
|
||||
preview_explorer="not deployed"
|
||||
if [[ $affected == *"governance"* ]]; then
|
||||
projects_e2e+='"governance-e2e" '
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"trading"* ]]; then
|
||||
projects_e2e+='"trading-e2e" '
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"explorer"* ]]; then
|
||||
projects_e2e+='"explorer-e2e" '
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
if [[ -z "$projects_e2e" ]]; then
|
||||
projects_e2e+='"governance-e2e" "trading-e2e" "explorer-e2e" '
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
else
|
||||
if [[ $affected == *"governance"* ]]; then
|
||||
projects_e2e+='"governance-e2e" '
|
||||
preview_governance=$(printf "https://%s.%s.vega.rocks" "governance" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"trading"* ]]; then
|
||||
projects_e2e+='"trading-e2e" '
|
||||
preview_trading=$(printf "https://%s.%s.vega.rocks" "trading" "$branch_slug")
|
||||
fi
|
||||
if [[ $affected == *"explorer"* ]]; then
|
||||
projects_e2e+='"explorer-e2e" '
|
||||
preview_explorer=$(printf "https://%s.%s.vega.rocks" "explorer" "$branch_slug")
|
||||
fi
|
||||
fi
|
||||
projects_e2e=${projects_e2e%?}
|
||||
projects_e2e=[${projects_e2e// /,}]
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Generate tranches
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */6 * * *'
|
||||
|
||||
jobs:
|
||||
master:
|
||||
name: Generate Queries
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.VEGA_CI_BOT_GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
- name: Use Node.js 16
|
||||
id: Node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.15.1
|
||||
- name: Install root dependencies
|
||||
run: yarn install
|
||||
- name: Generate queries
|
||||
run: node ./scripts/get-tranches.js
|
||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: 'chore: update tranches'
|
||||
commit_options: '--no-verify --signoff'
|
||||
skip_fetch: true
|
||||
skip_checkout: true
|
||||
@@ -59,39 +59,26 @@ jobs:
|
||||
key: ${{ runner.os }}-cache-node-modules-${{ hashFiles('yarn.lock') }}
|
||||
|
||||
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
- name: Define dist variables
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
- name: Define variables
|
||||
run: |
|
||||
envName=''
|
||||
domain="vega.rocks"
|
||||
bucketName=''
|
||||
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
||||
envName="mainnet"
|
||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ "${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }}" = "true" ]]; then
|
||||
envName="mainnet"
|
||||
fi
|
||||
|
||||
if [[ "${envName}" = "mainnet" ]]; then
|
||||
domain="vega.xyz"
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
elif [[ "${envName}" = "testnet" ]]; then
|
||||
domain="fairground.wtf"
|
||||
bucketName="${{ matrix.app }}.${domain}"
|
||||
fi
|
||||
|
||||
if [[ -z "${bucketName}" ]]; then
|
||||
if [[ "${{ github.event_name }}" = "push" ]]; then
|
||||
if [[ "${{ github.ref }}" =~ .*release/.* ]]; then
|
||||
envName="$(echo ${{ github.ref }} | rev | cut -d '/' -f 1 | rev)"
|
||||
elif [[ "${{ github.ref }}" =~ .*develop$ ]]; then
|
||||
envName="stagnet1"
|
||||
elif [[ "${{ matrix.app}}" = "trading" ]] && [[ ${{ startsWith(github.ref, 'refs/tags/v') && 'true' || 'false' }} = "true" ]]; then
|
||||
envName="mainnet"
|
||||
elif [[ "${{ github.ref }}" =~ .*main$ ]]; then
|
||||
envName="mainnet"
|
||||
fi
|
||||
if [[ "${envName}" = "mainnet" ]]; then
|
||||
domain="vega.xyz"
|
||||
fi
|
||||
bucketName="${{ matrix.app }}.${envName}.${domain}"
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
echo "bucket name: ${bucketName}"
|
||||
echo "env name: ${envName}"
|
||||
|
||||
echo BUCKET_NAME=${bucketName} >> $GITHUB_ENV
|
||||
echo ENV_NAME=${envName} >> $GITHUB_ENV
|
||||
|
||||
- name: Build local dist
|
||||
@@ -168,7 +155,7 @@ jobs:
|
||||
# bucket creation in github.com/vegaprotocol/terraform//frontend
|
||||
- name: Publish dist to s3
|
||||
uses: jakejarvis/s3-sync-action@master
|
||||
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') && ( matrix.app != 'trading' || (matrix.app == 'trading' && !endsWith(github.ref, 'main') ) ) }}
|
||||
if: ${{ github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/v') }}
|
||||
with:
|
||||
args: --acl private --follow-symlinks --delete
|
||||
env:
|
||||
|
||||
+3
-3
@@ -3,15 +3,15 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_TOKEN_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.xyz
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
|
||||
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.xyz/rest
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_VEGA_GOVERNANCE_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.jsoo
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# App configuration variables
|
||||
NX_TENDERMINT_URL=https://be.vega.community
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||
NX_SENTRY_DSN=https://b3a56b03eda842faad731f3ea9dfd1bc@o286262.ingest.sentry.io/6242427
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_ENV=MAINNET
|
||||
@@ -10,4 +9,3 @@ NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/
|
||||
NX_VEGA_CONSOLE_URL=https://vega.trading
|
||||
|
||||
@@ -10,4 +10,3 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -7,9 +7,8 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
|
||||
NX_TENDERMINT_URL=https://tm.be.validators-testnet.vega.rocks
|
||||
NX_VEGA_GOVERNANCE_URL=https://validator-testnet.governance.vega.xyz
|
||||
NX_TENDERMINT_URL=https://tm-be.validators-testnet.vega.rocks
|
||||
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest
|
||||
NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.xyz/websocket
|
||||
NX_VEGA_GOVERNANCE_URL=https://governance.validators-testnet.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks/
|
||||
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks/
|
||||
NX_VEGA_EXPLORER_URL=https://validator-testnet.explorer.vega.xyz/
|
||||
@@ -13,7 +13,6 @@ import { DEFAULT_CACHE_CONFIG } from '@vegaprotocol/apollo-client';
|
||||
import { RouterProvider } from 'react-router-dom';
|
||||
import { router } from './routes/router-config';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { Suspense } from 'react';
|
||||
|
||||
const splashLoading = (
|
||||
<Splash>
|
||||
@@ -33,9 +32,7 @@ function App() {
|
||||
skeleton={<div>{t('Loading')}</div>}
|
||||
failure={<AppFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
|
||||
>
|
||||
<Suspense fallback={splashLoading}>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
</Suspense>
|
||||
<RouterProvider router={router} fallbackElement={splashLoading} />
|
||||
</NodeGuard>
|
||||
<NodeSwitcherDialog
|
||||
open={nodeSwitcherOpen}
|
||||
|
||||
@@ -4,11 +4,9 @@ import {
|
||||
} from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { Link, ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import { useMemo } from 'react';
|
||||
import { ENV } from '../../config/env';
|
||||
import { Routes } from '../../routes/route-names';
|
||||
import { Link as RouteLink } from 'react-router-dom';
|
||||
|
||||
export const Footer = () => {
|
||||
const { VEGA_URL, GIT_COMMIT_HASH, GIT_ORIGIN_URL } = useEnvironment();
|
||||
@@ -23,7 +21,7 @@ export const Footer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<footer className="grid grid-rows-2 lg:grid-cols-[1fr_auto] text-xs md:text-md lg:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-xs md:text-md md:flex md:col-span-2 px-4 py-2 gap-4 border-t border-vega-light-200 dark:border-vega-dark-200">
|
||||
<div className="flex justify-between gap-2 align-middle">
|
||||
{GIT_COMMIT_HASH && (
|
||||
<div className="content-center flex border-r border-neutral-700 dark:border-neutral-300 pr-4">
|
||||
@@ -58,16 +56,11 @@ export const Footer = () => {
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="pl-2 align-center lg:align-right lg:flex lg:justify-end gap-2 align-middle lg:max-w-xs lg:ml-auto">
|
||||
<RouteLink to={`/${Routes.DISCLAIMER}`} className="underline">
|
||||
Disclaimer
|
||||
</RouteLink>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export const NodeUrl = ({ url }: { url: string }) => {
|
||||
const NodeUrl = ({ url }: { url: string }) => {
|
||||
// get base url from api url, api sub domain
|
||||
const urlObj = new URL(url);
|
||||
const nodeUrl = urlObj.origin.replace(/^[^.]+\./g, '');
|
||||
|
||||
@@ -84,17 +84,15 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
||||
<AgGridColumn
|
||||
colId="asset"
|
||||
headerName={t('Settlement asset')}
|
||||
field="tradableInstrument.instrument.product.settlementAsset.symbol"
|
||||
field="tradableInstrument.instrument.product.settlementAsset"
|
||||
hide={window.innerWidth <= BREAKPOINT_MD}
|
||||
cellRenderer={({
|
||||
data,
|
||||
value,
|
||||
}: VegaICellRendererParams<
|
||||
MarketFieldsFragment,
|
||||
'tradableInstrument.instrument.product.settlementAsset.symbol'
|
||||
>) => {
|
||||
const value =
|
||||
data?.tradableInstrument.instrument.product.settlementAsset;
|
||||
return value ? (
|
||||
'tradableInstrument.instrument.product.settlementAsset'
|
||||
>) =>
|
||||
value ? (
|
||||
<ButtonLink
|
||||
onClick={(e) => {
|
||||
openAssetDetailsDialog(value.id, e.target as HTMLElement);
|
||||
@@ -104,8 +102,8 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
|
||||
</ButtonLink>
|
||||
) : (
|
||||
''
|
||||
);
|
||||
}}
|
||||
)
|
||||
}
|
||||
/>
|
||||
<AgGridColumn
|
||||
flex={2}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { render } from '@testing-library/react';
|
||||
import { OracleDetailsType, isInternalSourceType } from './oracle-details-type';
|
||||
import type { SourceType } from './oracle';
|
||||
import { PropertyKeyType } from '@vegaprotocol/types';
|
||||
import { OracleDetailsType } from './oracle-details-type';
|
||||
import type { SourceTypeName } from './oracle-details-type';
|
||||
|
||||
function renderComponent(type: SourceType) {
|
||||
return <OracleDetailsType sourceType={type} />;
|
||||
function renderComponent(type: SourceTypeName) {
|
||||
return <OracleDetailsType type={type} />;
|
||||
}
|
||||
|
||||
function renderWrappedComponent(type: SourceType) {
|
||||
function renderWrappedComponent(type: SourceTypeName) {
|
||||
return (
|
||||
<table>
|
||||
<tbody>{renderComponent(type)}</tbody>
|
||||
@@ -15,53 +14,19 @@ function renderWrappedComponent(type: SourceType) {
|
||||
);
|
||||
}
|
||||
|
||||
function mock(name: string): SourceType {
|
||||
return {
|
||||
sourceType: {
|
||||
filters: [
|
||||
{
|
||||
__typename: 'Filter',
|
||||
key: {
|
||||
name,
|
||||
type: PropertyKeyType.TYPE_STRING,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('Oracle type view', () => {
|
||||
it('Renders nothing when type is null', () => {
|
||||
const res = render(renderComponent(null as unknown as SourceType));
|
||||
const res = render(renderComponent(null as unknown as SourceTypeName));
|
||||
expect(res.container).toBeEmptyDOMElement();
|
||||
});
|
||||
|
||||
it('Renders Internal time for internal sources - timestamp', () => {
|
||||
const s = mock('vegaprotocol.builtin.timestamp');
|
||||
expect(isInternalSourceType(s)).toEqual(true);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('Internal data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders Internal time for internal sources - potential future types', () => {
|
||||
const s = mock('vegaprotocol.builtin.boolean');
|
||||
expect(isInternalSourceType(s)).toEqual(true);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('Internal data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders External data otherwise - prices.external.whatever', () => {
|
||||
const s = mock('prices.external.whatever');
|
||||
expect(isInternalSourceType(s)).toEqual(false);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
expect(res.getByText('External data')).toBeInTheDocument();
|
||||
it('Renders Internal time for internal sources', () => {
|
||||
const res = render(renderWrappedComponent('DataSourceDefinitionInternal'));
|
||||
expect(res.getByText('Internal time')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('Renders External data otherwise', () => {
|
||||
const s = mock('prices.external.vegaprotocol.builtin.');
|
||||
expect(isInternalSourceType(s)).toEqual(false);
|
||||
const res = render(renderWrappedComponent(s));
|
||||
const res = render(renderWrappedComponent('DataSourceDefinitionExternal'));
|
||||
expect(res.getByText('External data')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,51 +1,27 @@
|
||||
import { TableRow, TableCell, TableHeader } from '../../../components/table';
|
||||
import type { SourceType } from './oracle';
|
||||
|
||||
/**
|
||||
* Basic function to determine if a source is internal or external.
|
||||
*
|
||||
* This should be distinguishable using __typename, but the type is incorrectly
|
||||
* reported at the moment, so instead we check the filters.
|
||||
*
|
||||
* @param s SourceType
|
||||
* @returns boolean True if the source is internal
|
||||
*/
|
||||
export function isInternalSourceType(s: SourceType) {
|
||||
if ('filters' in s.sourceType) {
|
||||
const filters = s.sourceType.filters;
|
||||
|
||||
if (filters) {
|
||||
return (
|
||||
filters?.filter((f) => {
|
||||
return f.key.name?.indexOf('vegaprotocol.builtin.') === 0;
|
||||
}).length > 0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
export type SourceTypeName = SourceType['__typename'] | undefined;
|
||||
|
||||
interface OracleDetailsTypeProps {
|
||||
sourceType: SourceType;
|
||||
type: SourceTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a a single table row for the Oracle Details view that shows
|
||||
* if the oracle is using the internal time oracle or external data
|
||||
*/
|
||||
export function OracleDetailsType({ sourceType }: OracleDetailsTypeProps) {
|
||||
if (!sourceType) {
|
||||
export function OracleDetailsType({ type }: OracleDetailsTypeProps) {
|
||||
if (!type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isInternal = isInternalSourceType(sourceType);
|
||||
|
||||
return (
|
||||
<TableRow modifier="bordered">
|
||||
<TableHeader scope="row">Type</TableHeader>
|
||||
<TableCell modifier="bordered">
|
||||
{isInternal ? 'Internal data' : 'External data'}
|
||||
{type === 'DataSourceDefinitionInternal'
|
||||
? 'Internal time'
|
||||
: 'External data'}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
|
||||
@@ -53,7 +53,7 @@ export const OracleDetails = ({
|
||||
<OracleLink id={id} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<OracleDetailsType sourceType={sourceType} />
|
||||
<OracleDetailsType type={sourceType.__typename} />
|
||||
<OracleSigners sourceType={sourceType} />
|
||||
<OracleMarkets id={id} />
|
||||
<TableRow modifier="bordered">
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
|
||||
export const Disclaimer = () => {
|
||||
return (
|
||||
<section>
|
||||
<div className="px-40 max-sm:px-0 max-md:px-10 mb-4 max-w-5xl">
|
||||
<RouteTitle data-testid="disclaimer-header">
|
||||
{t('Disclaimer')}
|
||||
</RouteTitle>
|
||||
<p className="mt-3">
|
||||
The Vega Block Explorer is an application that allows users to, among
|
||||
other things, browse through blocks, view wallet addresses, network
|
||||
hashrate, transaction data and other key information on the Vega
|
||||
blockchain. It is free, public and open source software. Software
|
||||
upgrades may contain bugs or security vulnerabilities that might
|
||||
result in loss of functionality.
|
||||
</p>
|
||||
<p className="mt-3">
|
||||
The Vega Block Explorer uses data from nodes on the Vega Blockchain.
|
||||
The developers of the Vega Block Explorer do not operate or run the
|
||||
Vega Blockchain or any other blockchain.
|
||||
</p>
|
||||
<p className="mt-3 font-semibold">
|
||||
The Vega Block Explorer is provided “as is”. The developers of the
|
||||
Vega Block Explorer make no representations or warranties of any kind,
|
||||
whether express or implied, statutory or otherwise regarding the Vega
|
||||
Block Explorer. They disclaim all warranties of merchantability,
|
||||
quality, fitness for purpose. They disclaim all warranties that the
|
||||
Vega Block Explorer is free of harmful components or errors.
|
||||
</p>
|
||||
<p className="mt-3 font-bold">
|
||||
No developer of the Vega Block Explorer accepts any responsibility
|
||||
for, or liability to users in connection with their use of the Vega
|
||||
Block Explorer.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -10,5 +10,4 @@ export const Routes = {
|
||||
MARKETS: 'markets',
|
||||
ORACLES: 'oracles',
|
||||
NETWORK_PARAMETERS: 'network-parameters',
|
||||
DISCLAIMER: 'disclaimer',
|
||||
};
|
||||
|
||||
@@ -29,7 +29,6 @@ import { AssetLink, MarketLink } from '../components/links';
|
||||
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
|
||||
import { remove0x } from '@vegaprotocol/utils';
|
||||
import { PartyAccountsByAsset } from './parties/id/accounts';
|
||||
import { Disclaimer } from './pages/disclaimer';
|
||||
|
||||
export type Navigable = {
|
||||
path: string;
|
||||
@@ -336,17 +335,6 @@ export const routerConfig: Route[] = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: Routes.DISCLAIMER,
|
||||
element: <Disclaimer />,
|
||||
handle: {
|
||||
name: t('Disclaimer'),
|
||||
text: t('Disclaimer'),
|
||||
breadcrumb: () => (
|
||||
<Link to={Routes.DISCLAIMER}>{t('Disclaimer')}</Link>
|
||||
),
|
||||
},
|
||||
},
|
||||
...partiesRoutes,
|
||||
...assetsRoutes,
|
||||
...genesisRoutes,
|
||||
|
||||
@@ -5,11 +5,10 @@ NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_FAIRGROUND=false
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://stagnet1.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
|
||||
@@ -12,4 +12,3 @@ NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.n00.devnet1.vega.xyz/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
|
||||
@@ -3,10 +3,9 @@ NX_VEGA_ENV=MAINNET
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_ETHEREUM_PROVIDER_URL=https://eth-mainnet.gateway.pokt.network/v1/lb/6684b914570bbfa533ba9324
|
||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40:87edc2605e544f888305d7fc4a9141bd@o286262.ingest.sentry.io/5882996
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://governance.stagnet1.vega.rocks","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https://stagnet1.governance.vega.xyz","TESTNET":"https://governance.fairground.wtf","MAINNET":"https://governance.vega.xyz"}'
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
|
||||
|
||||
@@ -12,5 +12,4 @@ NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_DELEGATIONS_PAGINATION=50
|
||||
NX_TRANCHES_SERVICE_URL=https://tranches-testnet-k8s.ops.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
|
||||
@@ -9,5 +9,4 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
|
||||
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
|
||||
NX_VEGA_REST_URL=https://api-validators-testnet.vega.rocks/api/v2/
|
||||
@@ -1,40 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
ExternalLink,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import Routes from '../../routes/routes';
|
||||
|
||||
export const RiskMessage = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="bg-vega-light-100 dark:bg-vega-dark-100 p-6 mb-6">
|
||||
<ul className="list-[square] ml-4">
|
||||
<li>
|
||||
{t(
|
||||
'You may encounter bugs, loss of functionality or loss of assets using the App.'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'No party accepts any liability for any losses whatsoever related to its use.'
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'By using the Vega Governance App, you acknowledge that you have read and understood the'
|
||||
)}{' '}
|
||||
<ExternalLink href={Routes.DISCLAIMER} className="underline">
|
||||
<span className="flex items-center gap-1">
|
||||
<span>{t('Vega Governance Disclaimer')}</span>
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
</span>
|
||||
</ExternalLink>
|
||||
.
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -4,11 +4,9 @@ import {
|
||||
useAppState,
|
||||
} from '../../contexts/app-state/app-state-context';
|
||||
import { Connectors } from '../../lib/vega-connectors';
|
||||
import { RiskMessage } from './risk-message';
|
||||
|
||||
export const VegaWalletDialogs = () => {
|
||||
const { appState, appDispatch } = useAppState();
|
||||
|
||||
return (
|
||||
<>
|
||||
<VegaConnectDialog
|
||||
@@ -19,7 +17,6 @@ export const VegaWalletDialogs = () => {
|
||||
isOpen: open,
|
||||
})
|
||||
}
|
||||
riskMessage={<RiskMessage />}
|
||||
/>
|
||||
|
||||
<VegaManageDialog
|
||||
|
||||
@@ -815,11 +815,5 @@
|
||||
"NoThanks": "No thanks",
|
||||
"ShareData": "Share data",
|
||||
"ContinueSharingData": "Continue sharing data",
|
||||
"NodeUnsuitable": "Node: {{url}} is unsuitable",
|
||||
"Disclaimer": "Disclaimer",
|
||||
"disclaimer1": "The Vega Governance App allows the Vega network to arrive at on-chain decisions, where tokenholders can create proposals that other tokenholders can vote to approve or reject. Vega supports on-chain proposals for creating markets and assets, and changing network parameters, markets and assets. Vega also supports freeform proposals for community suggestions that will not be enacted on-chain.",
|
||||
"disclaimer2": "The Vega Governance App is free, public and open source software. Software upgrades may contain bugs or security vulnerabilities that might result in loss of functionality.",
|
||||
"disclaimer3": "The Vega Governance App uses data obtained from nodes on the Vega Blockchain. The developers of the Vega Governance App do not operate or run the Vega Blockchain or any other blockchain.",
|
||||
"disclaimer4": "The Vega Governance App is provided “as is”. The developers of the Vega Governance App make no representations or warranties of any kind, whether express or implied, statutory or otherwise regarding the Vega Governance App. They disclaim all warranties of merchantability, quality, fitness for purpose. They disclaim all warranties that the Vega Governance App is free of harmful components or errors.",
|
||||
"disclaimer5": "No developer of the Vega Governance App accepts any responsibility for, or liability to users in connection with their use of the Vega Governance App."
|
||||
"NodeUnsuitable": "Node: {{url}} is unsuitable"
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { RouteChildProps } from '..';
|
||||
import { useDocumentTitle } from '../../hooks/use-document-title';
|
||||
import { Heading } from '../../components/heading';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const Disclaimer = ({ name }: RouteChildProps) => {
|
||||
useDocumentTitle(name);
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Heading title={t('Disclaimer')} />
|
||||
<p className="mb-6 mt-10">{t('disclaimer1')}</p>
|
||||
<p className="mb-6">{t('disclaimer2')}</p>
|
||||
<p className="mb-6">{t('disclaimer3')}</p>
|
||||
<p className="mb-8">{t('disclaimer4')}</p>
|
||||
<p className="mb-8">{t('disclaimer5')}</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Disclaimer;
|
||||
@@ -209,10 +209,7 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
|
||||
[proposalsData]
|
||||
);
|
||||
|
||||
const sortedProposals = useMemo(
|
||||
() => orderByDate(proposals).reverse(),
|
||||
[proposals]
|
||||
);
|
||||
const sortedProposals = useMemo(() => orderByDate(proposals), [proposals]);
|
||||
|
||||
const protocolUpgradeProposals = useMemo(
|
||||
() =>
|
||||
|
||||
+23
@@ -115,6 +115,29 @@ describe('Proposals list', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Orders proposals correctly by closingDateTime', () => {
|
||||
render(
|
||||
renderComponent([
|
||||
failedProposalClosedLastMonth,
|
||||
openProposalClosesNextMonth,
|
||||
openProposalClosesNextWeek,
|
||||
enactedProposalClosedLastWeek,
|
||||
])
|
||||
);
|
||||
const openProposals = within(screen.getByTestId('open-proposals'));
|
||||
const closedProposals = within(screen.getByTestId('closed-proposals'));
|
||||
const openProposalsItems = openProposals.getAllByTestId(
|
||||
'proposals-list-item'
|
||||
);
|
||||
const closedProposalsItems = closedProposals.getAllByTestId(
|
||||
'proposals-list-item'
|
||||
);
|
||||
expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal2');
|
||||
expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal1');
|
||||
expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal3');
|
||||
expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal4');
|
||||
});
|
||||
|
||||
it('Displays info on no proposals', () => {
|
||||
render(renderComponent([]));
|
||||
expect(screen.queryByTestId('open-proposals')).not.toBeInTheDocument();
|
||||
|
||||
@@ -35,11 +35,7 @@ export const orderByDate = (arr: ProposalFieldsFragment[]) =>
|
||||
orderBy(
|
||||
arr,
|
||||
[
|
||||
(p) =>
|
||||
p?.terms?.enactmentDatetime
|
||||
? new Date(p?.terms?.enactmentDatetime).getTime()
|
||||
: // has to be defaulted to 0 because new Date(null).getTime() -> NaN which is first when ordered
|
||||
new Date(p?.terms?.closingDatetime || 0).getTime(),
|
||||
(p) => new Date(p?.terms?.closingDatetime).getTime(),
|
||||
(p) => new Date(p?.datetime).getTime(),
|
||||
],
|
||||
['asc', 'asc']
|
||||
|
||||
@@ -5,9 +5,6 @@ import { ProtocolUpgradeProposalDetailInfo } from '../components/protocol-upgrad
|
||||
import { getNormalisedVotingPower } from '../../staking/shared';
|
||||
import type { NodesFragmentFragment } from '../../staking/home/__generated__/Nodes';
|
||||
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { useVegaRelease } from '@vegaprotocol/environment';
|
||||
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export interface ProtocolUpgradeProposalProps {
|
||||
proposal: ProtocolUpgradeProposalFieldsFragment;
|
||||
@@ -45,9 +42,6 @@ export const ProtocolUpgradeProposal = ({
|
||||
lastBlockHeight,
|
||||
consensusValidators,
|
||||
}: ProtocolUpgradeProposalProps) => {
|
||||
const { t } = useTranslation();
|
||||
const releaseInfo = useVegaRelease(proposal.vegaReleaseTag);
|
||||
|
||||
const consensusApprovals = useMemo(
|
||||
() => getConsensusApprovals(consensusValidators || [], proposal),
|
||||
[consensusValidators, proposal]
|
||||
@@ -84,14 +78,6 @@ export const ProtocolUpgradeProposal = ({
|
||||
totalConsensusValidators={consensusValidators.length}
|
||||
/>
|
||||
)}
|
||||
|
||||
{releaseInfo && releaseInfo.htmlUrl && (
|
||||
<div className="mb-10">
|
||||
<ExternalLink href={releaseInfo.htmlUrl}>
|
||||
{t('Explore release on GitHub')}
|
||||
</ExternalLink>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -207,13 +207,6 @@ const LazyWithdrawals = React.lazy(
|
||||
)
|
||||
);
|
||||
|
||||
const LazyDisclaimer = React.lazy(
|
||||
() =>
|
||||
import(
|
||||
/* webpackChunkName: "route-disclaimer", webpackPrefetch: true */ './disclaimer'
|
||||
)
|
||||
);
|
||||
|
||||
const redirects = [
|
||||
{
|
||||
path: Routes.VALIDATORS,
|
||||
@@ -356,10 +349,6 @@ const routerConfig = [
|
||||
path: Routes.CONTRACTS,
|
||||
element: <LazyContracts name="Contracts" />,
|
||||
},
|
||||
{
|
||||
path: Routes.DISCLAIMER,
|
||||
element: <LazyDisclaimer name="Disclaimer" />,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
// Not lazy as loaded when a user first hits the site
|
||||
|
||||
@@ -15,7 +15,6 @@ const Routes = {
|
||||
SUPPLY: '/token/tranches',
|
||||
ASSOCIATE: '/token/associate',
|
||||
DISASSOCIATE: '/token/disassociate',
|
||||
DISCLAIMER: '/disclaimer',
|
||||
};
|
||||
|
||||
export default Routes;
|
||||
|
||||
@@ -71,6 +71,14 @@ export const calculateOverstakedPenalty = (nodeId: string, nodes: Node[]) => {
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0).dividedBy(tts)
|
||||
)
|
||||
.times(100);
|
||||
console.log(
|
||||
nodeId,
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0).toString(),
|
||||
tts.toString(),
|
||||
new BigNumber(node.rewardScore?.rawValidatorScore || 0)
|
||||
.dividedBy(tts)
|
||||
.toString()
|
||||
);
|
||||
return penalty.isLessThan(0) ? new BigNumber(0) : penalty;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,5 @@ NX_VEGA_URL="https://api.n07.testnet.vega.xyz/graphql"
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
||||
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
|
||||
NX_VEGA_ENV=DEVNET
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_URL=https://api.vega.community/graphql
|
||||
NX_VEGA_ENV=MAINNET
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||
NX_VEGA_CONSOLE_URL=https://vega.trading
|
||||
|
||||
@@ -4,6 +4,5 @@ NX_VEGA_URL=https://api.n00.stagnet1.vega.xyz/graphql
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
|
||||
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.tom
|
||||
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
|
||||
NX_VEGA_NETWORKS={'{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_NETWORKS='{"TESTNET":"https://multisig-signer.fairground.wtf","MAINNET":"https://multisig-signer.vega.xyz"}'
|
||||
NX_VEGA_ENV=VALIDATOR_TESTNET
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,7 @@ NX_VEGA_CONFIG_URL=''
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
@@ -20,7 +19,6 @@ CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit
|
||||
CYPRESS_ETHEREUM_WALLET_ADDRESS=0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F
|
||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
CYPRESS_CONSOLE_URL=https://console.fairground.wtf
|
||||
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||
CYPRESS_ORACLE_PUBKEY=6d9d35f657589e40ddfb448b7ad4a7463b66efb307527fedd2aa7df1bbd5ea61
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||
|
||||
@@ -5,8 +5,7 @@ NX_VEGA_CONFIG_URL=''
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
@@ -18,7 +17,6 @@ CYPRESS_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit
|
||||
CYPRESS_ETHEREUM_WALLET_ADDRESS=0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F
|
||||
CYPRESS_ETHEREUM_PROVIDER_URL=http://localhost:8545
|
||||
CYPRESS_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
CYPRESS_CONSOLE_URL=https://console.fairground.wtf
|
||||
CYPRESS_FAUCET_URL=http://localhost:1790/api/v1/mint
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY=02ecea…342f65
|
||||
CYPRESS_TRUNCATED_VEGA_PUBLIC_KEY2=7f9cf0…c25535
|
||||
|
||||
@@ -24,7 +24,7 @@ module.exports = defineConfig({
|
||||
viewportHeight: 900,
|
||||
responseTimeout: 50000,
|
||||
requestTimeout: 20000,
|
||||
retries: 1,
|
||||
retries: 2,
|
||||
testIsolation: false,
|
||||
},
|
||||
env: {
|
||||
|
||||
@@ -50,7 +50,10 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
cy.wrap(markets[0]).as('market');
|
||||
});
|
||||
cy.visit('/#/portfolio');
|
||||
cy.connectVegaWallet();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.setVegaWallet();
|
||||
});
|
||||
|
||||
it('can deposit', function () {
|
||||
@@ -169,6 +172,7 @@ describe('capsule - without MultiSign', { tags: '@slow' }, () => {
|
||||
'contain.text',
|
||||
'Error occurredcannot estimate gas'
|
||||
);
|
||||
cy.getByTestId(toastCloseBtn).click({ multiple: true });
|
||||
cy.getByTestId(completeWithdrawalBtn).should(
|
||||
'contain.text',
|
||||
'Complete withdrawal'
|
||||
@@ -372,14 +376,10 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
'contain.text',
|
||||
'Transaction confirmed'
|
||||
);
|
||||
cy.getByTestId(toastContent, txTimeout)
|
||||
.should('contain.text', 'Funds unlocked')
|
||||
.and('contain.text', 'Your funds have been unlocked for withdrawal.')
|
||||
.and(
|
||||
'contain.text',
|
||||
'View in block explorerYou can save your withdrawal details for extra security.'
|
||||
)
|
||||
.and('contain.text', 'Withdraw 1.00 tBTCComplete withdrawal');
|
||||
cy.getByTestId(toastContent, txTimeout).should(
|
||||
'contain.text',
|
||||
'Funds unlockedYour funds have been unlocked for withdrawalView in block explorerWithdraw 1.00 tBTCComplete withdrawal'
|
||||
);
|
||||
|
||||
cy.get('.ag-center-cols-container')
|
||||
.find('[col-id="status"]')
|
||||
@@ -407,7 +407,7 @@ describe('capsule', { tags: '@slow', testIsolation: true }, () => {
|
||||
});
|
||||
|
||||
cy.getByTestId('withdraw-dialog-button').click({ force: true });
|
||||
// cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '6.999');
|
||||
cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '7.999');
|
||||
});
|
||||
|
||||
it('approved amount is less than deposit', function () {
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
import { closeWelcomeDialog } from '../support/helpers';
|
||||
|
||||
const dialogContent = 'dialog-content';
|
||||
const nodeHealth = 'node-health';
|
||||
|
||||
describe.skip('home', { tags: '@regression' }, () => {
|
||||
describe('home', { tags: '@regression' }, () => {
|
||||
before(() => {
|
||||
cy.clearAllLocalStorage();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.visit('/');
|
||||
closeWelcomeDialog();
|
||||
});
|
||||
|
||||
describe('footer', () => {
|
||||
it('shows current block height', () => {
|
||||
it.skip('shows current block height', () => {
|
||||
closeWelcomeDialog();
|
||||
// 0006-NETW-004
|
||||
// 0006-NETW-005
|
||||
// 0006-NETW-008
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||
import type { ProposalListFieldsFragment } from '@vegaprotocol/proposals';
|
||||
import { marketsDataQuery } from '@vegaprotocol/mock';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
||||
const selectMarketOverlay = 'select-market-list';
|
||||
const dialogContent = 'dialog-content';
|
||||
|
||||
const generateProposal = (code: string): ProposalListFieldsFragment => ({
|
||||
@@ -108,12 +110,77 @@ describe('home', { tags: '@regression' }, () => {
|
||||
|
||||
cy.get('main[data-testid^="/markets/"]');
|
||||
|
||||
// Overlay should be shown
|
||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||
cy.contains('Select a market to get started').should('be.visible');
|
||||
|
||||
// I expect the market overlay table to contain at least 3 rows (one header row)
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.then((row) => {
|
||||
expect(row.length >= 3).to.be.true;
|
||||
});
|
||||
|
||||
// each market shown in overlay table contains content under the last price and change fields
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.each(($element, index) => {
|
||||
if (index > 0) {
|
||||
// skip header row
|
||||
cy.root().within(() => {
|
||||
cy.getByTestId('price').should('not.be.empty');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cy.getByTestId('welcome-notice-proposed-markets')
|
||||
.children('div.pt-1.flex.justify-between')
|
||||
.should('have.length', 3)
|
||||
.each((item) => {
|
||||
cy.wrap(item).getByTestId('external-link').should('exist');
|
||||
});
|
||||
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId(selectMarketOverlay).should('not.exist');
|
||||
|
||||
// the choose market overlay is no longer showing
|
||||
cy.contains('Select a market to get started').should('not.exist');
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('market table should be properly rendered', () => {
|
||||
it('redirects to a default market with the landing dialog open', () => {
|
||||
const override = {
|
||||
marketsConnection: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
data: {
|
||||
markPrice: '46126900581221212121212121212121212121212121212',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
// @ts-ignore partial deep check failing
|
||||
const data = marketsDataQuery(override);
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'MarketsData', data);
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table')
|
||||
.invoke('outerWidth')
|
||||
.then((value) => {
|
||||
expect(value).to.be.closeTo(554, 10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('no markets found', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL((req) => {
|
||||
@@ -139,13 +206,40 @@ describe('home', { tags: '@regression' }, () => {
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
});
|
||||
|
||||
it('redirects to market/all and displays welcome notice', () => {
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets/all`);
|
||||
it('redirects to a the empty market page and displays welcome notice', () => {
|
||||
cy.url().should('eq', Cypress.config().baseUrl + `/#/markets`);
|
||||
cy.getByTestId('welcome-notice-title').should(
|
||||
'contain.text',
|
||||
'Welcome to Console'
|
||||
);
|
||||
cy.getByTestId('welcome-notice-proposed-markets').should(
|
||||
'contain.text',
|
||||
'AAAZZZ'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('no proposal found', () => {
|
||||
it('there is a link to propose market', () => {
|
||||
cy.mockGQL((req) => {
|
||||
aliasGQLQuery(req, 'ProposalsList', {
|
||||
proposalsConnection: {
|
||||
__typename: 'ProposalsConnection',
|
||||
edges: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.then((row) => {
|
||||
expect(row.length >= 3).to.be.true;
|
||||
});
|
||||
cy.getByTestId('external-link')
|
||||
.contains('Propose a market')
|
||||
.should('exist');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const selectMarketOverlay = 'select-market-list';
|
||||
const marketInfoBtn = 'Info';
|
||||
const marketInfoSubtitle = 'accordion-title';
|
||||
const marketSummaryBlock = 'header-summary';
|
||||
@@ -13,6 +14,45 @@ const itemHeader = 'item-header';
|
||||
const itemValue = 'item-value';
|
||||
const marketListContent = 'popover-content';
|
||||
|
||||
describe(
|
||||
'Console - market list - live env',
|
||||
{ tags: '@live', testIsolation: true },
|
||||
() => {
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
});
|
||||
|
||||
it('shows the market list page', () => {
|
||||
cy.get('main', { timeout: 20000 });
|
||||
|
||||
// Overlay should be shown
|
||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||
cy.contains('Select a market to get started').should('be.visible');
|
||||
|
||||
// I expect the market overlay table to contain at least one row
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.should('have.length.greaterThan', 1);
|
||||
|
||||
// each market shown in overlay table contains content under the last price and change fields
|
||||
cy.getByTestId(selectMarketOverlay)
|
||||
.get('table tr')
|
||||
.getByTestId('price')
|
||||
.should('not.be.empty');
|
||||
});
|
||||
|
||||
it('redirects to a default market', () => {
|
||||
cy.getByTestId('dialog-close').click();
|
||||
cy.getByTestId(selectMarketOverlay).should('not.exist');
|
||||
|
||||
// the choose market overlay is no longer showing
|
||||
cy.contains('Select a market to get started').should('not.exist');
|
||||
cy.contains('Loading...').should('not.exist');
|
||||
cy.getByTestId('popover-trigger').should('not.be.empty');
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
describe(
|
||||
'Console - market info - live env',
|
||||
{ tags: '@live', testIsolation: true },
|
||||
|
||||
@@ -38,28 +38,28 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
// TODO: load data from mocks in. Using alias and wrap intermittently fails
|
||||
const data = [
|
||||
{
|
||||
code: 'SOLUSD',
|
||||
markPrice: '84.41XYZalpha',
|
||||
code: 'AAPL.MF21',
|
||||
name: 'Apple Monthly (30 Jun 2022)',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
vol: '324h vol',
|
||||
},
|
||||
{
|
||||
code: 'ETHBTC.QM21',
|
||||
markPrice: '46,126.90058tBTC',
|
||||
change: '+200.00%',
|
||||
vol: '324h vol',
|
||||
},
|
||||
{
|
||||
code: 'BTCUSD.MF21',
|
||||
markPrice: '46,126.90058tDAI',
|
||||
name: 'ACTIVE MARKET',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
vol: '324h vol',
|
||||
},
|
||||
{
|
||||
code: 'AAPL.MF21',
|
||||
markPrice: '46,126.90058tUSDC',
|
||||
code: 'ETHBTC.QM21',
|
||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||
markPrice: '46,126.90058',
|
||||
change: '+200.00%',
|
||||
},
|
||||
{
|
||||
code: 'SOLUSD',
|
||||
name: 'SUSPENDED MARKET',
|
||||
markPrice: '84.41',
|
||||
change: '+200.00%',
|
||||
vol: '324h vol',
|
||||
},
|
||||
];
|
||||
cy.getByTestId(list)
|
||||
@@ -68,13 +68,12 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
const market = data[i];
|
||||
// 6001-MARK-021
|
||||
expect(item.find('h3').text()).equals(market.code);
|
||||
expect(
|
||||
item.find('[data-testid="market-selector-data-row"]').eq(0).text()
|
||||
).contains(market.vol);
|
||||
// 6001-MARK-022
|
||||
expect(item.find('h4').text()).equals(market.name);
|
||||
// 6001-MARK-024
|
||||
expect(
|
||||
item.find('[data-testid="market-selector-data-row"]').eq(1).text()
|
||||
).contains(market.markPrice);
|
||||
expect(item.find('[data-testid="market-item-price"]').text()).equals(
|
||||
market.markPrice
|
||||
);
|
||||
// 6001-MARK-023
|
||||
expect(item.find('[data-testid="market-item-change"]').text()).equals(
|
||||
market.change
|
||||
@@ -97,8 +96,8 @@ describe('markets selector', { tags: '@smoke' }, () => {
|
||||
// 6001-MARK-29
|
||||
cy.getByTestId(searchInput).clear().type('btc');
|
||||
cy.getByTestId(list).find('a').should('have.length', 2);
|
||||
cy.getByTestId(list).find('a').eq(1).contains('BTCUSD.MF21');
|
||||
cy.getByTestId(list).find('a').eq(0).contains('ETHBTC.QM21');
|
||||
cy.getByTestId(list).find('a').eq(0).contains('BTCUSD.MF21');
|
||||
cy.getByTestId(list).find('a').eq(1).contains('ETHBTC.QM21');
|
||||
|
||||
cy.getByTestId(searchInput).clear();
|
||||
cy.getByTestId(list).find('a').should('have.length', 4);
|
||||
|
||||
@@ -3,6 +3,8 @@ import { aliasGQLQuery, checkSorting } from '@vegaprotocol/cypress';
|
||||
import { marketsQuery } from '@vegaprotocol/mock';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
|
||||
const dialogCloseBtn = 'dialog-close';
|
||||
|
||||
describe('markets table', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage().then(() => {
|
||||
@@ -12,18 +14,20 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
|
||||
);
|
||||
cy.mockSubscription();
|
||||
cy.visit('/#/markets/all');
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
cy.wait('@MarketsCandles');
|
||||
});
|
||||
});
|
||||
|
||||
it('renders markets correctly', () => {
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
cy.get('[data-testid^="market-link-"]').should('not.be.empty');
|
||||
cy.getByTestId('price').invoke('text').should('not.be.empty');
|
||||
cy.getByTestId('settlement-asset').should('not.be.empty');
|
||||
cy.getByTestId('price-change-percentage').should('not.be.empty');
|
||||
cy.getByTestId('price-change').should('not.be.empty');
|
||||
cy.getByTestId('sparkline-svg').should('be.visible');
|
||||
});
|
||||
|
||||
it('able to open and sort full market list - market page', () => {
|
||||
@@ -33,6 +37,9 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
'ETHBTC.QM21',
|
||||
'SOLUSD',
|
||||
];
|
||||
cy.getByTestId('view-market-list-link')
|
||||
.should('have.attr', 'href', '#/markets/all')
|
||||
.click();
|
||||
cy.url().should('eq', Cypress.config('baseUrl') + '/#/markets/all');
|
||||
cy.contains('AAPL.MF21').should('be.visible');
|
||||
cy.get('.ag-header-cell-label').contains('Market').click(); // sort by market name
|
||||
@@ -44,6 +51,10 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
});
|
||||
|
||||
it('proposed markets tab should be rendered properly', () => {
|
||||
cy.getByTestId('view-market-list-link')
|
||||
.should('have.attr', 'href', '#/markets/all')
|
||||
.click();
|
||||
|
||||
cy.get('[data-testid="All markets"]').should(
|
||||
'have.attr',
|
||||
'data-state',
|
||||
@@ -76,8 +87,8 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/propose/new-market`
|
||||
);
|
||||
});
|
||||
|
||||
it('proposed markets tab should be sorted properly', () => {
|
||||
cy.getByTestId('view-market-list-link').click();
|
||||
cy.get('[data-testid="Proposed markets"]').click();
|
||||
const marketColDefault = [
|
||||
'ETHUSD',
|
||||
@@ -156,7 +167,7 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
checkSorting('state', stateColDefault, stateColAsc, stateColDesc);
|
||||
});
|
||||
|
||||
it.skip('opening auction subsets should be properly displayed', () => {
|
||||
it('opening auction subsets should be properly displayed', () => {
|
||||
cy.mockTradingPage(
|
||||
Schema.MarketState.STATE_ACTIVE,
|
||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION
|
||||
@@ -189,6 +200,7 @@ describe('markets table', { tags: '@smoke' }, () => {
|
||||
});
|
||||
cy.visit('#/markets/market-0');
|
||||
cy.url().should('contain', 'market-0');
|
||||
cy.getByTestId(dialogCloseBtn).click();
|
||||
cy.getByTestId('item-value').contains('Opening auction').realHover();
|
||||
cy.getByTestId('opening-auction-sub-status').should(
|
||||
'contain.text',
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { mockConnectWallet } from '@vegaprotocol/cypress';
|
||||
|
||||
describe('Navbar', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
before(() => {
|
||||
cy.clearAllLocalStorage();
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.visit('/');
|
||||
cy.wait('@Markets');
|
||||
cy.wait('@MarketsData');
|
||||
cy.wait('@MarketsCandles');
|
||||
// close welcome dialog
|
||||
cy.getByTestId('dialog-close').click();
|
||||
});
|
||||
|
||||
const pages = [
|
||||
@@ -44,18 +47,6 @@ describe('Navbar', { tags: '@smoke' }, () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Disclaimer should be presented after choosing from menu', () => {
|
||||
cy.get('nav')
|
||||
.find('ul li:contains(Resources)')
|
||||
.contains('Resources')
|
||||
.click();
|
||||
cy.getByTestId('Disclaimer').eq(0).click();
|
||||
cy.location('hash').should('equal', '#/disclaimer');
|
||||
cy.get('p').contains(
|
||||
'Vega is a decentralised peer-to-peer protocol that can be used to trade derivatives with cryptoassets.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mobile view', () => {
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { closeWelcomeDialog } from '../support/helpers';
|
||||
|
||||
describe('Settings page', { tags: '@smoke' }, () => {
|
||||
beforeEach(() => {
|
||||
cy.clearLocalStorage().then(() => {
|
||||
cy.mockTradingPage();
|
||||
cy.mockSubscription();
|
||||
cy.visit('/');
|
||||
closeWelcomeDialog();
|
||||
cy.get('[aria-label="cog icon"]').click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,3 +9,8 @@ export const selectAsset = (assetIndex: number) => {
|
||||
// eslint-disable-next-line
|
||||
cy.wait(100);
|
||||
};
|
||||
|
||||
export const closeWelcomeDialog = () => {
|
||||
cy.getByTestId('select-market-list').should('exist');
|
||||
cy.getByTestId('dialog-close').click();
|
||||
};
|
||||
|
||||
@@ -85,7 +85,7 @@ const mockTradingPage = (
|
||||
trigger?: Schema.AuctionTrigger
|
||||
) => {
|
||||
aliasGQLQuery(req, 'ChainId', chainIdQuery());
|
||||
aliasGQLQuery(req, 'NodeCheck', statisticsQuery());
|
||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||
aliasGQLQuery(req, 'NodeGuard', nodeGuardQuery());
|
||||
aliasGQLQuery(
|
||||
req,
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
|
||||
@@ -4,8 +4,8 @@ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_VEGA_CONFIG_URL=''
|
||||
NX_VEGA_ENV=CUSTOM
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_URL=http://localhost:3008/graphql
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
|
||||
@@ -2,11 +2,10 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_TRADING_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
|
||||
NX_VEGA_ENV=DEVNET
|
||||
NX_VEGA_EXPLORER_URL=https://dev.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
NX_ETHEREUM_PROVIDER_URL=https://eth-mainnet.gateway.pokt.network/v1/lb/af6a2d529a11f8158bc8ca2a
|
||||
NX_ETHEREUM_PROVIDER_URL=https://mainnet.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
|
||||
NX_ETHERSCAN_URL=https://etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_TRADING_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/mainnet1/mainnet1.toml
|
||||
NX_VEGA_ENV=MAINNET
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://alpha.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
|
||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
NX_VEGA_CONSOLE_URL=https://vega.trading
|
||||
# TAG name of the current app version - TODO: bump to the latest upon release
|
||||
NX_APP_VERSION=v0.20.12-core-0.71.4
|
||||
|
||||
@@ -2,12 +2,11 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_TRADING_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
|
||||
NX_VEGA_ENV=STAGNET1
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.stagnet1.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://stagnet1.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://stagnet1.governance.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
|
||||
@@ -2,15 +2,13 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_TRADING_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/fairground/vegawallet-fairground.toml
|
||||
NX_VEGA_ENV=TESTNET
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\"}
|
||||
NX_VEGA_NETWORKS={\"TESTNET\":\"https://console.fairground.wtf\",\"STAGNET1\":\"https://stagnet1.console.vega.xyz\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.fairground.wtf
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
NX_VEGA_CONSOLE_URL=https://console.fairground.wtf
|
||||
|
||||
@@ -2,15 +2,13 @@ NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9
|
||||
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
|
||||
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
|
||||
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
|
||||
NX_TRADING_SENTRY_DSN=https://2ffce43721964aafa78277c50654ece4@o286262.ingest.sentry.io/6300613
|
||||
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/master/testnet2/testnet2.toml
|
||||
NX_VEGA_ENV=VALIDATOR_TESTNET
|
||||
NX_VEGA_EXPLORER_URL=https://explorer.validators-testnet.vega.rocks
|
||||
NX_VEGA_NETWORKS={\"MAINNET\":\"https://vega.trading\",\"STAGNET1\":\"https://trading.stagnet1.vega.rocks\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_TOKEN_URL=https://governance.validators-testnet.vega.rocks
|
||||
NX_VEGA_EXPLORER_URL=https://validator-testnet.explorer.vega.xyz
|
||||
NX_VEGA_NETWORKS={\"STAGNET1\":\"https://stagnet1.console.vega.xyz\",\"TESTNET\":\"https://console.fairground.wtf\"}
|
||||
NX_VEGA_TOKEN_URL=https://validator-testnet.governance.vega.xyz
|
||||
NX_VEGA_WALLET_URL=http://localhost:1789
|
||||
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
|
||||
NX_VEGA_REPO_URL=https://github.com/vegaprotocol/vega/releases
|
||||
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
|
||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
NX_VEGA_CONSOLE_URL=https://trading.validators-testnet.vega.rocks
|
||||
NX_VEGA_INCIDENT_URL=https://blog.vega.xyz/tagged/vega-incident-reports
|
||||
@@ -1,48 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const Disclaimer = () => {
|
||||
return (
|
||||
<div className="py-16 px-8 flex w-full justify-center">
|
||||
<div className="lg:min-w-[700px] min-w-[300px] max-w-[700px]">
|
||||
<h1 className="text-4xl xl:text-5xl uppercase font-alpha calt">
|
||||
{t('Disclaimer')}
|
||||
</h1>
|
||||
<p className="mb-6 mt-10">
|
||||
{t(
|
||||
'Vega is a decentralised peer-to-peer protocol that can be used to trade derivatives with cryptoassets. The Vega Protocol is an implementation layer (layer one) protocol made of free, public, open-source or source-available software. Use of the Vega Protocol involves various risks, including but not limited to, losses while digital assets are supplied to the Vega Protocol and losses due to the fluctuation of prices of assets.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
{t(
|
||||
'Before using the Vega Protocol, review the relevant documentation at docs.vega.xyz to make sure that you understand how it works. Conduct your own due diligence and consult your financial advisor before making any investment decisions.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-6">
|
||||
{t(
|
||||
'As described in the Vega Protocol core license, the Vega Protocol is provided “as is”, at your own risk, and without warranties of any kind. Although Gobalsky Labs Limited developed much of the initial code for the Vega Protocol, it does not provide or control the Vega Protocol, which is run by third parties deploying it on a bespoke blockchain. Upgrades and modifications to the Vega Protocol are managed in a community-driven way by holders of the VEGA governance token.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'No developer or entity involved in creating the Vega Protocol will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the Vega Protocol, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or legal costs, or loss of profits, cryptoassets, tokens or anything else of value.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'This website is hosted on a decentralised network, the Interplanetary File System (“IPFS”). The IPFS decentralised web is made up of all the computers (nodes) connected to it. Data is therefore stored on many different computers.'
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
"The information provided on this website does not constitute investment advice, financial advice, trading advice, or any other sort of advice and you should not treat any of the website's content as such. No party recommends that any cryptoasset should be bought, sold, or held by you via this website. No party ensures the accuracy of information listed on this website or holds any responsibility for any missing or wrong information. You understand that you are using any and all information available here at your own risk."
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'Additionally, just as you can access email protocols such as SMTP through multiple email clients, you can potentially access the Vega Protocol through many web or mobile interfaces. You are responsible for doing your own diligence on those interfaces to understand the associated risks and any fees.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
import { Disclaimer } from './disclaimer';
|
||||
|
||||
export default Disclaimer;
|
||||
@@ -9,7 +9,7 @@ import { useGlobalStore } from '../../stores';
|
||||
export const Home = () => {
|
||||
const navigate = useNavigate();
|
||||
// The default market selected in the platform behind the overlay
|
||||
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
|
||||
// should be the oldest market that is currently trading in us mode(i.e. not in auction).
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider: marketsWithDataProvider,
|
||||
variables: undefined,
|
||||
@@ -30,7 +30,7 @@ export const Home = () => {
|
||||
replace: true,
|
||||
});
|
||||
} else {
|
||||
navigate(Links[Routes.MARKETS]());
|
||||
navigate(Links[Routes.MARKET]());
|
||||
}
|
||||
}
|
||||
}, [marketId, data, navigate, update]);
|
||||
|
||||
@@ -22,19 +22,7 @@ describe('MarketSelectorItem', () => {
|
||||
id: 'market-0',
|
||||
decimalPlaces: 2,
|
||||
// @ts-ignore fragment doesn't contain candles
|
||||
candles: [
|
||||
{ close: '5', volume: '50' },
|
||||
{ close: '10', volume: '50' },
|
||||
],
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
product: {
|
||||
settlementAsset: {
|
||||
symbol: 'SYM',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
candles: [{ close: '5' }, { close: '10' }],
|
||||
});
|
||||
const marketData: MarketDataUpdateFieldsFragment = {
|
||||
__typename: 'ObservableMarketData',
|
||||
@@ -95,9 +83,6 @@ describe('MarketSelectorItem', () => {
|
||||
};
|
||||
|
||||
it('renders market information', async () => {
|
||||
const symbol =
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol;
|
||||
|
||||
renderJsx();
|
||||
|
||||
const link = screen.getByRole('link');
|
||||
@@ -106,8 +91,7 @@ describe('MarketSelectorItem', () => {
|
||||
|
||||
expect(link).toHaveClass('ring-1');
|
||||
|
||||
expect(screen.getByTitle('24h vol')).toHaveTextContent('100');
|
||||
expect(screen.getByTitle(symbol)).toHaveTextContent('-');
|
||||
expect(screen.getByTestId('market-item-price')).toHaveTextContent('-');
|
||||
|
||||
// candles are loaded immediately
|
||||
expect(screen.getByTestId('market-item-change')).toHaveTextContent(
|
||||
@@ -115,7 +99,7 @@ describe('MarketSelectorItem', () => {
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTitle(symbol)).toHaveTextContent(
|
||||
expect(screen.getByTestId('market-item-price')).toHaveTextContent(
|
||||
addDecimalsFormatNumber(marketData.markPrice, market.decimalPlaces)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -7,14 +7,8 @@ import {
|
||||
priceChangePercentage,
|
||||
} from '@vegaprotocol/utils';
|
||||
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/markets';
|
||||
import { calcCandleVolume } from '@vegaprotocol/markets';
|
||||
import { useMarketDataUpdateSubscription } from '@vegaprotocol/markets';
|
||||
import { Sparkline } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
MarketTradingMode,
|
||||
MarketTradingModeMapping,
|
||||
} from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const MarketSelectorItem = ({
|
||||
market,
|
||||
@@ -44,6 +38,13 @@ export const MarketSelectorItem = ({
|
||||
onSelect && onSelect(market.id);
|
||||
}}
|
||||
>
|
||||
<h3>{market.tradableInstrument.instrument.code}</h3>
|
||||
<h4
|
||||
title={market.tradableInstrument.instrument.name}
|
||||
className="text-sm text-vega-light-300 dark:text-vega-dark-300 text-ellipsis whitespace-nowrap overflow-hidden"
|
||||
>
|
||||
{market.tradableInstrument.instrument.name}
|
||||
</h4>
|
||||
<MarketData market={market} />
|
||||
</Link>
|
||||
</div>
|
||||
@@ -67,84 +68,30 @@ const MarketData = ({ market }: { market: MarketMaybeWithDataAndCandles }) => {
|
||||
? addDecimalsFormatNumber(market.data.markPrice, market.decimalPlaces)
|
||||
: '-';
|
||||
|
||||
const marketTradingMode = marketData
|
||||
? marketData.marketTradingMode
|
||||
: market.tradingMode;
|
||||
|
||||
const mode = [
|
||||
MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||
MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
].includes(marketTradingMode)
|
||||
? MarketTradingModeMapping[marketTradingMode]
|
||||
: '';
|
||||
|
||||
const instrument = market.tradableInstrument.instrument;
|
||||
|
||||
const vol = market.candles ? calcCandleVolume(market.candles) : '0';
|
||||
const volume =
|
||||
vol && vol !== '0'
|
||||
? addDecimalsFormatNumber(vol, market.positionDecimalPlaces)
|
||||
: '0.00';
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex items-end gap-1 mb-1">
|
||||
<h3
|
||||
className={classNames(
|
||||
'overflow-hidden text-ellipsis whitespace-nowrap',
|
||||
{
|
||||
'w-1/2': mode, // make space for showing the trading mode
|
||||
}
|
||||
)}
|
||||
<div className="flex flex-nowrap justify-between items-center mt-1">
|
||||
<div className="w-1/2">
|
||||
<div
|
||||
className="text-ellipsis whitespace-nowrap overflow-hidden"
|
||||
data-testid="market-item-price"
|
||||
>
|
||||
{market.tradableInstrument.instrument.code}
|
||||
</h3>
|
||||
{mode && (
|
||||
<p className="w-1/2 text-xs text-right text-vega-orange-500 dark:text-vega-orange-550">
|
||||
{mode}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<DataRow value={volume} label={t('24h vol')} />
|
||||
<DataRow
|
||||
value={price}
|
||||
label={instrument.product.settlementAsset.symbol}
|
||||
/>
|
||||
<div className="relative">
|
||||
{price}
|
||||
</div>
|
||||
{market.candles && (
|
||||
<PriceChange candles={market.candles.map((c) => c.close)} />
|
||||
)}
|
||||
|
||||
<div
|
||||
// absolute so height is not larger than price change value
|
||||
className="absolute right-0 bottom-0 w-[120px]"
|
||||
>
|
||||
{market.candles && (
|
||||
<Sparkline
|
||||
width={120}
|
||||
height={20}
|
||||
data={market.candles.filter(Boolean).map((c) => Number(c.close))}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const DataRow = ({ value, label }: { value: string; label: string }) => {
|
||||
return (
|
||||
<div
|
||||
className="text-ellipsis whitespace-nowrap overflow-hidden leading-tight"
|
||||
data-testid="market-selector-data-row"
|
||||
>
|
||||
<span title={label} className="text-sm mr-1">
|
||||
{value}
|
||||
</span>
|
||||
<span className="text-xs text-vega-light-300 dark:text-vega-light-300">
|
||||
{label}
|
||||
</span>
|
||||
<div className="w-1/2 max-w-[120px]">
|
||||
{market.candles ? (
|
||||
<Sparkline
|
||||
width={120}
|
||||
height={20}
|
||||
data={market.candles.filter(Boolean).map((c) => Number(c.close))}
|
||||
/>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@ import classNames from 'classnames';
|
||||
|
||||
// Make sure these match the available __typename properties on product
|
||||
export const Product = {
|
||||
Future: 'Future',
|
||||
Spot: 'Spot',
|
||||
Future: 'Future',
|
||||
Perpetual: 'Perpetual',
|
||||
} as const;
|
||||
|
||||
@@ -12,8 +12,8 @@ export type ProductType = keyof typeof Product;
|
||||
const ProductTypeMapping: {
|
||||
[key in ProductType]: string;
|
||||
} = {
|
||||
[Product.Future]: 'Futures',
|
||||
[Product.Spot]: 'Spot',
|
||||
[Product.Future]: 'Futures',
|
||||
[Product.Perpetual]: 'Perpetuals',
|
||||
};
|
||||
|
||||
|
||||
@@ -247,7 +247,7 @@ const MainGrid = memo(
|
||||
const navigate = useNavigate();
|
||||
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'top' });
|
||||
const [sizesMiddle, handleOnMiddleLayoutChange] = usePaneLayout({
|
||||
id: 'middle-1',
|
||||
id: 'middle',
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -259,7 +259,27 @@ const MainGrid = memo(
|
||||
onChange={handleOnMiddleLayoutChange}
|
||||
>
|
||||
<ResizableGridPanel
|
||||
preferredSize={sizesMiddle[0] || 330}
|
||||
priority={LayoutPriority.High}
|
||||
minSize={200}
|
||||
preferredSize={sizesMiddle[0] || '50%'}
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-main-left">
|
||||
<Tab id="chart" name={t('Chart')}>
|
||||
<TradingViews.candles.component marketId={marketId} />
|
||||
</Tab>
|
||||
<Tab id="depth" name={t('Depth')}>
|
||||
<TradingViews.depth.component marketId={marketId} />
|
||||
</Tab>
|
||||
<Tab id="liquidity" name={t('Liquidity')}>
|
||||
<TradingViews.liquidity.component marketId={marketId} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
</ResizableGridPanel>
|
||||
<ResizableGridPanel
|
||||
priority={LayoutPriority.Low}
|
||||
preferredSize={sizesMiddle[1] || 330}
|
||||
minSize={300}
|
||||
>
|
||||
<TradeGridChild>
|
||||
@@ -277,25 +297,7 @@ const MainGrid = memo(
|
||||
</TradeGridChild>
|
||||
</ResizableGridPanel>
|
||||
<ResizableGridPanel
|
||||
priority={LayoutPriority.High}
|
||||
minSize={200}
|
||||
preferredSize={sizesMiddle[1] || '50%'}
|
||||
>
|
||||
<TradeGridChild>
|
||||
<Tabs storageKey="console-trade-grid-main-left">
|
||||
<Tab id="chart" name={t('Chart')}>
|
||||
<TradingViews.candles.component marketId={marketId} />
|
||||
</Tab>
|
||||
<Tab id="depth" name={t('Depth')}>
|
||||
<TradingViews.depth.component marketId={marketId} />
|
||||
</Tab>
|
||||
<Tab id="liquidity" name={t('Liquidity')}>
|
||||
<TradingViews.liquidity.component marketId={marketId} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</TradeGridChild>
|
||||
</ResizableGridPanel>
|
||||
<ResizableGridPanel
|
||||
priority={LayoutPriority.Low}
|
||||
preferredSize={sizesMiddle[2] || 430}
|
||||
minSize={200}
|
||||
>
|
||||
@@ -339,31 +341,24 @@ export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
|
||||
return (
|
||||
<div className={wrapperClasses}>
|
||||
<div className="border-b border-r border-default">
|
||||
<div className="h-full flex gap-2 justify-between items-end px-4 pt-1 pb-3">
|
||||
<div className="flex gap-2 justify-between items-center px-4 py-2">
|
||||
<HeaderTitle
|
||||
primaryContent={market?.tradableInstrument.instrument.code}
|
||||
secondaryContent={market?.tradableInstrument.instrument.name}
|
||||
/>
|
||||
<button
|
||||
onClick={() => setSidebarOpen((x) => !x)}
|
||||
className="flex flex-col items-center text-xs w-12"
|
||||
className="p-2"
|
||||
data-testid="sidebar-toggle"
|
||||
>
|
||||
{sidebarOpen ? (
|
||||
<>
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_UP} />
|
||||
<span className="text-vega-light-300 dark:text-vega-dark-300">
|
||||
{t('Close')}
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} />
|
||||
<span className="text-vega-light-300 dark:text-vega-dark-300">
|
||||
{t('Markets')}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<span
|
||||
className={classNames('block', {
|
||||
'rotate-90 translate-x-1': !sidebarOpen,
|
||||
'-rotate-90 -translate-x-1': sidebarOpen,
|
||||
})}
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.CHEVRON_UP} />
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -315,47 +315,39 @@ describe('useMarketSelectorList', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts by state and volume by default', () => {
|
||||
it('sorts albphabetically', () => {
|
||||
const markets = [
|
||||
createMarketFragment({
|
||||
id: 'market-0',
|
||||
state: MarketState.STATE_PENDING,
|
||||
// @ts-ignore candles not on fragment
|
||||
candles: [
|
||||
{
|
||||
volume: '200',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'd',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
createMarketFragment({
|
||||
id: 'market-1',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
// @ts-ignore candles not on fragment
|
||||
candles: [
|
||||
{
|
||||
volume: '200',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'b',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
createMarketFragment({
|
||||
id: 'market-2',
|
||||
state: MarketState.STATE_ACTIVE,
|
||||
// @ts-ignore candles not on fragment
|
||||
candles: [
|
||||
{
|
||||
volume: '100',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'a',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
createMarketFragment({
|
||||
state: MarketState.STATE_PENDING,
|
||||
id: 'market-3',
|
||||
// @ts-ignore candles not on fragment
|
||||
candles: [
|
||||
{
|
||||
volume: '100',
|
||||
tradableInstrument: {
|
||||
instrument: {
|
||||
code: 'c',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -372,10 +364,10 @@ describe('useMarketSelectorList', () => {
|
||||
assets: [],
|
||||
});
|
||||
expect(result.current.markets).toEqual([
|
||||
markets[1],
|
||||
markets[2],
|
||||
markets[0],
|
||||
markets[1],
|
||||
markets[3],
|
||||
markets[0],
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import { useMemo } from 'react';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { calcCandleVolume, useMarketList } from '@vegaprotocol/markets';
|
||||
import { useMarketList } from '@vegaprotocol/markets';
|
||||
import { priceChangePercentage } from '@vegaprotocol/utils';
|
||||
import type { Filter } from './market-selector';
|
||||
import { Sort } from './sort-dropdown';
|
||||
|
||||
// Used for sort order and filter
|
||||
const MARKET_TEMPLATE = [
|
||||
MarketState.STATE_ACTIVE,
|
||||
MarketState.STATE_SUSPENDED,
|
||||
MarketState.STATE_PENDING,
|
||||
];
|
||||
|
||||
export const useMarketSelectorList = ({
|
||||
product,
|
||||
assets,
|
||||
@@ -53,19 +46,7 @@ export const useMarketSelectorList = ({
|
||||
});
|
||||
|
||||
if (sort === Sort.None) {
|
||||
// Sort by market state primarilly and AtoZ secondarilly
|
||||
return orderBy(
|
||||
markets,
|
||||
[
|
||||
(m) => MARKET_TEMPLATE.indexOf(m.state),
|
||||
(m) => {
|
||||
if (!m.candles?.length) return 0;
|
||||
const vol = calcCandleVolume(m.candles);
|
||||
return Number(vol || 0);
|
||||
},
|
||||
],
|
||||
['asc', 'desc']
|
||||
);
|
||||
return orderBy(markets, ['tradableInstrument.instrument.code'], ['asc']);
|
||||
}
|
||||
|
||||
if (sort === Sort.Gained || sort === Sort.Lost) {
|
||||
@@ -97,5 +78,9 @@ export const useMarketSelectorList = ({
|
||||
};
|
||||
|
||||
export const isMarketActive = (state: MarketState) => {
|
||||
return MARKET_TEMPLATE.includes(state);
|
||||
return [
|
||||
MarketState.STATE_ACTIVE,
|
||||
MarketState.STATE_SUSPENDED,
|
||||
MarketState.STATE_PENDING,
|
||||
].includes(state);
|
||||
};
|
||||
|
||||
@@ -315,7 +315,6 @@ const ClosedMarketsDataGrid = ({ rowData }: { rowData: Row[] }) => {
|
||||
getRowId={({ data }) => data.id}
|
||||
defaultColDef={{
|
||||
resizable: true,
|
||||
minWidth: 100,
|
||||
}}
|
||||
overlayNoRowsTemplate="No data"
|
||||
storeKey="closedMarkets"
|
||||
|
||||
@@ -12,7 +12,7 @@ export const Proposed = () => {
|
||||
const externalLink = tokenLink(TOKEN_NEW_MARKET_PROPOSAL);
|
||||
return (
|
||||
<>
|
||||
<div className="h-[400px]">
|
||||
<div className="min-h-[200px]">
|
||||
<ProposalsList />
|
||||
</div>
|
||||
<ExternalLink className="py-4 px-[11px] text-sm" href={externalLink}>
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './announcement-banner';
|
||||
export * from './upgrade-banner';
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import { useMemo, useState } from 'react';
|
||||
import {
|
||||
ReleasesFeed,
|
||||
useEnvironment,
|
||||
useReleases,
|
||||
Networks,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
CopyWithTooltip,
|
||||
ExternalLink,
|
||||
Intent,
|
||||
NotificationBanner,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
const CANONICAL_URL = 'https://vega.trading';
|
||||
|
||||
type UpgradeBannerProps = {
|
||||
showVersionChange: boolean;
|
||||
};
|
||||
export const UpgradeBanner = ({ showVersionChange }: UpgradeBannerProps) => {
|
||||
const [visible, setVisible] = useState(true);
|
||||
const { data } = useReleases(ReleasesFeed.FrontEnd);
|
||||
const { APP_VERSION, VEGA_ENV } = useEnvironment();
|
||||
/**
|
||||
* Filtering out the release candidates.
|
||||
*/
|
||||
const latest = useMemo(() => {
|
||||
const valid =
|
||||
VEGA_ENV === Networks.MAINNET
|
||||
? data?.filter((r) => !/-rc$/i.test(r.tagName))
|
||||
: data;
|
||||
|
||||
return valid && valid.length > 0 ? valid[0] : undefined;
|
||||
}, [VEGA_ENV, data]);
|
||||
|
||||
if (!APP_VERSION) return null;
|
||||
|
||||
if (!visible || !latest || latest.tagName === APP_VERSION) return null;
|
||||
|
||||
const versionChange = (
|
||||
<span>
|
||||
<span className="line-through text-vega-light-300 dark:text-vega-dark-300">
|
||||
{APP_VERSION}
|
||||
</span>{' '}
|
||||
<VegaIcon size={14} name={VegaIconNames.ARROW_RIGHT} />{' '}
|
||||
<span className="text-vega-orange-500 dark:text-vega-yellow-500">
|
||||
<ExternalLink href={latest.htmlUrl}>{latest.tagName}</ExternalLink>
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<NotificationBanner
|
||||
intent={Intent.Warning}
|
||||
onClose={() => {
|
||||
setVisible(false);
|
||||
}}
|
||||
>
|
||||
<div className="uppercase ">
|
||||
{t('Upgrade to the latest version of Console')}{' '}
|
||||
{showVersionChange && versionChange}
|
||||
</div>
|
||||
<div data-testid="bookmark-message">
|
||||
{t('Bookmark')}{' '}
|
||||
<ExternalLink href={CANONICAL_URL}>{t('vega.trading')}</ExternalLink>
|
||||
<CopyWithTooltip text={CANONICAL_URL}>
|
||||
<button title={t('Copy %s', CANONICAL_URL)}>
|
||||
<span className="sr-only">{t('Copy %s', CANONICAL_URL)}</span>
|
||||
<VegaIcon size={14} name={VegaIconNames.COPY} />
|
||||
</button>
|
||||
</CopyWithTooltip>{' '}
|
||||
{'to always see the latest version.'}
|
||||
</div>
|
||||
</NotificationBanner>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
export const THROTTLE_UPDATE_TIME = 500;
|
||||
export const RISK_ACCEPTED_KEY = 'vega_risk_accepted';
|
||||
export const MAINNET_WELCOME_HEADER = t(
|
||||
|
||||
@@ -73,10 +73,10 @@ export const HeaderTitle = ({
|
||||
}) => {
|
||||
return (
|
||||
<div className="text-left" data-testid="header-title">
|
||||
<div className="text-sm md:text-md lg:text-lg whitespace-nowrap !leading-[1]">
|
||||
<div className="text-sm md:text-md lg:text-lg whitespace-nowrap leading-4">
|
||||
{primaryContent}
|
||||
</div>
|
||||
<div className="text-xs whitespace-nowrap text-vega-light-300 dark:text-vega-dark-300">
|
||||
<div className="text-xs whitespace-nowrap text-neutral-500 dark:text-neutral-400">
|
||||
{secondaryContent}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,10 +4,15 @@ export const WalletIcon = ({ className }: { className?: string }) => {
|
||||
width="26"
|
||||
height="18"
|
||||
viewBox="0 0 26 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
data-testid="wallet-icon"
|
||||
>
|
||||
<path d="M4.77437 17.7499H4.74987C3.6504 17.7368 2.77439 16.8489 2.77439 15.7772V12.8495V12.6343L2.5615 12.6023C1.59672 12.4575 0.849609 11.6116 0.849609 10.6266V7.40064C0.849609 6.39018 1.59509 5.56985 2.56147 5.4249L2.77439 5.39297V5.17767V2.24998C2.77439 1.14102 3.66537 0.25 4.77437 0.25H23.7501C24.8591 0.25 25.7501 1.14098 25.7501 2.24998V15.7499C25.7501 16.8588 24.8591 17.7499 23.7501 17.7499H4.77437ZM4.44917 12.5992H4.19917L4.77441 16.075V16.325H4.77466H23.7502C24.0778 16.325 24.3254 16.0777 24.3254 15.7497V2.24984C24.3254 1.9222 24.0782 1.6746 23.7502 1.6746H4.77441C4.44677 1.6746 4.19917 1.92182 4.19917 2.24984V5.12306V5.37306H4.44917H7.0244C8.51139 5.37306 9.67508 6.56094 9.67508 8.02374V9.94852C9.67508 11.4355 8.4872 12.5992 7.0244 12.5992H4.44917ZM2.84963 6.8253C2.52199 6.8253 2.27439 7.07253 2.27439 7.40054V10.6264C2.27439 10.9541 2.52161 11.2017 2.84962 11.2017L7.02419 11.2019C7.73619 11.2019 8.25009 10.6515 8.25009 9.97598V8.0512C8.25009 7.3392 7.69976 6.8253 7.0242 6.8253H2.84963Z" />
|
||||
<path
|
||||
d="M4.77437 17.7499H4.74987C3.6504 17.7368 2.77439 16.8489 2.77439 15.7772V12.8495V12.6343L2.5615 12.6023C1.59672 12.4575 0.849609 11.6116 0.849609 10.6266V7.40064C0.849609 6.39018 1.59509 5.56985 2.56147 5.4249L2.77439 5.39297V5.17767V2.24998C2.77439 1.14102 3.66537 0.25 4.77437 0.25H23.7501C24.8591 0.25 25.7501 1.14098 25.7501 2.24998V15.7499C25.7501 16.8588 24.8591 17.7499 23.7501 17.7499H4.77437ZM4.44917 12.5992H4.19917L4.77441 16.075V16.325H4.77466H23.7502C24.0778 16.325 24.3254 16.0777 24.3254 15.7497V2.24984C24.3254 1.9222 24.0782 1.6746 23.7502 1.6746H4.77441C4.44677 1.6746 4.19917 1.92182 4.19917 2.24984V5.12306V5.37306H4.44917H7.0244C8.51139 5.37306 9.67508 6.56094 9.67508 8.02374V9.94852C9.67508 11.4355 8.4872 12.5992 7.0244 12.5992H4.44917ZM2.84963 6.8253C2.52199 6.8253 2.27439 7.07253 2.27439 7.40054V10.6264C2.27439 10.9541 2.52161 11.2017 2.84962 11.2017L7.02419 11.2019C7.73619 11.2019 8.25009 10.6515 8.25009 9.97598V8.0512C8.25009 7.3392 7.69976 6.8253 7.0242 6.8253H2.84963Z"
|
||||
stroke="none"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -16,11 +16,10 @@ import {
|
||||
NavigationItem,
|
||||
NavigationLink,
|
||||
ExternalLink,
|
||||
Icon,
|
||||
NavigationBreakpoint,
|
||||
NavigationTrigger,
|
||||
NavigationContent,
|
||||
VegaIconNames,
|
||||
VegaIcon,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
@@ -37,8 +36,9 @@ export const Navbar = ({
|
||||
}) => {
|
||||
const { GITHUB_FEEDBACK_URL } = useEnvironment();
|
||||
const tokenLink = useLinks(DApp.Token);
|
||||
const marketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
const { marketId } = useGlobalStore((store) => ({
|
||||
marketId: store.marketId,
|
||||
}));
|
||||
const tradingPath = marketId
|
||||
? Links[Routes.MARKET](marketId)
|
||||
: Links[Routes.MARKET]();
|
||||
@@ -107,14 +107,6 @@ export const Navbar = ({
|
||||
{t('Give Feedback')}
|
||||
</NavExternalLink>
|
||||
</NavigationItem>
|
||||
<NavigationItem>
|
||||
<NavigationLink
|
||||
data-testid="Disclaimer"
|
||||
to={Links[Routes.DISCLAIMER]()}
|
||||
>
|
||||
{t('Disclaimer')}
|
||||
</NavigationLink>
|
||||
</NavigationItem>
|
||||
</NavigationList>
|
||||
</NavigationContent>
|
||||
</NavigationItem>
|
||||
@@ -147,7 +139,7 @@ const NavExternalLink = ({
|
||||
<ExternalLink href={href}>
|
||||
<span className="flex items-center gap-2">
|
||||
<span>{children}</span>
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
<Icon name="arrow-top-right" size={3} />
|
||||
</span>
|
||||
</ExternalLink>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './select-market-columns';
|
||||
export * from './select-market-table';
|
||||
@@ -0,0 +1,344 @@
|
||||
import type { RefObject, MouseEvent } from 'react';
|
||||
import {
|
||||
FeesCell,
|
||||
calcCandleHigh,
|
||||
calcCandleLow,
|
||||
calcCandleVolume,
|
||||
Last24hPriceChange,
|
||||
Last24hVolume,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { PriceCell } from '@vegaprotocol/datagrid';
|
||||
import { Link as UILink, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import isNil from 'lodash/isNil';
|
||||
import type { CandleClose } from '@vegaprotocol/types';
|
||||
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/markets';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { MarketMarkPrice } from '../market-mark-price';
|
||||
import { MarketTradingMode } from '../market-trading-mode';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
|
||||
const ellipsisClasses = 'whitespace-nowrap overflow-hidden text-ellipsis';
|
||||
export const cellClassNames = `py-1 first:text-left text-right ${ellipsisClasses}`;
|
||||
|
||||
const FeesInfo = () => {
|
||||
return (
|
||||
<Tooltip
|
||||
description={
|
||||
<span>
|
||||
{t(
|
||||
'Fees are paid by market takers on aggressive orders only. The fee displayed is made up of:'
|
||||
)}
|
||||
<ul className="list-disc ml-4">
|
||||
<li>{t('An infrastructure fee')}</li>
|
||||
<li>{t('A liquidity provision fee')}</li>
|
||||
<li>{t('A maker fee')}</li>
|
||||
</ul>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<span>{t('Taker fee')}</span>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export enum ColumnKind {
|
||||
Market,
|
||||
LastPrice,
|
||||
Change24,
|
||||
Asset,
|
||||
ProductType,
|
||||
Sparkline,
|
||||
High24,
|
||||
Low24,
|
||||
TradingMode,
|
||||
Volume,
|
||||
Fee,
|
||||
Position,
|
||||
FullName,
|
||||
}
|
||||
|
||||
export interface Column {
|
||||
kind: ColumnKind;
|
||||
value: string | React.ReactNode;
|
||||
className: string;
|
||||
onlyOnDetailed: boolean;
|
||||
dataTestId?: string;
|
||||
}
|
||||
|
||||
const headers: Column[] = [
|
||||
{
|
||||
kind: ColumnKind.Market,
|
||||
value: t('Market'),
|
||||
className: cellClassNames,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.ProductType,
|
||||
value: t('Type'),
|
||||
className: 'py-2 text-left hidden sm:table-cell',
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.LastPrice,
|
||||
value: t('Last price'),
|
||||
className: cellClassNames,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Change24,
|
||||
value: t('Change (24h)'),
|
||||
className: cellClassNames,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Sparkline,
|
||||
value: t(''),
|
||||
className: `${cellClassNames} hidden lg:table-cell`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Asset,
|
||||
value: t('Settlement asset'),
|
||||
className: `${cellClassNames} hidden sm:table-cell`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.High24,
|
||||
value: t('24h High'),
|
||||
className: `${cellClassNames} hidden xl:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Low24,
|
||||
value: t('24h Low'),
|
||||
className: `${cellClassNames} hidden xl:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Volume,
|
||||
value: t('24h Volume'),
|
||||
className: `${cellClassNames} hidden lg:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.TradingMode,
|
||||
value: t('Trading mode'),
|
||||
className: `${cellClassNames} hidden lg:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Fee,
|
||||
value: <FeesInfo />,
|
||||
className: `${cellClassNames} hidden xl:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const columnHeadersPositionMarkets: Column[] = [
|
||||
...headers,
|
||||
{
|
||||
kind: ColumnKind.Position,
|
||||
value: t('Position'),
|
||||
className: `${cellClassNames} hidden xxl:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
];
|
||||
|
||||
export const columnHeaders: Column[] = [
|
||||
...headers,
|
||||
{
|
||||
kind: ColumnKind.FullName,
|
||||
value: t('Full name'),
|
||||
className: `${cellClassNames} hidden xxl:block`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
];
|
||||
|
||||
export type OnCellClickHandler = (
|
||||
e: MouseEvent,
|
||||
kind: ColumnKind,
|
||||
value: string
|
||||
) => void;
|
||||
|
||||
export const columns = (
|
||||
market: MarketMaybeWithDataAndCandles,
|
||||
onSelect: (id: string, metaKey?: boolean) => void,
|
||||
onCellClick: OnCellClickHandler,
|
||||
inViewRoot?: RefObject<HTMLElement>
|
||||
) => {
|
||||
const candlesClose = market.candles
|
||||
?.map((candle) => candle?.close)
|
||||
.filter((c: string | undefined): c is CandleClose => !isNil(c));
|
||||
const candleLow = market.candles && calcCandleLow(market.candles);
|
||||
const candleHigh = market.candles && calcCandleHigh(market.candles);
|
||||
const candleVolume = market.candles && calcCandleVolume(market.candles);
|
||||
|
||||
const selectMarketColumns: Column[] = [
|
||||
{
|
||||
kind: ColumnKind.Market,
|
||||
value: (
|
||||
<Link
|
||||
to={Links[Routes.MARKET](market.id)}
|
||||
data-testid={`market-link-${market.id}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onSelect(market.id, e.metaKey || e.ctrlKey);
|
||||
}}
|
||||
>
|
||||
<UILink>{market.tradableInstrument.instrument.code}</UILink>
|
||||
</Link>
|
||||
),
|
||||
className: `${cellClassNames} max-w-[110px]`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.ProductType,
|
||||
value: market.tradableInstrument.instrument.product.__typename,
|
||||
className: `py-2 text-left hidden sm:table-cell max-w-[50px] ${ellipsisClasses}`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.LastPrice,
|
||||
value: (
|
||||
<MarketMarkPrice
|
||||
marketId={market.id}
|
||||
decimalPlaces={market?.decimalPlaces}
|
||||
initialValue={market.data?.markPrice}
|
||||
inViewRoot={inViewRoot}
|
||||
asPriceCell
|
||||
/>
|
||||
),
|
||||
className: `${cellClassNames} max-w-[100px]`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Change24,
|
||||
value: (
|
||||
<Last24hPriceChange
|
||||
marketId={market.id}
|
||||
decimalPlaces={market?.decimalPlaces}
|
||||
inViewRoot={inViewRoot}
|
||||
initialValue={candlesClose}
|
||||
/>
|
||||
),
|
||||
className: `${cellClassNames} max-w-[150px]`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Sparkline,
|
||||
value: market.candles && (
|
||||
<Sparkline
|
||||
width={100}
|
||||
height={20}
|
||||
muted={false}
|
||||
data={candlesClose?.map((c: string) => Number(c)) || []}
|
||||
/>
|
||||
),
|
||||
className: `${cellClassNames} hidden lg:table-cell max-w-[80px]`,
|
||||
onlyOnDetailed: false && candlesClose,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Asset,
|
||||
value: (
|
||||
<button
|
||||
data-dialog-trigger
|
||||
className="inline underline"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onCellClick(
|
||||
e,
|
||||
ColumnKind.Asset,
|
||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||
);
|
||||
}}
|
||||
>
|
||||
{market.tradableInstrument.instrument.product.settlementAsset.symbol}
|
||||
</button>
|
||||
),
|
||||
dataTestId: 'settlement-asset',
|
||||
className: `${cellClassNames} hidden sm:table-cell max-w-[100px]`,
|
||||
onlyOnDetailed: false,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.High24,
|
||||
value: candleHigh ? (
|
||||
<PriceCell
|
||||
value={Number(candleHigh)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
candleHigh.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
'-'
|
||||
),
|
||||
className: `${cellClassNames} hidden xl:table-cell font-mono`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Low24,
|
||||
value: candleLow ? (
|
||||
<PriceCell
|
||||
value={Number(candleLow)}
|
||||
valueFormatted={addDecimalsFormatNumber(
|
||||
candleLow.toString(),
|
||||
market.decimalPlaces,
|
||||
2
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
'-'
|
||||
),
|
||||
className: `${cellClassNames} hidden xl:table-cell font-mono`,
|
||||
onlyOnDetailed: true,
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Volume,
|
||||
value: (
|
||||
<Last24hVolume
|
||||
marketId={market.id}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
initialValue={candleVolume}
|
||||
inViewRoot={inViewRoot}
|
||||
formatDecimals={2}
|
||||
/>
|
||||
),
|
||||
className: `${cellClassNames} hidden lg:table-cell font-mono`,
|
||||
onlyOnDetailed: true,
|
||||
dataTestId: 'market-volume',
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.TradingMode,
|
||||
value: (
|
||||
<MarketTradingMode
|
||||
marketId={market?.id}
|
||||
inViewRoot={inViewRoot}
|
||||
initialTradingMode={market.tradingMode}
|
||||
initialTrigger={market.data?.trigger}
|
||||
/>
|
||||
),
|
||||
className: `${cellClassNames} hidden lg:table-cell`,
|
||||
onlyOnDetailed: true,
|
||||
dataTestId: 'trading-mode-col',
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.Fee,
|
||||
value: <FeesCell feeFactors={market.fees.factors} />,
|
||||
className: `${cellClassNames} hidden xl:table-cell font-mono`,
|
||||
onlyOnDetailed: true,
|
||||
dataTestId: 'taker-fee',
|
||||
},
|
||||
{
|
||||
kind: ColumnKind.FullName,
|
||||
value: market.tradableInstrument.instrument.name,
|
||||
className: `${cellClassNames} hidden xxl:block`,
|
||||
onlyOnDetailed: true,
|
||||
dataTestId: 'market-name',
|
||||
},
|
||||
];
|
||||
return selectMarketColumns;
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
import { columnHeaders } from './select-market-columns';
|
||||
import classNames from 'classnames';
|
||||
import type { Column } from './select-market-columns';
|
||||
|
||||
export const SelectMarketTableHeader = ({
|
||||
detailed = false,
|
||||
headers = columnHeaders,
|
||||
}) => {
|
||||
return (
|
||||
<tr className="sticky top-0 z-10 border-b border-default bg-inherit">
|
||||
{headers.map(({ kind, value, className, onlyOnDetailed }) => {
|
||||
const thClass = classNames(
|
||||
'font-normal text-neutral-500 dark:text-neutral-400',
|
||||
className
|
||||
);
|
||||
|
||||
if (!onlyOnDetailed || detailed === onlyOnDetailed) {
|
||||
return (
|
||||
<th key={kind} className={thClass}>
|
||||
{value}
|
||||
</th>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
||||
export const SelectMarketTableRow = ({
|
||||
detailed = false,
|
||||
columns,
|
||||
onSelect,
|
||||
marketId,
|
||||
}: {
|
||||
detailed?: boolean;
|
||||
columns: Column[];
|
||||
onSelect: (id: string, metaKey?: boolean) => void;
|
||||
marketId: string;
|
||||
}) => {
|
||||
return (
|
||||
<tr
|
||||
className={`hover:bg-neutral-200 dark:hover:bg-neutral-700 cursor-pointer relative h-[34px]`}
|
||||
onClick={(ev) => {
|
||||
onSelect(marketId, ev.metaKey || ev.ctrlKey);
|
||||
}}
|
||||
data-testid={`market-link-${marketId}`}
|
||||
>
|
||||
{columns.map(({ kind, value, className, dataTestId, onlyOnDetailed }) => {
|
||||
if (!onlyOnDetailed || detailed === onlyOnDetailed) {
|
||||
const tdClass = classNames(className);
|
||||
return (
|
||||
<td key={kind} data-testid={dataTestId} className={tdClass}>
|
||||
{value}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
@@ -53,13 +53,12 @@ const MobileWalletButton = ({
|
||||
setDrawerOpen(!drawerOpen);
|
||||
}
|
||||
}, [drawerOpen, fetchPubKeys, isConnected, openVegaWalletDialog]);
|
||||
console.log(drawerOpen, isYellow);
|
||||
|
||||
const iconClass = drawerOpen
|
||||
? 'hidden'
|
||||
: isYellow
|
||||
? 'fill-black'
|
||||
: 'fill-white';
|
||||
: 'fill-black dark:fill-white';
|
||||
const [container, setContainer] = useState<HTMLElement | null>(null);
|
||||
|
||||
const walletButton = (
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './welcome-dialog';
|
||||
export * from './risk-message';
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
ExternalLink,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
|
||||
export const RiskMessage = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="bg-vega-light-100 dark:bg-vega-dark-100 p-6 mb-6">
|
||||
<ul className="list-[square] ml-4">
|
||||
<li className="mb-1">
|
||||
{t(
|
||||
'Conduct your own due diligence and consult your financial advisor before making any investment decisions.'
|
||||
)}
|
||||
</li>
|
||||
<li className="mb-1">
|
||||
{t(
|
||||
'You may encounter bugs, loss of functionality or loss of assets.'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t('No party accepts any liability for any losses whatsoever.')}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'By using the Vega Console, you acknowledge that you have read and understood the'
|
||||
)}{' '}
|
||||
<ExternalLink
|
||||
href={`/#/${Links[Routes.DISCLAIMER]()}`}
|
||||
className="underline"
|
||||
>
|
||||
<span className="flex items-center gap-1">
|
||||
<span>{t('Vega Console Disclaimer')}</span>
|
||||
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} />
|
||||
</span>
|
||||
</ExternalLink>
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -47,4 +47,25 @@ describe('Risk notice dialog', () => {
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
}
|
||||
);
|
||||
|
||||
it('displays a risk message for mainnet', () => {
|
||||
const introText = 'Regulation may apply to use of this app';
|
||||
const network = Networks.MAINNET;
|
||||
|
||||
// @ts-ignore ignore mock implementation
|
||||
useEnvironment.mockImplementation(() => ({
|
||||
...mockEnvDefinitions,
|
||||
VEGA_ENV: network,
|
||||
}));
|
||||
|
||||
render(<RiskNoticeDialog onClose={mockOnClose} network={network} />);
|
||||
|
||||
expect(screen.getByText(introText)).toBeInTheDocument();
|
||||
|
||||
const button = screen.getByRole('button', {
|
||||
name: 'I understand, Continue',
|
||||
});
|
||||
fireEvent.click(button);
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { RISK_ACCEPTED_KEY } from '../constants';
|
||||
import { TelemetryApproval } from './telemetry-approval';
|
||||
import type { Networks } from '@vegaprotocol/environment';
|
||||
import {
|
||||
Networks,
|
||||
useEnvironment,
|
||||
DocsLinks,
|
||||
ExternalLinks,
|
||||
@@ -28,17 +28,29 @@ export const RiskNoticeDialog = ({ onClose, network }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<TestnetContent network={network} handleAcceptRisk={handleAcceptRisk} />
|
||||
<>
|
||||
{network === Networks.MAINNET ? (
|
||||
<MainnetContent />
|
||||
) : (
|
||||
<TestnetContent network={network} />
|
||||
)}
|
||||
<div className="my-4">
|
||||
<TelemetryApproval
|
||||
helpText={t(
|
||||
'Help identify bugs and improve the service by sharing anonymous usage data. You can change this in your settings at any time.'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleAcceptRisk}>
|
||||
{network === Networks.MAINNET
|
||||
? t('I understand, Continue')
|
||||
: t('Continue')}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const TestnetContent = ({
|
||||
network,
|
||||
handleAcceptRisk,
|
||||
}: {
|
||||
network: Networks;
|
||||
handleAcceptRisk: () => void;
|
||||
}) => {
|
||||
const TestnetContent = ({ network }: { network: Networks }) => {
|
||||
const { GITHUB_FEEDBACK_URL } = useEnvironment();
|
||||
return (
|
||||
<>
|
||||
@@ -76,14 +88,29 @@ const TestnetContent = ({
|
||||
</li>
|
||||
</ul>
|
||||
)}
|
||||
<div className="my-4">
|
||||
<TelemetryApproval
|
||||
helpText={t(
|
||||
'Help identify bugs and improve the service by sharing anonymous usage data. You can change this in your settings at any time.'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleAcceptRisk}>{t('Continue')}</Button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const MainnetContent = () => {
|
||||
return (
|
||||
<>
|
||||
<h4 className="text-xl mb-2 mt-4">
|
||||
{t('Regulation may apply to use of this app')}
|
||||
</h4>
|
||||
<p className="mb-6">
|
||||
{t(
|
||||
'This decentralised application allows you to connect to and use publicly available blockchain services operated by third parties that may include trading, financial products, or other services that may be subject to legal and regulatory restrictions in your jurisdiction. This application is a front end only and does not hold any funds or provide any products or services. It is available to anyone with an internet connection via IPFS and other methods, and the ability to access it does not imply any right to use any services or that it is legal for you to do so. By using this application you accept that it is your responsibility to ensure that your use of the application and any blockchain services accessed through it is compliant with applicable laws and regulations in your jusrisdiction.'
|
||||
)}
|
||||
</p>
|
||||
<h4 className="text-xl mb-2">
|
||||
{t('Technical and financial risk of loss')}
|
||||
</h4>
|
||||
<p className="mb-8">
|
||||
{t(
|
||||
'The public blockchain services accessible via this decentralised application are operated by third parties and may carry significant risks including the potential loss of all funds that you deposit or hold with these services. Technical risks include the risk of loss in the event of the failure or compromise of the public blockchain infrastructure or smart contracts that provide any services you use. Financial risks include but are not limited to losses due to volatility, excessive leverage, low liquidity, and your own lack of understanding of the services you use. By using this decentralised application you accept that it is your responsibility to ensure that you understand any services you use and the technical and financial risks inherent in your use. Do not risk what you cannot afford to lose.'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
|
||||
export const TelemetryApproval = ({ helpText }: { helpText: string }) => {
|
||||
const [isApproved, setIsApproved] = useTelemetryApproval();
|
||||
return (
|
||||
<div className="flex flex-col py-3">
|
||||
<div className="flex flex-col px-2 py-3">
|
||||
<div className="mr-4" role="form">
|
||||
<Checkbox
|
||||
label={<span className="text-lg pl-1">{t('Share usage data')}</span>}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import * as constants from '../constants';
|
||||
|
||||
export const WelcomeDialogHeader = () => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const header =
|
||||
VEGA_ENV === Networks.MAINNET
|
||||
? constants.MAINNET_WELCOME_HEADER
|
||||
: constants.TESTNET_WELCOME_HEADER;
|
||||
return <h1 className="mb-6 p-4 text-center text-2xl">{header}</h1>;
|
||||
};
|
||||
@@ -8,6 +8,7 @@ import { activeMarketsProvider } from '@vegaprotocol/markets';
|
||||
import * as constants from '../constants';
|
||||
import { RiskNoticeDialog } from './risk-notice-dialog';
|
||||
import { WelcomeNoticeDialog } from './welcome-notice-dialog';
|
||||
import { WelcomeLandingDialog } from './welcome-landing-dialog';
|
||||
import { useGlobalStore } from '../../stores';
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { Networks } from '@vegaprotocol/environment';
|
||||
@@ -29,29 +30,24 @@ export const WelcomeDialog = () => {
|
||||
const shouldDisplayWelcomeDialog = useGlobalStore(
|
||||
(store) => store.shouldDisplayWelcomeDialog
|
||||
);
|
||||
|
||||
const isRiskDialogNeeded =
|
||||
riskAccepted !== 'true' &&
|
||||
VEGA_ENV !== Networks.MAINNET &&
|
||||
!('Cypress' in window);
|
||||
|
||||
const isRiskDialogNeeded = riskAccepted !== 'true' && !('Cypress' in window);
|
||||
const isWelcomeDialogNeeded = pathname === '/' || shouldDisplayWelcomeDialog;
|
||||
|
||||
const onCloseDialog = useCallback(() => {
|
||||
update({
|
||||
shouldDisplayWelcomeDialog: isRiskDialogNeeded,
|
||||
});
|
||||
update({ shouldDisplayWelcomeDialog: isRiskDialogNeeded });
|
||||
}, [update, isRiskDialogNeeded]);
|
||||
|
||||
if (isRiskDialogNeeded) {
|
||||
dialogContent = (
|
||||
<RiskNoticeDialog onClose={onCloseDialog} network={VEGA_ENV} />
|
||||
);
|
||||
title = t('Vega Console');
|
||||
title = VEGA_ENV === Networks.MAINNET ? t('WARNING') : t('Vega Console');
|
||||
size = 'medium';
|
||||
} else if (isWelcomeDialogNeeded && data?.length === 0) {
|
||||
dialogContent = <WelcomeNoticeDialog />;
|
||||
onClose = onCloseDialog;
|
||||
} else if (isWelcomeDialogNeeded && (data?.length || 0) > 0) {
|
||||
dialogContent = <WelcomeLandingDialog onClose={onCloseDialog} />;
|
||||
onClose = onCloseDialog;
|
||||
} else {
|
||||
dialogContent = null as React.ReactNode;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { MockedProvider } from '@apollo/client/testing';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type {
|
||||
MarketMaybeWithCandles,
|
||||
MarketMaybeWithData,
|
||||
MarketData,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { SelectMarketLandingTable } from './welcome-landing-dialog';
|
||||
const mockMarketClickHandler = jest.fn();
|
||||
jest.mock('../../lib/hooks/use-market-click-handler', () => ({
|
||||
useMarketClickHandler: () => mockMarketClickHandler,
|
||||
}));
|
||||
|
||||
type Market = MarketMaybeWithCandles & MarketMaybeWithData;
|
||||
type PartialMarket = Partial<
|
||||
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
||||
>;
|
||||
|
||||
const MARKET_A: PartialMarket = {
|
||||
__typename: 'Market',
|
||||
id: '1',
|
||||
decimalPlaces: 2,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
tradableInstrument: {
|
||||
__typename: 'TradableInstrument',
|
||||
instrument: {
|
||||
__typename: 'Instrument',
|
||||
id: '1',
|
||||
code: 'ABCDEF',
|
||||
name: 'ABCDEF 1-Day',
|
||||
product: {
|
||||
__typename: 'Future',
|
||||
quoteName: 'ABCDEF',
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-ABC',
|
||||
name: 'asset-ABC',
|
||||
decimals: 2,
|
||||
symbol: 'ABC',
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
__typename: 'DataSourceSpec',
|
||||
id: 'oracleId',
|
||||
data: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecForSettlementData: {
|
||||
__typename: 'DataSourceSpec',
|
||||
id: 'oracleId',
|
||||
data: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecBinding: {
|
||||
__typename: 'DataSourceSpecToFutureBinding',
|
||||
tradingTerminationProperty: 'trading-termination-property',
|
||||
settlementDataProperty: 'settlement-data-property',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
__typename: 'InstrumentMetadata',
|
||||
tags: ['ABC', 'DEF'],
|
||||
},
|
||||
},
|
||||
},
|
||||
fees: {
|
||||
__typename: 'Fees',
|
||||
factors: {
|
||||
__typename: 'FeeFactors',
|
||||
infrastructureFee: '0.01',
|
||||
liquidityFee: '0.01',
|
||||
makerFee: '0.01',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
__typename: 'MarketData',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '1',
|
||||
},
|
||||
markPrice: '90',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_OPENING,
|
||||
marketState: Schema.MarketState.STATE_PENDING,
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
indicativeVolume: '1000',
|
||||
},
|
||||
candles: [
|
||||
{
|
||||
__typename: 'Candle',
|
||||
high: '100',
|
||||
low: '10',
|
||||
open: '10',
|
||||
close: '80',
|
||||
volume: '1000',
|
||||
periodStart: '2022-11-01T15:49:00Z',
|
||||
},
|
||||
{
|
||||
__typename: 'Candle',
|
||||
high: '10',
|
||||
low: '1',
|
||||
open: '1',
|
||||
close: '100',
|
||||
volume: '1000',
|
||||
periodStart: '2022-11-01T15:50:00Z',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const MARKET_B: PartialMarket = {
|
||||
__typename: 'Market',
|
||||
id: '2',
|
||||
decimalPlaces: 2,
|
||||
positionDecimalPlaces: 0,
|
||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||
tradableInstrument: {
|
||||
__typename: 'TradableInstrument',
|
||||
instrument: {
|
||||
__typename: 'Instrument',
|
||||
id: '2',
|
||||
code: 'XYZ',
|
||||
name: 'XYZ 1-Day',
|
||||
product: {
|
||||
__typename: 'Future',
|
||||
quoteName: 'XYZ',
|
||||
settlementAsset: {
|
||||
__typename: 'Asset',
|
||||
id: 'asset-XYZ',
|
||||
name: 'asset-XYZ',
|
||||
decimals: 2,
|
||||
symbol: 'XYZ',
|
||||
},
|
||||
dataSourceSpecForTradingTermination: {
|
||||
__typename: 'DataSourceSpec',
|
||||
id: 'oracleId',
|
||||
data: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecForSettlementData: {
|
||||
__typename: 'DataSourceSpec',
|
||||
id: 'oracleId',
|
||||
data: {
|
||||
__typename: 'DataSourceDefinition',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceDefinitionExternal',
|
||||
sourceType: {
|
||||
__typename: 'DataSourceSpecConfiguration',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataSourceSpecBinding: {
|
||||
__typename: 'DataSourceSpecToFutureBinding',
|
||||
tradingTerminationProperty: 'trading-termination-property',
|
||||
settlementDataProperty: 'settlement-data-property',
|
||||
},
|
||||
},
|
||||
metadata: {
|
||||
__typename: 'InstrumentMetadata',
|
||||
tags: ['XYZ'],
|
||||
},
|
||||
},
|
||||
},
|
||||
fees: {
|
||||
__typename: 'Fees',
|
||||
factors: {
|
||||
__typename: 'FeeFactors',
|
||||
infrastructureFee: '0.01',
|
||||
liquidityFee: '0.01',
|
||||
makerFee: '0.01',
|
||||
},
|
||||
},
|
||||
data: {
|
||||
__typename: 'MarketData',
|
||||
market: {
|
||||
__typename: 'Market',
|
||||
id: '2',
|
||||
},
|
||||
markPrice: '123.123',
|
||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_OPENING,
|
||||
marketState: Schema.MarketState.STATE_PENDING,
|
||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||
indicativeVolume: '2000',
|
||||
},
|
||||
candles: [
|
||||
{
|
||||
__typename: 'Candle',
|
||||
high: '100',
|
||||
low: '10',
|
||||
open: '10',
|
||||
close: '80',
|
||||
volume: '1000',
|
||||
periodStart: '2022-11-01T15:49:00Z',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
describe('WelcomeLandingDialog', () => {
|
||||
it('should call onSelect callback on SelectMarketLandingTable', () => {
|
||||
const onClose = jest.fn();
|
||||
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<SelectMarketLandingTable
|
||||
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</MemoryRouter>,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
fireEvent.click(screen.getAllByTestId(`market-link-2`)[0]);
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call onClose when metaKey is held', () => {
|
||||
const onClose = jest.fn();
|
||||
|
||||
render(
|
||||
<MemoryRouter>
|
||||
<SelectMarketLandingTable
|
||||
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||
onClose={onClose}
|
||||
/>
|
||||
</MemoryRouter>,
|
||||
{ wrapper: MockedProvider }
|
||||
);
|
||||
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0], {
|
||||
metaKey: true,
|
||||
});
|
||||
expect(mockMarketClickHandler).toHaveBeenCalled();
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
fireEvent.click(screen.getAllByTestId(`market-link-1`)[0]);
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useMarketList } from '@vegaprotocol/markets';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import { Link as UILink, TinyScroll } from '@vegaprotocol/ui-toolkit';
|
||||
import type { OnCellClickHandler } from '../select-market';
|
||||
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/markets';
|
||||
import {
|
||||
ColumnKind,
|
||||
columns,
|
||||
SelectMarketTableHeader,
|
||||
SelectMarketTableRow,
|
||||
} from '../select-market';
|
||||
import { WelcomeDialogHeader } from './welcome-dialog-header';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ProposedMarkets } from './proposed-markets';
|
||||
import { Links, Routes } from '../../pages/client-router';
|
||||
import { useMarketClickHandler } from '../../lib/hooks/use-market-click-handler';
|
||||
|
||||
export const SelectMarketLandingTable = ({
|
||||
markets,
|
||||
onClose,
|
||||
}: {
|
||||
markets: MarketMaybeWithDataAndCandles[] | null;
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const onSelect = useMarketClickHandler();
|
||||
const onSelectMarket = useCallback(
|
||||
(id: string, metaKey?: boolean) => {
|
||||
onSelect(id, metaKey);
|
||||
if (!metaKey) {
|
||||
onClose();
|
||||
}
|
||||
},
|
||||
[onSelect, onClose]
|
||||
);
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
const onCellClick = useCallback<OnCellClickHandler>(
|
||||
(e, kind, value) => {
|
||||
if (value && kind === ColumnKind.Asset) {
|
||||
openAssetDetailsDialog(value, e.target as HTMLElement);
|
||||
}
|
||||
},
|
||||
[openAssetDetailsDialog]
|
||||
);
|
||||
const showProposed = (markets?.length || 0) <= 5;
|
||||
return (
|
||||
<>
|
||||
<TinyScroll
|
||||
className="max-h-[60vh] overflow-x-auto -mr-4 pr-4"
|
||||
data-testid="select-market-list"
|
||||
>
|
||||
<p className="text-neutral-500 dark:text-neutral-400 mb-4">
|
||||
{t('Select a market to get started...')}
|
||||
</p>
|
||||
<table className="text-sm relative h-full min-w-full whitespace-nowrap">
|
||||
<thead className="sticky top-0 z-10 bg-white dark:bg-black">
|
||||
<SelectMarketTableHeader />
|
||||
</thead>
|
||||
<tbody>
|
||||
{markets?.map((market, i) => (
|
||||
<SelectMarketTableRow
|
||||
marketId={market.id}
|
||||
key={i}
|
||||
detailed={false}
|
||||
onSelect={onSelectMarket}
|
||||
columns={columns(market, onSelectMarket, onCellClick)}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</TinyScroll>
|
||||
<div className="mt-4 text-md">
|
||||
<Link
|
||||
to={Links[Routes.MARKETS]()}
|
||||
data-testid="view-market-list-link"
|
||||
onClick={() => onClose()}
|
||||
>
|
||||
<UILink className="text-sm underline">
|
||||
{'Or view full market list'}
|
||||
</UILink>
|
||||
</Link>
|
||||
</div>
|
||||
{showProposed && <ProposedMarkets />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
interface LandingDialogContainerProps {
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export const WelcomeLandingDialog = ({
|
||||
onClose,
|
||||
}: LandingDialogContainerProps) => {
|
||||
const { data, loading, error } = useMarketList();
|
||||
if (error) {
|
||||
return (
|
||||
<div className="flex justify-center items-center">
|
||||
<p className="my-8">{t('Failed to load markets')}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex justify-center items-center">
|
||||
<p className="my-8">{t('Loading...')}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WelcomeDialogHeader />
|
||||
<SelectMarketLandingTable markets={data} onClose={onClose} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
ExternalLinks,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { ProposedMarkets } from './proposed-markets';
|
||||
import { TelemetryApproval } from './telemetry-approval';
|
||||
|
||||
export const WelcomeNoticeDialog = () => {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
@@ -21,30 +20,30 @@ export const WelcomeNoticeDialog = () => {
|
||||
<>
|
||||
<h1
|
||||
data-testid="welcome-notice-title"
|
||||
className="text-2xl uppercase mb-6 text-center font-alpha calt"
|
||||
className="mb-6 p-4 text-center text-2xl"
|
||||
>
|
||||
{t('Welcome to Console')}
|
||||
</h1>
|
||||
<p className="leading-6 mb-4">
|
||||
<p className="leading-6 mb-7">
|
||||
{t(
|
||||
'There are no markets to trade on right now. Trading on Vega is now live, but markets need to pass a governance vote before they can be traded on. In the meantime:'
|
||||
)}
|
||||
</p>
|
||||
<ul className="list-[square] pl-4 mb-4">
|
||||
<ul className="list-[square] pl-7">
|
||||
{isMainnet && (
|
||||
<li className="mb-1">
|
||||
<li>
|
||||
<ExternalLink target="_blank" href={consoleFairgroundLink()}>
|
||||
{t('Try out Console')}
|
||||
</ExternalLink>
|
||||
{t(' on Fairground, our Testnet')}
|
||||
</li>
|
||||
)}
|
||||
<li className="mb-1">
|
||||
<li>
|
||||
<ExternalLink target="_blank" href={tokenLink(TOKEN_PROPOSALS)}>
|
||||
{t('View and vote for proposed markets')}
|
||||
</ExternalLink>
|
||||
</li>
|
||||
<li className="mb-1">
|
||||
<li>
|
||||
<ExternalLink
|
||||
target="_blank"
|
||||
href={tokenLink(TOKEN_NEW_MARKET_PROPOSAL)}
|
||||
@@ -52,19 +51,12 @@ export const WelcomeNoticeDialog = () => {
|
||||
{t('Propose a market')}
|
||||
</ExternalLink>
|
||||
</li>
|
||||
<li className="mb-1">
|
||||
<li>
|
||||
<ExternalLink target="_blank" href={ExternalLinks.BLOG}>
|
||||
{t('Read about the mainnet launch')}
|
||||
</ExternalLink>
|
||||
</li>
|
||||
</ul>
|
||||
{isMainnet && (
|
||||
<TelemetryApproval
|
||||
helpText={t(
|
||||
'Help identify bugs and improve the service by sharing anonymous usage data. You can change this in your settings at any time.'
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<ProposedMarkets />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ import ToastsManager from './toasts-manager';
|
||||
import { HashRouter, useLocation, useSearchParams } from 'react-router-dom';
|
||||
import { Connectors } from '../lib/vega-connectors';
|
||||
import { ViewingBanner } from '../components/viewing-banner';
|
||||
import { AnnouncementBanner, UpgradeBanner } from '../components/banner';
|
||||
import { AnnouncementBanner } from '../components/banner';
|
||||
import { AppLoader, DynamicLoader } from '../components/app-loader';
|
||||
import { Navbar } from '../components/navbar';
|
||||
import { ENV } from '../lib/config';
|
||||
@@ -99,7 +99,6 @@ function AppBody({ Component }: AppProps) {
|
||||
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
|
||||
/>
|
||||
<ViewingBanner />
|
||||
<UpgradeBanner showVersionChange={true} />
|
||||
</div>
|
||||
<main data-testid={location.pathname}>
|
||||
<Component />
|
||||
|
||||
@@ -30,10 +30,6 @@ const LazySettings = dynamic(() => import('../client-pages/settings'), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const LazyDisclaimer = dynamic(() => import('../client-pages/disclaimer'), {
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export enum Routes {
|
||||
HOME = '/',
|
||||
MARKET = '/markets',
|
||||
@@ -41,7 +37,6 @@ export enum Routes {
|
||||
PORTFOLIO = '/portfolio',
|
||||
LIQUIDITY = 'liquidity/:marketId',
|
||||
SETTINGS = 'settings',
|
||||
DISCLAIMER = 'disclaimer',
|
||||
}
|
||||
|
||||
type ConsoleLinks = { [r in Routes]: (...args: string[]) => string };
|
||||
@@ -56,7 +51,6 @@ export const Links: ConsoleLinks = {
|
||||
? trimEnd(`${Routes.LIQUIDITY}/${marketId}`, '/')
|
||||
: Routes.LIQUIDITY,
|
||||
[Routes.SETTINGS]: () => Routes.SETTINGS,
|
||||
[Routes.DISCLAIMER]: () => Routes.DISCLAIMER,
|
||||
};
|
||||
|
||||
const routerConfig: RouteObject[] = [
|
||||
@@ -103,10 +97,6 @@ const routerConfig: RouteObject[] = [
|
||||
path: Routes.SETTINGS,
|
||||
element: <LazySettings />,
|
||||
},
|
||||
{
|
||||
path: Routes.DISCLAIMER,
|
||||
element: <LazyDisclaimer />,
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
element: (
|
||||
|
||||
@@ -12,16 +12,13 @@ import {
|
||||
} from '@vegaprotocol/web3';
|
||||
import { WelcomeDialog } from '../components/welcome-dialog';
|
||||
import { TransferDialog } from '@vegaprotocol/accounts';
|
||||
import { RiskMessage } from '../components/welcome-dialog';
|
||||
|
||||
const DialogsContainer = () => {
|
||||
const { isOpen, id, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||
|
||||
return (
|
||||
<>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
riskMessage={<RiskMessage />}
|
||||
/>
|
||||
<VegaConnectDialog connectors={Connectors} />
|
||||
<AssetDetailsDialog
|
||||
assetId={id}
|
||||
trigger={trigger || null}
|
||||
|
||||
@@ -2,10 +2,9 @@ import { useEffect, useState } from 'react';
|
||||
import type { AppNameType, Announcement } from './schema';
|
||||
import { useAnnouncement } from './hooks/use-announcement';
|
||||
import {
|
||||
Icon,
|
||||
AnnouncementBanner as Banner,
|
||||
ExternalLink,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export type AnnouncementBannerProps = {
|
||||
@@ -76,22 +75,22 @@ export const AnnouncementBanner = ({
|
||||
|
||||
return (
|
||||
<Banner className="relative px-10">
|
||||
<button
|
||||
className="absolute left-0 top-0 w-10 h-full flex items-center justify-center"
|
||||
data-testid="app-announcement-close"
|
||||
onClick={() => setVisible(false)}
|
||||
>
|
||||
<Icon name="cross" className="w-6 h-6" ariaLabel="dismiss" />
|
||||
</button>
|
||||
<div
|
||||
data-testid="app-announcement"
|
||||
className="relative font-alpha flex gap-2 justify-center text-center text-lg text-white"
|
||||
className="relative font-alpha flex gap-2 justify-center calt uppercase text-center text-lg text-white"
|
||||
>
|
||||
<span>{data.text}</span>{' '}
|
||||
<span className="pr-4">{data.text}</span>
|
||||
{data.urlText && data.url && (
|
||||
<ExternalLink href={data.url}>{data.urlText}</ExternalLink>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
className="absolute right-0 top-0 p-4 w-10 h-full flex items-center justify-center text-white"
|
||||
data-testid="app-announcement-close"
|
||||
onClick={() => setVisible(false)}
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.CROSS} size={24} />
|
||||
</button>
|
||||
</Banner>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -60,7 +60,6 @@ export function addVegaWalletConnect() {
|
||||
export function addSetVegaWallet() {
|
||||
Cypress.Commands.add('setVegaWallet', () => {
|
||||
cy.window().then((win) => {
|
||||
win.localStorage.setItem('vega_risk_accepted', 'true');
|
||||
win.localStorage.setItem(
|
||||
'vega_wallet_config',
|
||||
JSON.stringify({
|
||||
|
||||
@@ -6,7 +6,6 @@ import type {
|
||||
} from 'ag-grid-community';
|
||||
import { renderHook, act, waitFor } from '@testing-library/react';
|
||||
import { useColumnSizes } from './use-column-sizes';
|
||||
import * as reactHelpers from '@vegaprotocol/react-helpers';
|
||||
|
||||
const mockApis = {
|
||||
api: {
|
||||
@@ -50,9 +49,6 @@ describe('UseColumnSizes hook', () => {
|
||||
});
|
||||
|
||||
it('onGridSizeChanged should call setSize', async () => {
|
||||
jest
|
||||
.spyOn(reactHelpers, 'useScreenDimensions')
|
||||
.mockReturnValue({ screenSize: 'xxl' });
|
||||
const { result } = renderHook(() =>
|
||||
useColumnSizes({ storeKey, props: {} })
|
||||
);
|
||||
@@ -99,7 +95,6 @@ describe('UseColumnSizes hook', () => {
|
||||
|
||||
it('onGridReady should call setSizes', async () => {
|
||||
const props = { onGridReady: jest.fn() };
|
||||
|
||||
const { result } = renderHook(() => useColumnSizes({ storeKey, props }));
|
||||
const obTest = { cool: 1, ...mockApis };
|
||||
await act(() => {
|
||||
|
||||
@@ -8,7 +8,6 @@ import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const STORAGE_KEY = 'vega_columns_sizes_store';
|
||||
|
||||
@@ -94,12 +93,11 @@ export const useColumnSizes = ({
|
||||
},
|
||||
[valueSetter, storeKey, parentOnColumnResized]
|
||||
);
|
||||
const { screenSize } = useScreenDimensions();
|
||||
const largeScreen = ['xl', 'xxl', 'xxxl'].includes(screenSize);
|
||||
|
||||
const setSizes = useCallback(
|
||||
(apiEvent: GridReadyEvent | GridSizeChangedEvent) => {
|
||||
if (!storeKey || !Object.keys(sizes).length || !widthRef.current) {
|
||||
largeScreen && apiEvent?.api.sizeColumnsToFit();
|
||||
apiEvent?.api.sizeColumnsToFit();
|
||||
} else {
|
||||
const recalculatedSizes = recalculateSizes(sizes);
|
||||
const newSizes = Object.entries(recalculatedSizes).map(
|
||||
@@ -111,7 +109,7 @@ export const useColumnSizes = ({
|
||||
apiEvent.columnApi.setColumnWidths(newSizes);
|
||||
}
|
||||
},
|
||||
[storeKey, recalculateSizes, sizes, largeScreen]
|
||||
[storeKey, recalculateSizes, sizes]
|
||||
);
|
||||
|
||||
const onGridReady = useCallback(
|
||||
|
||||
@@ -304,7 +304,7 @@ export const DealTicket = ({
|
||||
: order.postOnly,
|
||||
expiresAt: undefined,
|
||||
});
|
||||
clearErrors(['expiresAt', 'price']);
|
||||
clearErrors('expiresAt');
|
||||
}}
|
||||
market={market}
|
||||
marketData={marketData}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user