fix(explorer): fix resizing callout (#2492)

* fix(explorer): prevent layout thrashing on stats page
This commit is contained in:
Edd 2022-12-30 11:40:47 +00:00 committed by GitHub
parent ee6f26d473
commit f8eec8a056
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 35 additions and 117 deletions

View File

@ -4,6 +4,7 @@ NX_TENDERMINT_URL=https://n04.d.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://n04.d.vega.xyz/tm/websocket
NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql NX_VEGA_URL=https://api.n04.d.vega.xyz/graphql
NX_VEGA_ENV=DEVNET NX_VEGA_ENV=DEVNET
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
# App flags # App flags
NX_EXPLORER_ASSETS=1 NX_EXPLORER_ASSETS=1

View File

@ -4,6 +4,7 @@ NX_TENDERMINT_URL=https://mainnet-observer-proxy01.ops.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://mainnet-observer-proxy01.ops.vega.xyz/websocket
NX_VEGA_URL=https://api.vega.xyz/query NX_VEGA_URL=https://api.vega.xyz/query
NX_VEGA_ENV=MAINNET NX_VEGA_ENV=MAINNET
NX_BLOCK_EXPLORER=https://be.explorer.vega.xyz/rest
# App flags # App flags
NX_EXPLORER_ASSETS=1 NX_EXPLORER_ASSETS=1

View File

@ -4,6 +4,7 @@ NX_TENDERMINT_URL=https://tm.n00.stagnet3.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n00.stagnet3.vega.xyz/websocket
NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql NX_VEGA_URL=https://api.stagnet3.vega.xyz/graphql
NX_VEGA_ENV=STAGNET3 NX_VEGA_ENV=STAGNET3
NX_BLOCK_EXPLORER=https://be.stagnet3.vega.xyz/rest
# App flags # App flags
NX_EXPLORER_ASSETS=1 NX_EXPLORER_ASSETS=1

View File

@ -4,6 +4,7 @@ NX_TENDERMINT_URL=https://tm.n07.testnet.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
NX_VEGA_ENV=TESTNET NX_VEGA_ENV=TESTNET
NX_BLOCK_EXPLORER=https://be.testnet.vega.xyz/rest
# App flags # App flags
NX_EXPLORER_ASSETS=1 NX_EXPLORER_ASSETS=1

View File

@ -52,7 +52,8 @@ context('Blocks page', { tags: '@regression' }, function () {
}); });
}); });
it('Previous button disabled on first block', function () { // Skipping - see https://github.com/vegaprotocol/frontend-monorepo/issues/2494
it.skip('Previous button disabled on first block', function () {
cy.get('[data-testid="block-input"]').type('1'); cy.get('[data-testid="block-input"]').type('1');
cy.get('[data-testid="go-submit"]').click(); cy.get('[data-testid="go-submit"]').click();
cy.get(previousBlockBtn).find('button').should('be.disabled'); cy.get(previousBlockBtn).find('button').should('be.disabled');

View File

@ -20,19 +20,18 @@ context('Home Page', function () {
1: 'Height', 1: 'Height',
2: 'Uptime', 2: 'Uptime',
3: 'Total nodes', 3: 'Total nodes',
4: 'Inactive nodes', 4: 'Total staked',
5: 'Total staked', 5: 'Backlog',
6: 'Backlog', 6: 'Trades / second',
7: 'Trades / second', 7: 'Orders / block',
8: 'Orders / block', 8: 'Orders / second',
9: 'Orders / second', 9: 'Transactions / block',
10: 'Transactions / block', 10: 'Block time',
11: 'Block time', 11: 'Time',
12: 'Time', 12: 'App',
13: 'App', 13: 'Tendermint',
14: 'Tendermint', 14: 'Up since',
15: 'Up since', 15: 'Chain ID',
16: 'Chain ID',
}; };
cy.get('[data-testid="stats-title"]') cy.get('[data-testid="stats-title"]')
@ -40,7 +39,7 @@ context('Home Page', function () {
cy.wrap($list).should('have.text', statTitles[index]); cy.wrap($list).should('have.text', statTitles[index]);
}) })
.then(($list) => { .then(($list) => {
cy.wrap($list).should('have.length', 17); cy.wrap($list).should('have.length', 16);
}); });
cy.get(statsValue).eq(0).should('have.text', 'CONNECTED'); cy.get(statsValue).eq(0).should('have.text', 'CONNECTED');
@ -50,30 +49,29 @@ context('Home Page', function () {
.invoke('text') .invoke('text')
.should('match', /\d+d \d+h \d+m \d+s/i); .should('match', /\d+d \d+h \d+m \d+s/i);
cy.get(statsValue).eq(3).should('have.text', '2'); cy.get(statsValue).eq(3).should('have.text', '2');
cy.get(statsValue).eq(4).should('have.text', '2');
cy.get(statsValue) cy.get(statsValue)
.eq(5) .eq(4)
.invoke('text') .invoke('text')
.should('match', /\d+\.\d\d(?!\d)/i); .should('match', /\d+\.\d\d(?!\d)/i);
cy.get(statsValue).eq(5).should('have.text', '0');
cy.get(statsValue).eq(6).should('have.text', '0'); cy.get(statsValue).eq(6).should('have.text', '0');
cy.get(statsValue).eq(7).should('have.text', '0'); cy.get(statsValue).eq(7).should('have.text', '0');
cy.get(statsValue).eq(8).should('have.text', '0'); cy.get(statsValue).eq(8).should('have.text', '0');
cy.get(statsValue).eq(9).should('have.text', '0'); cy.get(statsValue).eq(9).should('not.be.empty');
cy.get(statsValue).eq(10).should('not.be.empty'); cy.get(statsValue).eq(10).should('not.be.empty');
cy.get(statsValue).eq(11).should('not.be.empty'); cy.get(statsValue).eq(11).should('not.be.empty');
cy.get(statsValue).eq(12).should('not.be.empty');
if (Cypress.env('NIGHTLY_RUN') != true) { if (Cypress.env('NIGHTLY_RUN') != true) {
cy.get(statsValue) cy.get(statsValue)
.eq(13) .eq(12)
.invoke('text') .invoke('text')
.should('match', /v\d+\.\d+\.\d+/i); .should('match', /v\d+\.\d+\.\d+/i);
} }
cy.get(statsValue) cy.get(statsValue)
.eq(14) .eq(13)
.invoke('text') .invoke('text')
.should('match', /\d+\.\d+\.\d+/i); .should('match', /\d+\.\d+\.\d+/i);
cy.get(statsValue).eq(14).should('not.be.empty');
cy.get(statsValue).eq(15).should('not.be.empty'); cy.get(statsValue).eq(15).should('not.be.empty');
cy.get(statsValue).eq(16).should('not.be.empty');
}); });
it('Block height should be updating', function () { it('Block height should be updating', function () {

View File

@ -2,4 +2,3 @@ export { TxList } from './tx-list';
export { TxOrderType } from './tx-order-type'; export { TxOrderType } from './tx-order-type';
export { TxsInfiniteList } from './txs-infinite-list'; export { TxsInfiniteList } from './txs-infinite-list';
export { TxsInfiniteListItem } from './txs-infinite-list-item'; export { TxsInfiniteListItem } from './txs-infinite-list-item';
export { TxsStatsInfo } from './txs-stats-info';

View File

@ -1,77 +0,0 @@
import { t } from '@vegaprotocol/react-helpers';
import { useEffect } from 'react';
import { InfoBlock } from '../../components/info-block';
import { Panel } from '../../components/panel';
import { useExplorerStatsQuery } from './__generated__/Explorer-stats';
import type { ExplorerStatsFieldsFragment } from './__generated__/Explorer-stats';
interface StatsMap {
field: keyof ExplorerStatsFieldsFragment;
label: string;
info: string;
}
export const TXS_STATS_MAP: StatsMap[] = [
{
field: 'averageOrdersPerBlock',
label: t('Orders per block'),
info: t(
'Number of new orders processed in the last block. All orders derived from pegged orders and liquidity commitments count as a single order'
),
},
{
field: 'txPerBlock',
label: t('Transactions per block'),
info: t('Number of transactions processed in the last block'),
},
{
field: 'tradesPerSecond',
label: t('Trades per second'),
info: t('Number of trades processed in the last second'),
},
{
field: 'ordersPerSecond',
label: t('Order per second'),
info: t(
'Number of orders processed in the last second. All orders derived from pegged orders and liquidity commitments count as a single order'
),
},
];
interface TxsStatsInfoProps {
className?: string;
}
export const TxsStatsInfo = ({ className }: TxsStatsInfoProps) => {
const { data, startPolling, stopPolling } = useExplorerStatsQuery();
useEffect(() => {
startPolling(1000);
return () => stopPolling();
});
const gridStyles =
'grid grid-rows-2 gap-4 grid-cols-2 xl:gap-8 xl:grid-rows-1 xl:grid-cols-4';
return (
<Panel className={className}>
<section className={gridStyles}>
{TXS_STATS_MAP.map((field) => {
if (!data?.statistics) {
return null;
}
// Workaround for awkward typing
const title = data.statistics[field.field] || '';
return (
<InfoBlock
subtitle={field.label}
tooltipInfo={field.info}
title={title}
/>
);
})}
</section>
</Panel>
);
};

View File

@ -1,7 +1,7 @@
import { t } from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers';
import { RouteTitle } from '../../../components/route-title'; import { RouteTitle } from '../../../components/route-title';
import { BlocksRefetch } from '../../../components/blocks'; import { BlocksRefetch } from '../../../components/blocks';
import { TxsInfiniteList, TxsStatsInfo } from '../../../components/txs'; import { TxsInfiniteList } from '../../../components/txs';
import { useTxsData } from '../../../hooks/use-txs-data'; import { useTxsData } from '../../../hooks/use-txs-data';
import { useDocumentTitle } from '../../../hooks/use-document-title'; import { useDocumentTitle } from '../../../hooks/use-document-title';
@ -16,7 +16,6 @@ export const TxsList = () => {
<section className="md:p-2 lg:p-4 xl:p-6"> <section className="md:p-2 lg:p-4 xl:p-6">
<RouteTitle>{t('Transactions')}</RouteTitle> <RouteTitle>{t('Transactions')}</RouteTitle>
<BlocksRefetch refetch={refreshTxs} /> <BlocksRefetch refetch={refreshTxs} />
<TxsStatsInfo className="!my-12 py-8" />
<TxsInfiniteList <TxsInfiniteList
hasMoreTxs={hasMoreTxs} hasMoreTxs={hasMoreTxs}
areTxsLoading={loading} areTxsLoading={loading}

View File

@ -31,7 +31,7 @@ const compileData = (data?: StatsQuery) => {
value.forEach((x) => { value.forEach((x) => {
const stat = { const stat = {
...x, ...x,
value: statData, value: statData || '-',
}; };
stat.promoted ? acc.promoted.push(stat) : acc.table.push(stat); stat.promoted ? acc.promoted.push(stat) : acc.table.push(stat);
@ -75,7 +75,7 @@ export const StatsManager = ({ className }: StatsManagerProps) => {
return ( return (
<PromotedStatsItem <PromotedStatsItem
title={stat.title} title={stat.title}
value={stat.value} value={stat.value || '-'}
formatter={stat.formatter} formatter={stat.formatter}
goodThreshold={stat.goodThreshold} goodThreshold={stat.goodThreshold}
description={stat.description} description={stat.description}
@ -92,7 +92,7 @@ export const StatsManager = ({ className }: StatsManagerProps) => {
return ( return (
<TableRow <TableRow
title={stat.title} title={stat.title}
value={stat.value} value={stat.value || '-'}
formatter={stat.formatter} formatter={stat.formatter}
goodThreshold={stat.goodThreshold} goodThreshold={stat.goodThreshold}
description={stat.description} description={stat.description}

View File

@ -48,13 +48,7 @@ export const statsFields: { [key in keyof Stats]: StatFields[] } = {
description: t('The total number of nodes registered on the network'), description: t('The total number of nodes registered on the network'),
}, },
], ],
inactiveNodes: [ inactiveNodes: [],
{
title: t('Inactive nodes'),
goodThreshold: (totalInactive: number) => totalInactive < 1,
description: t('Nodes that are registered but not validating'),
},
],
stakedTotal: [ stakedTotal: [
{ {
title: t('Total staked'), title: t('Total staked'),
@ -174,11 +168,11 @@ export const statsFields: { [key in keyof Stats]: StatFields[] } = {
title: t('Uptime'), title: t('Uptime'),
formatter: (t: string) => { formatter: (t: string) => {
if (!t) { if (!t) {
return; return '-';
} }
const date = new Date(t); const date = new Date(t);
if (!isValidDate(date)) { if (!isValidDate(date)) {
return; return '-';
} }
const secSinceStart = (new Date().getTime() - date.getTime()) / 1000; const secSinceStart = (new Date().getTime() - date.getTime()) / 1000;
const days = Math.floor(secSinceStart / 60 / 60 / 24); const days = Math.floor(secSinceStart / 60 / 60 / 24);
@ -194,13 +188,13 @@ export const statsFields: { [key in keyof Stats]: StatFields[] } = {
title: t('Up since'), title: t('Up since'),
formatter: (t: string) => { formatter: (t: string) => {
if (!t) { if (!t) {
return; return '-';
} }
const date = new Date(t); const date = new Date(t);
if (!isValidDate(date)) { if (!isValidDate(date)) {
return; return '-';
} }
return getDateTimeFormat().format(date); return getDateTimeFormat().format(date) || '-';
}, },
description: t('Genesis'), description: t('Genesis'),
}, },