Slight latency chart additions (for any expansions) (#8779)

* Slight latency chart additions (for any expansions)

* s/icompleted/isLoaded/

* Adjust peers displayAdjust with loading

* No peer info

* Fix NodeInfo initial refresh
This commit is contained in:
Jaco 2023-01-13 08:35:31 +02:00 committed by GitHub
parent 1b351985e1
commit ea9f6e0887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 53 additions and 30 deletions

View File

@ -97,29 +97,24 @@ function formatTime (time: number, divisor = 1000): React.ReactNode {
function Latency ({ className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { details, maxItems, stdDev, timeAvg, timeMax, timeMin } = useLatency();
const [renderOrder, setRenderOrder] = useState([false, false, false, false]);
const isLoaded = useMemo(
() => details.length === maxItems,
[details, maxItems]
);
const { details, isLoaded, maxItems, stdDev, timeAvg, timeMax, timeMin } = useLatency();
const [shouldRender, setShouldRender] = useState(() => new Array<boolean>(ORDER.length).fill(false));
useEffect((): void => {
// HACK try and render the charts in order - this _may_ work around the
// crosshair plugin init issues, but at best it is non-reproducable
if (isLoaded) {
const index = renderOrder.findIndex((v) => !v);
const index = shouldRender.findIndex((v) => !v);
if (index !== -1) {
nextTick(() =>
setRenderOrder(
renderOrder.map((v, i) => (i === index) || v)
setShouldRender(
shouldRender.map((v, i) => (i === index) || v)
)
);
}
}
}, [isLoaded, renderOrder]);
}, [isLoaded, shouldRender]);
const points = useMemo(
() => getPoints(details, timeAvg),
@ -185,7 +180,7 @@ function Latency ({ className }: Props): React.ReactElement<Props> {
</SummaryBox>
{isLoaded
? ORDER.map((key, i) =>
renderOrder[i] && (
shouldRender[i] && (
<Chart
colors={COLORS[key]}
key={key}

View File

@ -23,6 +23,7 @@ export interface Detail {
export interface Result {
details: Detail[];
isLoaded: boolean;
maxItems: number;
stdDev: number;
timeAvg: number;

View File

@ -15,6 +15,7 @@ const INITIAL_ITEMS = 50;
const MAX_ITEMS = INITIAL_ITEMS;
const EMPTY: Result = {
details: [],
isLoaded: false,
maxItems: MAX_ITEMS,
stdDev: 0,
timeAvg: 0,
@ -172,6 +173,7 @@ function useLatencyImpl (): Result {
return {
details,
isLoaded: details.length === MAX_ITEMS,
maxItems: MAX_ITEMS,
stdDev,
timeAvg,

View File

@ -3,11 +3,11 @@
import type { PeerInfo } from '@polkadot/types/interfaces';
import React, { useRef } from 'react';
import React, { useMemo, useRef } from 'react';
import styled from 'styled-components';
import { Table } from '@polkadot/react-components';
import { formatNumber } from '@polkadot/util';
import { formatNumber, stringPascalCase } from '@polkadot/util';
import { useTranslation } from '../translate';
@ -16,28 +16,45 @@ interface Props {
peers?: PeerInfo[] | null;
}
function sortPeers (peers: PeerInfo[]) {
return peers
.map(({ bestHash, bestNumber, peerId, roles }) => ({
bestHash: bestHash.toHex(),
bestNumber,
peerId: peerId.toString(),
roles: stringPascalCase(roles)
}))
.sort((a, b) => a.peerId.localeCompare(b.peerId))
.sort((a, b) => a.roles.localeCompare(b.roles))
.sort((a, b) => b.bestNumber.cmp(a.bestNumber));
}
function Peers ({ className = '', peers }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const headerRef = useRef<([React.ReactNode?, string?, number?] | false)[]>([
[t('connected peers'), 'start'],
[t('role'), 'start'],
[t('best #'), 'number'],
[t('best hash'), 'hash']
[t('connected peers'), 'start', 2],
[t('best hash'), 'start'],
[t('best #'), 'number']
]);
const sorted = useMemo(
() => peers && sortPeers(peers),
[peers]
);
return (
<Table
className={className}
empty={t<string>('no peers connected')}
header={headerRef.current}
>
{peers?.sort((a, b): number => b.bestNumber.cmp(a.bestNumber)).map((peer) => (
<tr key={peer.peerId.toString()}>
<td className='hash'>{peer.peerId.toString()}</td>
<td>{peer.roles.toString().toLowerCase()}</td>
<td className='number all'>{formatNumber(peer.bestNumber)}</td>
<td className='hash'>{peer.bestHash.toHex()}</td>
{sorted?.map(({ bestHash, bestNumber, peerId, roles }) => (
<tr key={peerId}>
<td className='roles'>{roles}</td>
<td className='hash overflow'>{peerId}</td>
<td className='hash overflow'>{bestHash}</td>
<td className='number bestNumber'>{formatNumber(bestNumber)}</td>
</tr>
))}
</Table>
@ -46,4 +63,14 @@ function Peers ({ className = '', peers }: Props): React.ReactElement<Props> {
export default React.memo(styled(Peers)`
overflow-x: auto;
td.roles {
max-width: 9ch;
width: 9ch;
}
td.bestNumber {
max-width: 11ch;
width: 11ch;
}
`);

View File

@ -37,16 +37,14 @@ function NodeInfo (): React.ReactElement {
const [nextRefresh, setNextRefresh] = useState(() => Date.now());
useEffect((): () => void => {
const _getStatus = (): void => {
const getStatus = (): void => {
setNextRefresh(Date.now() + POLL_TIMEOUT);
retrieveInfo(api).then(setInfo).catch(console.error);
};
_getStatus();
getStatus();
const timerId = window.setInterval((): void => {
setNextRefresh(Date.now() + POLL_TIMEOUT);
_getStatus();
}, POLL_TIMEOUT);
const timerId = window.setInterval(getStatus, POLL_TIMEOUT);
return (): void => {
window.clearInterval(timerId);