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:
parent
e7eb08851f
commit
e6bced1d9a
@ -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
|
||||
} </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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
34
packages/app-explorer/src/BlockQuery/ByNumber.tsx
Normal file
34
packages/app-explorer/src/BlockQuery/ByNumber.tsx
Normal 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);
|
||||
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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';
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user