TxButton to functional (#2314)
* TxButton to functional * bug fix * Small moves Co-authored-by: Jaco Greeff <jacogr@gmail.com>
This commit is contained in:
parent
8c47775ec0
commit
1c8e504457
@ -108,7 +108,6 @@ class VanityApp extends TxComponent<Props, State> {
|
||||
? t('Stop generation')
|
||||
: t('Start generation')
|
||||
}
|
||||
ref={this.button}
|
||||
/>
|
||||
</Button.Group>
|
||||
);
|
||||
|
||||
@ -57,7 +57,6 @@ class ChangePass extends TxComponent<Props, State> {
|
||||
isPrimary
|
||||
label={t('Change')}
|
||||
onClick={this.doChange}
|
||||
ref={this.button}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
);
|
||||
|
||||
@ -47,7 +47,6 @@ class Import extends TxComponent<Props, State> {
|
||||
isPrimary
|
||||
onClick={this.onSave}
|
||||
label={t('Restore')}
|
||||
ref={this.button}
|
||||
/>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
|
||||
@ -82,7 +82,6 @@ class Upload extends ContractModal<Props, State> {
|
||||
onFailed={this.toggleBusy(false)}
|
||||
params={[gasLimit, wasm]}
|
||||
tx={api.tx.contracts ? 'contracts.putCode' : 'contract.putCode'}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
);
|
||||
|
||||
@ -81,7 +81,6 @@ class Add extends ContractModal<Props, State> {
|
||||
isPrimary
|
||||
label={t('Save')}
|
||||
onClick={this.onAdd}
|
||||
ref={this.button}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -241,7 +241,6 @@ class Deploy extends ContractModal<Props, State> {
|
||||
: 'contracts.create' // V2 (old)
|
||||
: 'contract.create' // V1
|
||||
}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
);
|
||||
|
||||
@ -35,7 +35,7 @@ class Selection extends TxComponent<Props, State> {
|
||||
public render (): React.ReactNode {
|
||||
const { apiDefaultTxSudo, t } = this.props;
|
||||
const { isValid, isValidUnsigned, accountId } = this.state;
|
||||
const extrinsic = this.getExtrinsic() || apiDefaultTxSudo;
|
||||
const extrinsic = this.getExtrinsic() || apiDefaultTxSudo('0x00');
|
||||
|
||||
return (
|
||||
<div className='extrinsics--Selection'>
|
||||
@ -64,12 +64,11 @@ class Selection extends TxComponent<Props, State> {
|
||||
<Button.Or />
|
||||
<TxButton
|
||||
accountId={accountId}
|
||||
icon='sign-in'
|
||||
isDisabled={!isValid}
|
||||
isPrimary
|
||||
label={t('Submit Transaction')}
|
||||
icon='sign-in'
|
||||
extrinsic={extrinsic}
|
||||
ref={this.button}
|
||||
label={t('Submit Transaction')}
|
||||
/>
|
||||
</Button.Group>
|
||||
</div>
|
||||
|
||||
@ -80,7 +80,6 @@ class BondExtra extends TxComponent<Props, State> {
|
||||
icon='sign-in'
|
||||
onStart={onClose}
|
||||
extrinsic={extrinsic}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -90,7 +90,6 @@ class SetControllerAccount extends TxComponent<Props, State> {
|
||||
onStart={onClose}
|
||||
params={[controllerId]}
|
||||
tx='staking.setController'
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -52,7 +52,6 @@ class SetRewardDestination extends TxComponent<Props, State> {
|
||||
onStart={onClose}
|
||||
params={[destination]}
|
||||
tx={'staking.setPayee'}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -76,7 +76,6 @@ class Unbond extends TxComponent<Props, State> {
|
||||
onStart={onClose}
|
||||
params={[maxUnbond]}
|
||||
tx='staking.unbond'
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -94,7 +94,6 @@ class Validate extends TxComponent<Props, State> {
|
||||
onStart={onClose}
|
||||
params={[{ commission }]}
|
||||
tx='staking.validate'
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -122,7 +122,6 @@ class NewStake extends TxComponent<Props, State> {
|
||||
icon='sign-in'
|
||||
onStart={onClose}
|
||||
extrinsic={extrinsic}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Modal.Actions>
|
||||
|
||||
@ -52,7 +52,6 @@ class Propose extends TxComponent<Props, State> {
|
||||
tx='sudo.sudo'
|
||||
isDisabled={!method || !isValid}
|
||||
params={method ? [createType(registry, 'Proposal', method)] : []}
|
||||
ref={this.button}
|
||||
withSpinner
|
||||
/>
|
||||
</Button.Group>
|
||||
|
||||
@ -2,141 +2,93 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { QueueTx, QueueTxExtrinsicAdd } from './Status/types';
|
||||
import { TxButtonProps as Props } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { SubmittableResult } from '@polkadot/api';
|
||||
import { withApi } from '@polkadot/react-api/hoc';
|
||||
import { useApi, useToggle } from '@polkadot/react-hooks';
|
||||
import { assert, isFunction, isUndefined } from '@polkadot/util';
|
||||
|
||||
import Button from './Button';
|
||||
import { QueueConsumer } from './Status/Context';
|
||||
import { StatusContext } from './Status';
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
interface InjectedProps {
|
||||
queueExtrinsic: QueueTxExtrinsicAdd;
|
||||
txqueue: QueueTx[];
|
||||
}
|
||||
export default function TxButton ({ accountId, className, extrinsic: propsExtrinsic, icon, iconSize, isBasic, isDisabled, isNegative, isPrimary, isUnsigned, label, onClick, onFailed, onSendRef, onStart, onSuccess, onUpdate, params, tx, tooltip, withSpinner }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { queueExtrinsic } = useContext(StatusContext);
|
||||
const [isSending, , setIsSending] = useToggle(false);
|
||||
const needsAccount = !isUnsigned && !accountId;
|
||||
|
||||
type InnerProps = Props & InjectedProps;
|
||||
const _onFailed = (result: SubmittableResult | null): void => {
|
||||
setIsSending(false);
|
||||
|
||||
interface State {
|
||||
extrinsic?: SubmittableExtrinsic;
|
||||
isSending: boolean;
|
||||
}
|
||||
|
||||
class TxButtonInner extends React.PureComponent<InnerProps> {
|
||||
public state: State = {
|
||||
isSending: false
|
||||
onFailed && onFailed(result);
|
||||
};
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { accountId, className, icon, iconSize, innerRef, isBasic, isDisabled, isNegative, isPrimary, isUnsigned, label, tooltip } = this.props;
|
||||
const _onSuccess = (result: SubmittableResult): void => {
|
||||
setIsSending(false);
|
||||
|
||||
const { isSending } = this.state;
|
||||
const needsAccount = isUnsigned
|
||||
? false
|
||||
: !accountId;
|
||||
onSuccess && onSuccess(result);
|
||||
};
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={className}
|
||||
tooltip={tooltip}
|
||||
icon={icon}
|
||||
isBasic={isBasic}
|
||||
isDisabled={isSending || isDisabled || needsAccount}
|
||||
isLoading={isSending}
|
||||
isNegative={isNegative}
|
||||
isPrimary={
|
||||
isUndefined(isPrimary)
|
||||
? (!isNegative && !isBasic)
|
||||
: isPrimary
|
||||
}
|
||||
label={label}
|
||||
onClick={this.send}
|
||||
ref={innerRef}
|
||||
size={iconSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
protected send = (): void => {
|
||||
const { accountId, api, extrinsic: propsExtrinsic, isUnsigned, onClick, onFailed, onStart, onSuccess, onUpdate, params = [], queueExtrinsic, tx = '', withSpinner = true } = this.props;
|
||||
const _onSend = (): void => {
|
||||
let extrinsic: any;
|
||||
|
||||
if (propsExtrinsic) {
|
||||
extrinsic = propsExtrinsic;
|
||||
} else {
|
||||
const [section, method] = tx.split('.');
|
||||
const [section, method] = (tx || '').split('.');
|
||||
|
||||
assert(api.tx[section] && api.tx[section][method], `Unable to find api.tx.${section}.${method}`);
|
||||
|
||||
extrinsic = api.tx[section][method](...(
|
||||
isFunction(params)
|
||||
? params()
|
||||
: params
|
||||
: (params || [])
|
||||
));
|
||||
}
|
||||
|
||||
assert(extrinsic, 'Expected generated extrinsic passed to TxButton');
|
||||
|
||||
if (withSpinner) {
|
||||
this.setState({ isSending: true });
|
||||
setIsSending(true);
|
||||
}
|
||||
|
||||
queueExtrinsic({
|
||||
accountId,
|
||||
accountId: accountId && accountId.toString(),
|
||||
extrinsic,
|
||||
isUnsigned,
|
||||
txFailedCb: withSpinner ? this.onFailed : onFailed,
|
||||
txFailedCb: withSpinner ? _onFailed : onFailed,
|
||||
txStartCb: onStart,
|
||||
txSuccessCb: withSpinner ? this.onSuccess : onSuccess,
|
||||
txSuccessCb: withSpinner ? _onSuccess : onSuccess,
|
||||
txUpdateCb: onUpdate
|
||||
});
|
||||
|
||||
onClick && onClick();
|
||||
};
|
||||
|
||||
if (onSendRef) {
|
||||
onSendRef.current = _onSend;
|
||||
}
|
||||
|
||||
private onFailed = (result: SubmittableResult | null): void => {
|
||||
const { onFailed } = this.props;
|
||||
|
||||
this.setState({ isSending: false });
|
||||
|
||||
onFailed && onFailed(result);
|
||||
}
|
||||
|
||||
private onSuccess = (result: SubmittableResult): void => {
|
||||
const { onSuccess } = this.props;
|
||||
|
||||
this.setState({ isSending: false });
|
||||
|
||||
onSuccess && onSuccess(result);
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
className={className}
|
||||
tooltip={tooltip}
|
||||
icon={icon || 'check'}
|
||||
isBasic={isBasic}
|
||||
isDisabled={isSending || isDisabled || needsAccount}
|
||||
isLoading={isSending}
|
||||
isNegative={isNegative}
|
||||
isPrimary={
|
||||
isUndefined(isPrimary)
|
||||
? (!isNegative && !isBasic)
|
||||
: isPrimary
|
||||
}
|
||||
label={label || t('Submit')}
|
||||
onClick={_onSend}
|
||||
size={iconSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
class TxButton extends React.PureComponent<Props, State> {
|
||||
protected button: any = React.createRef();
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { innerRef, ...props } = this.props;
|
||||
return (
|
||||
<QueueConsumer>
|
||||
{({ queueExtrinsic, txqueue }): React.ReactNode => (
|
||||
<TxButtonInner
|
||||
{...props}
|
||||
queueExtrinsic={queueExtrinsic}
|
||||
txqueue={txqueue}
|
||||
innerRef={innerRef}
|
||||
/>
|
||||
)}
|
||||
</QueueConsumer>
|
||||
);
|
||||
}
|
||||
|
||||
protected send = (): void => {
|
||||
this.button.current.send();
|
||||
}
|
||||
}
|
||||
|
||||
export default withApi(TxButton);
|
||||
|
||||
@ -157,7 +157,6 @@ export default class TxModal<P extends TxModalProps, S extends TxModalState> ext
|
||||
onFailed={this.onFailed}
|
||||
onSuccess={this.onSuccess}
|
||||
params={this.txParams()}
|
||||
ref={this.button}
|
||||
tx={this.txMethod()}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -7,13 +7,14 @@ import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
||||
import { Abi } from '@polkadot/api-contract';
|
||||
import { ActionStatus } from '@polkadot/react-components/Status/types';
|
||||
import { InputAddressProps } from '@polkadot/react-components/InputAddress/types';
|
||||
import { IExtrinsic } from '@polkadot/types/types';
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
import { TxState } from '@polkadot/react-hooks/types';
|
||||
import { Index } from '@polkadot/types/interfaces';
|
||||
import { ButtonProps, Button$OnClick, Button$Sizes } from './Button/types';
|
||||
import { IExtrinsic } from '@polkadot/types/types';
|
||||
import { AccountId, Index } from '@polkadot/types/interfaces';
|
||||
import { ButtonProps, Button$Sizes } from './Button/types';
|
||||
import { TxCallback, TxFailedCallback } from './Status/types';
|
||||
|
||||
export type VoidFn = () => void;
|
||||
|
||||
export interface BareProps {
|
||||
className?: string;
|
||||
style?: Record<string, string | number>;
|
||||
@ -27,22 +28,6 @@ export interface AppProps {
|
||||
|
||||
export type I18nProps = BareProps & WithTranslation;
|
||||
|
||||
export type ButtonRef = React.RefObject<React.Component<ButtonProps>>;
|
||||
|
||||
// export type FormProps$Ref = React.MutableRefObject<Button$OnClick>;
|
||||
|
||||
export interface FormProps {
|
||||
onCancel: Button$OnClick;
|
||||
onSubmit: Button$OnClick;
|
||||
}
|
||||
|
||||
// export interface FormProps$Hooks {
|
||||
// onInputEnterKey: () => void;
|
||||
// onInputEscapeKey: () => void;
|
||||
// }
|
||||
|
||||
// export interface FormProps extends FormProps$Refs, FormProps$Hooks {}
|
||||
|
||||
export type ConstructTxFn = () => any[];
|
||||
|
||||
export type TxTrigger = React.ComponentType<TxTriggerProps>;
|
||||
@ -51,59 +36,39 @@ export interface TxTriggerProps {
|
||||
onOpen: () => void;
|
||||
}
|
||||
|
||||
export interface TxButtonInterface {
|
||||
component?: {
|
||||
current?: {
|
||||
send: () => void;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface TxProps {
|
||||
extrinsic?: IExtrinsic | SubmittableExtrinsic | null;
|
||||
tx?: string;
|
||||
params?: any[] | ConstructTxFn;
|
||||
}
|
||||
|
||||
export interface TxButtonProps extends TxProps, ApiProps {
|
||||
accountId?: string;
|
||||
accountNonce?: Index;
|
||||
export interface TxAccountProps {
|
||||
className?: string;
|
||||
icon: string;
|
||||
iconSize?: Button$Sizes;
|
||||
innerRef: ButtonRef;
|
||||
isBasic?: boolean;
|
||||
isDisabled?: boolean;
|
||||
isNegative?: boolean;
|
||||
isPrimary?: boolean;
|
||||
isUnsigned?: boolean;
|
||||
label: React.ReactNode;
|
||||
onClick?: () => any;
|
||||
onFailed?: TxFailedCallback;
|
||||
onStart?: () => void;
|
||||
onSuccess?: TxCallback;
|
||||
onUpdate?: TxCallback;
|
||||
tooltip?: string;
|
||||
withSpinner?: boolean;
|
||||
filter?: string[];
|
||||
label?: React.ReactNode;
|
||||
help?: React.ReactNode;
|
||||
onChange: (value: string | null) => void;
|
||||
}
|
||||
|
||||
export interface TxButtonNewProps extends TxProps {
|
||||
accountId?: StringOrNull;
|
||||
export interface TxButtonProps extends TxProps {
|
||||
accountId?: AccountId | StringOrNull;
|
||||
accountNonce?: Index;
|
||||
className?: string;
|
||||
icon: string;
|
||||
icon?: string;
|
||||
iconSize?: Button$Sizes;
|
||||
isBasic?: boolean;
|
||||
isDisabled?: boolean;
|
||||
isNegative?: boolean;
|
||||
isPrimary?: boolean;
|
||||
isUnsigned?: boolean;
|
||||
label: React.ReactNode;
|
||||
onClick?: () => any;
|
||||
label?: React.ReactNode;
|
||||
onClick?: VoidFn;
|
||||
onFailed?: TxFailedCallback;
|
||||
onStart?: () => void;
|
||||
onSendRef?: React.MutableRefObject<VoidFn | undefined>;
|
||||
onStart?: VoidFn;
|
||||
onSuccess?: TxCallback;
|
||||
onUpdate?: TxCallback;
|
||||
size?: string;
|
||||
tooltip?: string;
|
||||
withSpinner?: boolean;
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ export { default as useAddresses } from './useAddresses';
|
||||
export { default as useApi } from './useApi';
|
||||
export { default as useCacheKey } from './useCacheKey';
|
||||
export { default as useCall } from './useCall';
|
||||
export { default as useForm } from './useForm';
|
||||
export { default as useDebounce } from './useDebounce';
|
||||
export { default as useFavorites } from './useFavorites';
|
||||
export { default as useIsMountedRef } from './useIsMountedRef';
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
// Copyright 2017-2020 @polkadot/react-hooks 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 { Button$OnClick } from '@polkadot/react-components/Button/types';
|
||||
import { FormProps } from '@polkadot/react-components/types';
|
||||
|
||||
import { useRef } from 'react';
|
||||
|
||||
const EMPTY_CALLBACK = (): void => undefined;
|
||||
|
||||
export default function useForm (onSubmit: () => void, onCancel: () => void = EMPTY_CALLBACK): FormProps {
|
||||
const onCancelRef = useRef<Button$OnClick>(onCancel);
|
||||
const onSubmitRef = useRef<Button$OnClick>(onSubmit);
|
||||
|
||||
return {
|
||||
onCancel: (): void => {
|
||||
onCancelRef.current && onCancelRef.current();
|
||||
},
|
||||
onSubmit: (): void => {
|
||||
onSubmitRef.current && onSubmitRef.current();
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user