Toolbox RPC adjustments (#2505)
This commit is contained in:
parent
4cbde60d47
commit
6c86eea578
@ -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'>
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
`);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user