Block explorer expanded (#801)

* Add extrinsic hash to detail display

* Move BlockByHash -> ByHash

* Query block by number

* isEmpty check fro block and header
This commit is contained in:
Jaco Greeff 2019-03-12 13:02:39 +01:00 committed by GitHub
parent e7eb08851f
commit e6bced1d9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 113 additions and 41 deletions

View File

@ -36,7 +36,7 @@ export default class BlockHeader extends React.PureComponent<Props> {
<div className='header'>
<div className='number'>{
withLink
? <Link to={`/explorer/hash/${hashHex}`}>{textNumber}</Link>
? <Link to={`/explorer/query/${hashHex}`}>{textNumber}</Link>
: textNumber
}&nbsp;</div>
<div className='hash'>{hashHex}</div>
@ -65,7 +65,7 @@ export default class BlockHeader extends React.PureComponent<Props> {
<label>parentHash</label>
<div className='hash'>{
blockNumber.gtn(1)
? <Link to={`/explorer/hash/${parentHex}`}>{parentHex}</Link>
? <Link to={`/explorer/query/${parentHex}`}>{parentHex}</Link>
: parentHex
}</div>
</div>

View File

@ -26,7 +26,7 @@ class BlockByHash extends React.PureComponent<Props> {
render () {
const { system_events, chain_getBlock, chain_getHeader } = this.props;
if (!chain_getBlock || !chain_getHeader) {
if (!chain_getBlock || chain_getBlock.isEmpty || !chain_getHeader || chain_getHeader.isEmpty) {
return null;
}

View File

@ -0,0 +1,34 @@
// Copyright 2017-2019 @polkadot/app-explorer authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiProps } from '@polkadot/ui-api/types';
import React from 'react';
import { Hash } from '@polkadot/types';
import { withCalls } from '@polkadot/ui-api/index';
import BlockByHash from './ByHash';
type Props = ApiProps & {
chain_getBlockHash?: Hash,
value: string
};
class BlockByNumber extends React.PureComponent<Props> {
render () {
const { chain_getBlockHash } = this.props;
if (!chain_getBlockHash) {
return null;
}
return (
<BlockByHash value={chain_getBlockHash.toHex()} />
);
}
}
export default withCalls<Props>(
['rpc.chain.getBlockHash', { paramName: 'value' }]
)(BlockByNumber);

View File

@ -11,11 +11,12 @@ import { isHex } from '@polkadot/util';
import translate from '../translate';
type Props = I18nProps & {
hash?: string
value?: string
};
type State = {
hash: string
value: string
isNumber: boolean,
isValid: boolean
};
@ -23,17 +24,14 @@ class Query extends React.PureComponent<Props, State> {
constructor (props: Props) {
super(props);
const { hash } = this.props;
const { value } = this.props;
this.state = {
hash: hash || '',
isValid: isHex(hash, 256)
};
this.state = this.stateFromValue(value || '');
}
render () {
const { t } = this.props;
const { hash, isValid } = this.state;
const { value, isValid } = this.state;
return (
<summary>
@ -42,9 +40,9 @@ class Query extends React.PureComponent<Props, State> {
<div className='storage--actionrow medium'>
<Input
className='storage--actionrow-value'
defaultValue={this.props.hash}
isError={!isValid && hash.length !== 0}
placeholder={t('block hash to query')}
defaultValue={this.props.value}
isError={!isValid && value.length !== 0}
placeholder={t('block hash or number to query')}
onChange={this.setHash}
withLabel={false}
/>
@ -60,17 +58,27 @@ class Query extends React.PureComponent<Props, State> {
);
}
private setHash = (hash: string) => {
this.setState({
hash,
isValid: isHex(hash, 256)
});
private setHash = (value: string) => {
this.setState(
this.stateFromValue(value)
);
}
private onQuery = () => {
const { hash } = this.state;
const { value } = this.state;
window.location.hash = `/explorer/hash/${hash}`;
window.location.hash = `/explorer/query/${value}`;
}
private stateFromValue (value: string): State {
const isValidHex = isHex(value, 256);
const isNumber = !isValidHex && /^\d+$/.test(value);
return {
value,
isNumber,
isValid: isValidHex || isNumber
};
}
}

View File

@ -5,42 +5,51 @@
import { BareProps } from '@polkadot/ui-app/types';
import React from 'react';
import { isHex } from '@polkadot/util';
import BlockByHash from './BlockByHash';
import BlockByHash from './ByHash';
import BlockByNumber from './ByNumber';
import Query from './Query';
type Props = BareProps & {
match: {
params: {
hash: string
value: string
}
}
};
export default class Entry extends React.PureComponent<Props> {
render () {
const { match: { params: { hash } } } = this.props;
const { match: { params: { value } } } = this.props;
return (
<>
<Query hash={hash} />
<Query value={value} />
{this.renderBlock()}
</>
);
}
private renderBlock () {
const { match: { params: { hash } } } = this.props;
const { match: { params: { value } } } = this.props;
if (!hash) {
if (!value) {
return null;
}
return (
<BlockByHash
key={hash}
value={hash}
/>
);
return isHex(value)
? (
<BlockByHash
key={value}
value={value}
/>
)
: (
<BlockByNumber
key={value}
value={value}
/>
);
}
}

View File

@ -7,12 +7,12 @@ import { AppProps, I18nProps } from '@polkadot/ui-app/types';
import { Info } from './types';
import React from 'react';
import Extrinsics from '@polkadot/app-explorer/BlockByHash/Extrinsics';
import { withApi, withMulti } from '@polkadot/ui-api/index';
import { Health, PeerInfo, PendingExtrinsics } from '@polkadot/types';
import './index.css';
import Extrinsics from '../BlockQuery/Extrinsics';
import Peers from './Peers';
import Summary from './Summary';
import translate from './translate';

View File

@ -11,8 +11,9 @@ import { Route, Switch } from 'react-router';
import Tabs, { TabItem } from '@polkadot/ui-app/Tabs';
import translate from './translate';
import BlockByHash from './BlockByHash';
import Main from './Main';import NodeInfo from './NodeInfo';
import BlockQuery from './BlockQuery';
import Main from './Main';
import NodeInfo from './NodeInfo';
type Props = AppProps & BareProps & I18nProps;
@ -34,7 +35,7 @@ class ExplorerApp extends React.Component<Props, State> {
},
{
hasParams: true,
name: 'hash',
name: 'query',
text: t('Block query')
},
{
@ -58,8 +59,8 @@ class ExplorerApp extends React.Component<Props, State> {
/>
</header>
<Switch>
<Route path={`${basePath}/hash/:hash`} component={BlockByHash} />
<Route path={`${basePath}/hash`} component={BlockByHash} />
<Route path={`${basePath}/query/:value`} component={BlockQuery} />
<Route path={`${basePath}/query`} component={BlockQuery} />
<Route path={`${basePath}/node`} component={NodeInfo} />
<Route component={Main} />
</Switch>

View File

@ -6,6 +6,7 @@ import { IExtrinsic, IMethod } from '@polkadot/types/types';
import { BareProps } from './types';
import React from 'react';
import styled from 'styled-components';
import { Method, getTypeDef } from '@polkadot/types';
import Params from '@polkadot/ui-params/index';
@ -16,6 +17,15 @@ export type Props = BareProps & {
value: IExtrinsic | IMethod
};
const Wrapper = styled.div`
.hash {
opacity: 0.5;
overflow: hidden;
padding: 0 0.5rem 0.75rem 1.75rem;
text-overflow: ellipsis;
}
`;
export default class Call extends React.PureComponent<Props> {
render () {
const { children, className, style, value } = this.props;
@ -27,19 +37,29 @@ export default class Call extends React.PureComponent<Props> {
isValid: true,
value
}));
const hash = (value as IExtrinsic).hash;
return (
<div
<Wrapper
className={classes('ui--Extrinsic', className)}
style={style}
>
{children}
{
hash
? (
<div className='hash'>
{hash.toHex()}
</div>
)
: null
}
<Params
isDisabled
params={params}
values={values}
/>
</div>
</Wrapper>
);
}
}