Toolbox RPC adjustments (#2505)

This commit is contained in:
Jaco Greeff 2020-04-02 10:05:54 +02:00 committed by GitHub
parent 4cbde60d47
commit 6c86eea578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 127 deletions

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { Input, Output, Static } from '@polkadot/react-components';
import { hexToU8a, isHex, stringToU8a } from '@polkadot/util';
import { blake2AsHex } from '@polkadot/util-crypto';
@ -15,7 +15,7 @@ interface State {
isHexData: boolean;
}
function Hash (): React.ReactElement<{}> {
function Hash (): React.ReactElement {
const { t } = useTranslation();
const [{ data, hash, isHexData }, setState] = useState<State>({
data: '',
@ -23,20 +23,23 @@ function Hash (): React.ReactElement<{}> {
isHexData: false
});
const _onChangeData = (data: string): void => {
const isHexData = isHex(data);
const _onChangeData = useCallback(
(data: string): void => {
const isHexData = isHex(data);
setState({
data,
hash: blake2AsHex(
setState({
data,
hash: blake2AsHex(
isHexData
? hexToU8a(data)
: stringToU8a(data),
256
),
isHexData
? hexToU8a(data)
: stringToU8a(data),
256
),
isHexData
});
};
});
},
[]
);
return (
<div className='toolbox--Hash'>

View File

@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import { InputAddress, Labelled } from '@polkadot/react-components';
import { Nonce } from '@polkadot/react-query';
@ -22,15 +22,9 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React.
const [accountId, setAccountId] = useState<string | null | undefined>(defaultValue);
const [accountNonce, setAccountNonce] = useState(new BN(0));
const _onChangeAccountId = (accountId: string | null): void => {
setAccountId(accountId);
useEffect((): void => {
onChange(accountId, accountNonce);
};
const _onChangeAccountNonce = (accountNonce: BN): void => {
setAccountNonce(accountNonce);
onChange(accountId, accountNonce);
};
}, [accountId, accountNonce, onChange]);
return (
<div className={`ui--row ${className}`}>
@ -39,7 +33,7 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React.
defaultValue={defaultValue}
isError={isError}
label={t('sign data from account')}
onChange={_onChangeAccountId}
onChange={setAccountId}
placeholder='0x...'
type='account'
/>
@ -50,7 +44,7 @@ function Account ({ className, defaultValue, isError, onChange }: Props): React.
label={t('with an index of')}
>
<Nonce
callOnResult={_onChangeAccountNonce}
callOnResult={setAccountNonce}
className='ui disabled dropdown selection'
params={accountId}
/>

View File

@ -15,9 +15,7 @@ interface Props extends BareProps {
function Results ({ queue = [] }: Props): React.ReactElement<Props> | null {
const filtered = queue
.filter(({ error, result }): boolean =>
!isUndefined(error) || !isUndefined(result)
)
.filter(({ error, result }) => !isUndefined(error) || !isUndefined(result))
.reverse();
if (!filtered.length) {

View File

@ -3,20 +3,19 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ParamDef, RawParam } from '@polkadot/react-params/types';
import { I18nProps } from '@polkadot/react-components/types';
import { QueueTxRpcAdd } from '@polkadot/react-components/Status/types';
import { DefinitionRpcExt } from '@polkadot/types/types';
import React from 'react';
import { Button, InputRpc, TxComponent } from '@polkadot/react-components';
import React, { useCallback, useState } from 'react';
import { Button, InputRpc } from '@polkadot/react-components';
import Params from '@polkadot/react-params';
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
import { getTypeDef } from '@polkadot/types';
import { isNull } from '@polkadot/util';
import translate from '../translate';
import { useTranslation } from '../translate';
interface Props extends I18nProps {
interface Props {
queueRpc: QueueTxRpcAdd;
}
@ -29,57 +28,21 @@ interface State {
const defaultMethod = jsonrpc.author.submitExtrinsic;
class Selection extends TxComponent<Props, State> {
public state: State = {
function Selection ({ queueRpc }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [{ accountId, isValid, rpc, values }, setState] = useState<State>({
accountId: null,
isValid: false,
rpc: defaultMethod,
values: []
};
});
public render (): React.ReactNode {
const { t } = this.props;
const { isValid, rpc } = this.state;
const params = rpc.params.map(({ isOptional, name, type }): ParamDef => ({
name,
type: getTypeDef(isOptional ? `Option<${type}>` : type)
}));
return (
<section className='rpc--Selection'>
<InputRpc
defaultValue={defaultMethod}
help={t('The actual JSONRPC module and function to make a call to.')}
label={t('call the selected endpoint')}
onChange={this.onChangeMethod}
/>
<Params
key={`${rpc.section}.${rpc.method}:params` /* force re-render on change */}
onChange={this.onChangeValues}
onEnter={this.submit}
params={params}
/>
<Button.Group>
<Button
icon='sign-in'
isDisabled={!isValid}
label={t('Submit RPC call')}
onClick={this.onSubmit}
ref={this.button}
/>
</Button.Group>
</section>
);
}
private nextState (newState: Partial<State>): void {
this.setState(
(prevState: State): State => {
const _nextState = useCallback(
(newState: Partial<State>): void =>
setState((prevState: State): State => {
const { accountId = prevState.accountId, rpc = prevState.rpc, values = prevState.values } = newState;
const reqCount = rpc.params.reduce((count, { isOptional }): number => count + (isOptional ? 0 : 1), 0);
const isValid = values.reduce((isValid, value): boolean => {
return isValid && value.isValid === true;
}, reqCount <= values.length);
const isValid = values.reduce((isValid, value) => isValid && value.isValid === true, reqCount <= values.length);
return {
accountId,
@ -87,33 +50,59 @@ class Selection extends TxComponent<Props, State> {
rpc,
values
};
}
);
}
}),
[]
);
private onChangeMethod = (rpc: DefinitionRpcExt): void => {
this.nextState({
rpc,
values: [] as RawParam[]
});
}
const _onChangeMethod = useCallback(
(rpc: DefinitionRpcExt): void => _nextState({ rpc, values: [] }),
[_nextState]
);
private onChangeValues = (values: RawParam[]): void => {
this.nextState({ values });
}
const _onChangeValues = useCallback(
(values: RawParam[]): void => _nextState({ values }),
[_nextState]
);
private onSubmit = (): void => {
const { queueRpc } = this.props;
const { accountId, rpc, values } = this.state;
queueRpc({
const _onSubmit = useCallback(
(): void => queueRpc({
accountId,
rpc,
values: values
.filter(({ value }): boolean => !isNull(value))
.map(({ value }): any => value)
});
}
}),
[accountId, queueRpc, rpc, values]
);
const params = rpc.params.map(({ isOptional, name, type }): ParamDef => ({
name,
type: getTypeDef(isOptional ? `Option<${type}>` : type)
}));
return (
<section className='rpc--Selection'>
<InputRpc
defaultValue={defaultMethod}
help={t('The actual JSONRPC module and function to make a call to.')}
label={t('call the selected endpoint')}
onChange={_onChangeMethod}
/>
<Params
key={`${rpc.section}.${rpc.method}:params` /* force re-render on change */}
onChange={_onChangeValues}
params={params}
/>
<Button.Group>
<Button
icon='sign-in'
isDisabled={!isValid}
label={t('Submit RPC call')}
onClick={_onSubmit}
/>
</Button.Group>
</section>
);
}
export default translate(Selection);
export default React.memo(Selection);

View File

@ -2,24 +2,20 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { QueueProps } from '@polkadot/react-components/Status/types';
import React from 'react';
import { QueueConsumer } from '@polkadot/react-components/Status/Context';
import React, { useContext } from 'react';
import { StatusContext } from '@polkadot/react-components';
import Results from './Results';
import Selection from './Selection';
function RpcApp (): React.ReactElement {
const { queueRpc, txqueue } = useContext(StatusContext);
return (
<QueueConsumer>
{({ queueRpc, txqueue }: QueueProps): React.ReactNode => (
<>
<Selection queueRpc={queueRpc} />
<Results queue={txqueue} />
</>
)}
</QueueConsumer>
<>
<Selection queueRpc={queueRpc} />
<Results queue={txqueue} />
</>
);
}

View File

@ -7,7 +7,7 @@
import { DefinitionRpcExt } from '@polkadot/types/types';
import { DropdownOptions } from '../util/types';
import React, { useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { useApi } from '@polkadot/react-hooks';
import jsonrpc from '@polkadot/types/interfaces/jsonrpc';
@ -34,26 +34,35 @@ function InputRpc ({ className, defaultValue, help, label, onChange, style, with
const [optionsSection] = useState<DropdownOptions>(sectionOptions(api));
const [value, setValue] = useState<DefinitionRpcExt>((): DefinitionRpcExt => defaultValue);
const _onMethodChange = (newValue: DefinitionRpcExt): void => {
if (value.section === newValue.section && value.method === newValue.method) {
return;
}
useEffect((): void => {
onChange && onChange(value);
}, [onChange, value]);
// set via callback since the method is a function itself
setValue((): DefinitionRpcExt => newValue);
onChange && onChange(newValue);
};
const _onMethodChange = useCallback(
(newValue: DefinitionRpcExt): void => {
if (value.section === newValue.section && value.method === newValue.method) {
return;
}
const _onSectionChange = (section: string): void => {
if (section === value.section) {
return;
}
// set via callback since the method is a function itself
setValue((): DefinitionRpcExt => newValue);
},
[value]
);
const optionsMethod = methodOptions(api, section);
const _onSectionChange = useCallback(
(section: string): void => {
if (section === value.section) {
return;
}
setOptionsMethod(optionsMethod);
_onMethodChange(jsonrpc[section][optionsMethod[0].value]);
};
const optionsMethod = methodOptions(api, section);
setOptionsMethod(optionsMethod);
_onMethodChange(jsonrpc[section][optionsMethod[0].value]);
},
[_onMethodChange, api, value]
);
return (
<LinkedWrapper

View File

@ -5,6 +5,7 @@
import { BareProps } from './types';
import React from 'react';
import styled from 'styled-components';
import CopyButton from './CopyButton';
import Labelled from './Labelled';
@ -50,4 +51,9 @@ function Output ({ children, className, help, isError, isHidden, isMonospace, la
);
}
export default React.memo(Output);
export default React.memo(styled(Output)`
pre {
overflow: hidden;
text-overflow: ellipsis;
}
`);