Adjust explorer links (#8772)
* Adjust explorer links * Fix build * Add chart key * title extraction * maxItems * fully loaded
This commit is contained in:
parent
eed5329a8d
commit
3f40bdaf2d
@ -13,14 +13,8 @@
|
||||
--font-sans: 1em "-apple-system", BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
|
||||
/*
|
||||
1.125 (8:9) factor (https://www.modularscale.com/?1&rem&1.067, https://type-scale.com/) -
|
||||
|
||||
1.424rem
|
||||
1.266rem
|
||||
1.125rem
|
||||
1rem
|
||||
0.889rem
|
||||
0.79rem
|
||||
From https://www.modularscale.com/?1&rem&1.125 and https://type-scale.com/ -
|
||||
1.125 (8:9) factor: 1.424rem, 1.266rem, 1.125rem, 1rem, 0.889rem, 0.79rem
|
||||
*/
|
||||
--font-percent-small: 88.9%;
|
||||
--font-percent-tiny: 79.0%;
|
||||
@ -31,7 +25,7 @@
|
||||
--font-size-small: 0.889rem;
|
||||
--font-size-tiny: 0.79rem;
|
||||
|
||||
--font-weight-bold: 700; /* semi-bold = 600 */
|
||||
--font-weight-bold: 600; /* semi */
|
||||
--font-weight-light: 200;
|
||||
--font-weight-normal: 400;
|
||||
|
||||
|
||||
@ -23,7 +23,9 @@ function BlockHeader ({ value }: Props): React.ReactElement<Props> | null {
|
||||
return (
|
||||
<tr>
|
||||
<td className='number'>
|
||||
<Link to={`/explorer/query/${hashHex}`}><span className='--digits'>#{formatNumber(value.number)}</span></Link>
|
||||
<h4 className='--digits'>
|
||||
<Link to={`/explorer/query/${hashHex}`}>{formatNumber(value.number)}</Link>
|
||||
</h4>
|
||||
</td>
|
||||
<td className='all hash overflow'>{hashHex}</td>
|
||||
<td className='address'>
|
||||
|
||||
@ -5,7 +5,6 @@ import type { KeyedEvent } from '@polkadot/react-hooks/ctx/types';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { MarkError, Table } from '@polkadot/react-components';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
@ -15,13 +14,32 @@ import { useTranslation } from './translate';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
error?: Error;
|
||||
error?: Error | null;
|
||||
emptyLabel?: React.ReactNode;
|
||||
events?: KeyedEvent[] | null;
|
||||
eventClassName?: string;
|
||||
label?: React.ReactNode;
|
||||
}
|
||||
|
||||
function renederEvent (className: string | undefined, { blockHash, blockNumber, indexes, key, record }: KeyedEvent): React.ReactNode {
|
||||
return (
|
||||
<tr
|
||||
className={className}
|
||||
key={key}
|
||||
>
|
||||
<td className='overflow relative'>
|
||||
<Event value={record} />
|
||||
{blockNumber && (
|
||||
<div className='absolute --digits'>
|
||||
{indexes.length !== 1 && <span>{formatNumber(indexes.length)}x </span>}
|
||||
<Link to={`/explorer/query/${blockHash || ''}`}>{formatNumber(blockNumber)}-{indexes[0].toString().padStart(2, '0')}</Link>
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
function Events ({ className = '', emptyLabel, error, eventClassName, events, label }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -47,35 +65,10 @@ function Events ({ className = '', emptyLabel, error, eventClassName, events, la
|
||||
<td><MarkError content={t<string>('Unable to decode the block events. {{error}}', { replace: { error: error.message } })} /></td>
|
||||
</tr>
|
||||
)
|
||||
: events && events.map(({ blockHash, blockNumber, indexes, key, record }): React.ReactNode => (
|
||||
<tr
|
||||
className={eventClassName}
|
||||
key={key}
|
||||
>
|
||||
<td className='overflow'>
|
||||
<Event value={record} />
|
||||
{blockNumber && (
|
||||
<div className='event-link'>
|
||||
{indexes.length !== 1 && <span>({formatNumber(indexes.length)}x) </span>}
|
||||
<Link to={`/explorer/query/${blockHash || ''}`}>{formatNumber(blockNumber)}-{indexes[0]}</Link>
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))
|
||||
: events && events.map((e) => renederEvent(eventClassName, e))
|
||||
}
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(styled(Events)`
|
||||
td.overflow {
|
||||
position: relative;
|
||||
|
||||
.event-link {
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
}
|
||||
`);
|
||||
export default React.memo(Events);
|
||||
|
||||
@ -93,24 +93,33 @@ function formatTime (time: number, divisor = 1000): React.ReactNode {
|
||||
|
||||
function Latency ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { details, stdDev, timeAvg, timeMax, timeMin } = useLatency();
|
||||
const { details, maxItems, stdDev, timeAvg, timeMax, timeMin } = useLatency();
|
||||
|
||||
const { blockLast, blocks, events, extrinsics, times } = useMemo(
|
||||
const points = useMemo(
|
||||
() => getPoints(details, timeAvg),
|
||||
[details, timeAvg]
|
||||
);
|
||||
|
||||
const { blocksLegend, eventsLegend, extrinsicsLegend, timesLegend } = useMemo(
|
||||
() => ({
|
||||
blocksLegend: [t<string>('bytes'), t<string>('average')],
|
||||
eventsLegend: [t<string>('events'), t<string>('system'), t<string>('average')],
|
||||
extrinsicsLegend: [t<string>('extrinsics'), t<string>('average')],
|
||||
timesLegend: [t<string>('blocktime'), t<string>('average')]
|
||||
}), [t]
|
||||
const [legend, title] = useMemo(
|
||||
() => [
|
||||
{
|
||||
blocks: [t<string>('bytes'), t<string>('average')],
|
||||
events: [t<string>('events'), t<string>('system'), t<string>('average')],
|
||||
extrinsics: [t<string>('extrinsics'), t<string>('average')],
|
||||
times: [t<string>('blocktime'), t<string>('average')]
|
||||
},
|
||||
{
|
||||
blocks: t<string>('blocksize (last {{n}} blocks)', { replace: { n: maxItems } }),
|
||||
events: t<string>('events (last {{n}} blocks)', { replace: { n: maxItems } }),
|
||||
extrinsics: t<string>('extrinsics (last {{n}} blocks)', { replace: { n: maxItems } }),
|
||||
times: t<string>('blocktimes (last {{n}} blocks)', { replace: { n: maxItems } })
|
||||
}
|
||||
],
|
||||
[maxItems, t]
|
||||
);
|
||||
|
||||
const isLoaded = details.length > 2;
|
||||
const EMPTY_TIME = <span className='--tmp --digits'>0.000 s</span>;
|
||||
const isLoaded = details.length === maxItems;
|
||||
const EMPTY_TIME = <span className='--tmp --digits'>0.000 <span className='postfix'>s</span></span>;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
@ -145,38 +154,42 @@ function Latency ({ className }: Props): React.ReactElement<Props> {
|
||||
</section>
|
||||
<CardSummary label={t<string>('last')}>
|
||||
{isLoaded
|
||||
? formatTime(blockLast, 1)
|
||||
? formatTime(points.blockLast, 1)
|
||||
: EMPTY_TIME}
|
||||
</CardSummary>
|
||||
</SummaryBox>
|
||||
{isLoaded
|
||||
? (
|
||||
<>
|
||||
<div key='charts'>
|
||||
<Chart
|
||||
colors={COLORS_TIMES}
|
||||
legends={timesLegend}
|
||||
title={t<string>('blocktimes (last {{num}} blocks)', { replace: { num: times.labels.length } })}
|
||||
value={times}
|
||||
key='times'
|
||||
legends={legend.times}
|
||||
title={title.times}
|
||||
value={points.times}
|
||||
/>
|
||||
<Chart
|
||||
colors={COLORS_BLOCKS}
|
||||
legends={blocksLegend}
|
||||
title={t<string>('blocksize (last {{num}} blocks)', { replace: { num: blocks.labels.length } })}
|
||||
value={blocks}
|
||||
key='blocks'
|
||||
legends={legend.blocks}
|
||||
title={title.blocks}
|
||||
value={points.blocks}
|
||||
/>
|
||||
<Chart
|
||||
colors={COLORS_TXS}
|
||||
legends={extrinsicsLegend}
|
||||
title={t<string>('extrinsics (last {{num}} blocks)', { replace: { num: extrinsics.labels.length } })}
|
||||
value={extrinsics}
|
||||
key='extrinsics'
|
||||
legends={legend.extrinsics}
|
||||
title={title.extrinsics}
|
||||
value={points.extrinsics}
|
||||
/>
|
||||
<Chart
|
||||
colors={COLORS_EVENTS}
|
||||
legends={eventsLegend}
|
||||
title={t<string>('events (last {{num}} blocks)', { replace: { num: events.labels.length } })}
|
||||
value={events}
|
||||
key='events'
|
||||
legends={legend.events}
|
||||
title={title.events}
|
||||
value={points.events}
|
||||
/>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
: <Spinner />
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ export interface Detail {
|
||||
|
||||
export interface Result {
|
||||
details: Detail[];
|
||||
maxItems: number;
|
||||
stdDev: number;
|
||||
timeAvg: number;
|
||||
timeMax: number;
|
||||
|
||||
@ -15,6 +15,7 @@ const INITIAL_ITEMS = 50;
|
||||
const MAX_ITEMS = INITIAL_ITEMS;
|
||||
const EMPTY: Result = {
|
||||
details: [],
|
||||
maxItems: MAX_ITEMS,
|
||||
stdDev: 0,
|
||||
timeAvg: 0,
|
||||
timeMax: 0,
|
||||
@ -171,6 +172,7 @@ function useLatencyImpl (): Result {
|
||||
|
||||
return {
|
||||
details,
|
||||
maxItems: MAX_ITEMS,
|
||||
stdDev,
|
||||
timeAvg,
|
||||
timeMax: Math.max(...delays),
|
||||
|
||||
@ -512,6 +512,10 @@ export default createGlobalStyle<Props & ThemeProps>(({ theme, uiHighlight }: Pr
|
||||
font-size: var(--font-size-h3);
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: var(--font-size-h4);
|
||||
}
|
||||
|
||||
header {
|
||||
margin-bottom: 1.5rem;
|
||||
text-align: center;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user