Adjust ErrorBoundary with trigger, cleanup InputAddress outer icon (#2528)
* Adjust ErrorBoundary with trigger, cleanup InputAddress outer icon * Remove extra fluff
This commit is contained in:
parent
94cfc37c29
commit
8fcf2d8864
@ -58,7 +58,7 @@ function Content ({ className }: Props): React.ReactElement<Props> {
|
||||
: (
|
||||
<>
|
||||
<Suspense fallback='...'>
|
||||
<ErrorBoundary>
|
||||
<ErrorBoundary trigger={name}>
|
||||
<Component
|
||||
basePath={`/${name}`}
|
||||
location={location}
|
||||
|
||||
@ -3,94 +3,55 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { SubmittableExtrinsic } from '@polkadot/api/types';
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
import { ApiProps } from '@polkadot/react-api/types';
|
||||
import { ComponentProps } from './types';
|
||||
import { ComponentProps as Props } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import { createType } from '@polkadot/types';
|
||||
import { Button, Icon, Extrinsic, TxButton, TxComponent } from '@polkadot/react-components';
|
||||
import { registry } from '@polkadot/react-api';
|
||||
import { withApi, withMulti } from '@polkadot/react-api/hoc';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { Button, Icon, Extrinsic, TxButton } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
import translate from './translate';
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
interface Props extends I18nProps, ApiProps, ComponentProps {
|
||||
onChange: (accountId?: string) => void;
|
||||
}
|
||||
function Propose ({ isMine, sudoKey }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { apiDefaultTxSudo } = useApi();
|
||||
const [method, setMethod] = useState<SubmittableExtrinsic<'promise'> | null>(null);
|
||||
|
||||
interface State {
|
||||
method: SubmittableExtrinsic<'promise'> | null;
|
||||
isValid: boolean;
|
||||
}
|
||||
const _onChangeExtrinsic = useCallback(
|
||||
(method: SubmittableExtrinsic<'promise'> | null = null) =>
|
||||
setMethod(() => method),
|
||||
[]
|
||||
);
|
||||
|
||||
class Propose extends TxComponent<Props, State> {
|
||||
public state: State = {
|
||||
isValid: false,
|
||||
method: null
|
||||
};
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { apiDefaultTxSudo, isMine, sudoKey, t } = this.props;
|
||||
const { isValid, method } = this.state;
|
||||
|
||||
return isMine
|
||||
? (
|
||||
<section>
|
||||
<Extrinsic
|
||||
defaultValue={apiDefaultTxSudo}
|
||||
label={t('submit the following change')}
|
||||
onChange={this.onChangeExtrinsic}
|
||||
onEnter={this.sendTx}
|
||||
return isMine
|
||||
? (
|
||||
<section>
|
||||
<Extrinsic
|
||||
defaultValue={apiDefaultTxSudo}
|
||||
label={t('submit the following change')}
|
||||
onChange={_onChangeExtrinsic}
|
||||
/>
|
||||
<br />
|
||||
<Button.Group>
|
||||
<TxButton
|
||||
accountId={sudoKey}
|
||||
icon='sign-in'
|
||||
isDisabled={!method}
|
||||
label={t('Submit Sudo')}
|
||||
params={[method]}
|
||||
tx='sudo.sudo'
|
||||
withSpinner={false}
|
||||
/>
|
||||
<br />
|
||||
<Button.Group>
|
||||
<TxButton
|
||||
accountId={sudoKey}
|
||||
icon='sign-in'
|
||||
isDisabled={!method || !isValid}
|
||||
label={t('Submit Sudo')}
|
||||
params={method ? [createType(registry, 'Proposal', method)] : []}
|
||||
tx='sudo.sudo'
|
||||
withSpinner
|
||||
/>
|
||||
</Button.Group>
|
||||
</section>
|
||||
)
|
||||
: (
|
||||
<article className='error padded'>
|
||||
<div>
|
||||
<Icon name='ban' />
|
||||
{t('You do not have access to the current sudo key')}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
private nextState (newState: Partial<State>): void {
|
||||
this.setState(
|
||||
(prevState: State): State => {
|
||||
const { method = prevState.method } = newState;
|
||||
|
||||
return {
|
||||
isValid: !!method,
|
||||
method
|
||||
};
|
||||
}
|
||||
</Button.Group>
|
||||
</section>
|
||||
)
|
||||
: (
|
||||
<article className='error padded'>
|
||||
<div>
|
||||
<Icon name='ban' />
|
||||
{t('You do not have access to the current sudo key')}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
private onChangeExtrinsic = (method?: SubmittableExtrinsic<'promise'>): void => {
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.nextState({ method });
|
||||
}
|
||||
}
|
||||
|
||||
export default withMulti(
|
||||
Propose,
|
||||
translate,
|
||||
withApi
|
||||
);
|
||||
export default React.memo(Propose);
|
||||
|
||||
@ -12,24 +12,31 @@ interface Props extends I18nProps {
|
||||
children: React.ReactNode;
|
||||
doThrow?: boolean;
|
||||
onError?: () => void;
|
||||
trigger?: any;
|
||||
}
|
||||
|
||||
interface State {
|
||||
hasError: boolean;
|
||||
error: Error | null;
|
||||
prevTrigger: string | null;
|
||||
}
|
||||
|
||||
// NOTE: This is the only way to do an error boundary, via extend
|
||||
class ErrorBoundary extends React.Component<Props> {
|
||||
state: State = { hasError: false };
|
||||
state: State = { error: null, prevTrigger: null };
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
static getDerivedStateFromError (_error: Error): State {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return { hasError: true };
|
||||
static getDerivedStateFromError (error: Error): Partial<State> {
|
||||
return { error };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
public componentDidCatch (error: Error, _errorInfo: any): void {
|
||||
static getDerivedStateFromProps ({ trigger }: Props, { prevTrigger }: State): State | null {
|
||||
const newTrigger = JSON.stringify({ trigger });
|
||||
|
||||
return (prevTrigger !== newTrigger)
|
||||
? { error: null, prevTrigger: newTrigger }
|
||||
: null;
|
||||
}
|
||||
|
||||
public componentDidCatch (error: Error): void {
|
||||
const { doThrow, onError } = this.props;
|
||||
|
||||
onError && onError();
|
||||
@ -41,12 +48,16 @@ class ErrorBoundary extends React.Component<Props> {
|
||||
|
||||
public render (): React.ReactNode {
|
||||
const { children, t } = this.props;
|
||||
const { hasError } = this.state;
|
||||
const { error } = this.state;
|
||||
|
||||
return hasError
|
||||
return error
|
||||
? (
|
||||
<article className='error'>
|
||||
{t('Uncaught error. Something went wrong with the query and rendering of this component.')}
|
||||
{t('Uncaught error. Something went wrong with the query and rendering of this component. {{message}}', {
|
||||
replace: {
|
||||
message: error.message
|
||||
}
|
||||
})}
|
||||
</article>
|
||||
)
|
||||
: children;
|
||||
|
||||
@ -60,11 +60,12 @@ function IdentityIcon ({ className, onCopy, prefix, size, theme, value }: Props)
|
||||
|
||||
return (
|
||||
<span
|
||||
className={className}
|
||||
className={`ui--IdentityIcon-Outer ${className}`}
|
||||
data-for={trigger}
|
||||
data-tip={true}
|
||||
>
|
||||
<BaseIdentityIcon
|
||||
className={className}
|
||||
isHighlight={isValidator}
|
||||
onCopy={_onCopy}
|
||||
prefix={prefix}
|
||||
|
||||
@ -290,7 +290,7 @@ const ExportedComponent = withMulti(
|
||||
|
||||
.ui.search.selection.dropdown {
|
||||
> .text > .ui--KeyPair {
|
||||
.ui--IdentityIcon {
|
||||
.ui--IdentityIcon-Outer {
|
||||
border: 1px solid #888;
|
||||
border-radius: 50%;
|
||||
left: -2.75rem;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user