Convert options & items (tabs) to useMemo (#2207)
* Convert options & items (tabs) to useMemo * Add missing var in useMemo * Remove floating isSubstrateV2 * Cleanup staking entry * Remove unneeded ?
This commit is contained in:
parent
d2816155c7
commit
1d8613655f
@ -5,7 +5,7 @@
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { useAccounts } from '@polkadot/react-hooks';
|
||||
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
||||
@ -19,6 +19,17 @@ export default function AccountsApp ({ basePath, onStatusChange }: Props): React
|
||||
const { t } = useTranslation();
|
||||
const { hasAccounts } = useAccounts();
|
||||
const [hidden, setHidden] = useState<string[]>(['vanity']);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('My accounts')
|
||||
},
|
||||
{
|
||||
name: 'vanity',
|
||||
text: t('Vanity address')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
useEffect((): void => {
|
||||
setHidden(
|
||||
@ -42,17 +53,7 @@ export default function AccountsApp ({ basePath, onStatusChange }: Props): React
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
hidden={hidden}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('My accounts')
|
||||
},
|
||||
{
|
||||
name: 'vanity',
|
||||
text: t('Vanity address')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -8,7 +8,7 @@ import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
import { ModalProps } from '../types';
|
||||
|
||||
import FileSaver from 'file-saver';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { DEV_PHRASE } from '@polkadot/keyring/defaults';
|
||||
import { AddressRow, Button, Dropdown, Input, InputAddress, Modal, Password } from '@polkadot/react-components';
|
||||
@ -164,6 +164,14 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr
|
||||
const [{ isNameValid, name }, setName] = useState({ isNameValid: false, name: '' });
|
||||
const [{ isPassValid, password }, setPassword] = useState({ isPassValid: false, password: '' });
|
||||
const isValid = !!address && !deriveError && isNameValid && isPassValid && isSeedValid;
|
||||
const seedOpt = useMemo(() => (
|
||||
isDevelopment
|
||||
? [{ value: 'dev', text: t('Development') }]
|
||||
: []
|
||||
).concat(
|
||||
{ value: 'bip', text: t('Mnemonic') },
|
||||
{ value: 'raw', text: t('Raw seed') }
|
||||
), [isDevelopment, t]);
|
||||
|
||||
const _onChangePass = (password: string): void =>
|
||||
setPassword({ isPassValid: keyring.isPassValid(password), password });
|
||||
@ -245,16 +253,7 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, type: pr
|
||||
isButton
|
||||
defaultValue={seedType}
|
||||
onChange={_selectSeedType}
|
||||
options={
|
||||
(
|
||||
isDevelopment
|
||||
? [{ value: 'dev', text: t('Development') }]
|
||||
: []
|
||||
).concat(
|
||||
{ value: 'bip', text: t('Mnemonic') },
|
||||
{ value: 'raw', text: t('Raw seed') }
|
||||
)
|
||||
}
|
||||
options={seedOpt}
|
||||
/>
|
||||
</Input>
|
||||
<Password
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { AppProps } from '@polkadot/react-components/types';
|
||||
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { HelpOverlay } from '@polkadot/react-components';
|
||||
import Tabs from '@polkadot/react-components/Tabs';
|
||||
@ -21,6 +21,13 @@ interface Props extends AppProps {
|
||||
|
||||
export default function AddressBookApp ({ basePath, onStatusChange }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('My contacts')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className='address-book--App'>
|
||||
@ -28,13 +35,7 @@ export default function AddressBookApp ({ basePath, onStatusChange }: Props): Re
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('My contacts')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { DerivedCollectiveProposals } from '@polkadot/api-derive/types';
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
@ -27,27 +27,28 @@ function CouncilApp ({ basePath, className }: Props): React.ReactElement<Props>
|
||||
const { pathname } = useLocation();
|
||||
const numMotions = useCounter();
|
||||
const motions = useCall<DerivedCollectiveProposals>(api.derive.council.proposals, []);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Council overview')
|
||||
},
|
||||
{
|
||||
name: 'candidates',
|
||||
text: t('Candidates')
|
||||
},
|
||||
{
|
||||
name: 'motions',
|
||||
text: t('Motions ({{count}})', { replace: { count: numMotions } })
|
||||
}
|
||||
], [numMotions, t]);
|
||||
|
||||
return (
|
||||
<main className={className}>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Council overview')
|
||||
},
|
||||
{
|
||||
name: 'candidates',
|
||||
text: t('Candidates')
|
||||
},
|
||||
{
|
||||
name: 'motions',
|
||||
text: t('Motions ({{count}})', { replace: { count: numMotions } })
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -11,11 +11,6 @@ import { isBoolean } from '@polkadot/util';
|
||||
|
||||
import { useTranslation } from '../translate';
|
||||
|
||||
interface Option {
|
||||
text: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
proposal?: Proposal;
|
||||
referendumId: PropIndex;
|
||||
@ -28,17 +23,15 @@ export default function Voting ({ proposal, referendumId }: Props): React.ReactE
|
||||
const [conviction, setConviction] = useState(0);
|
||||
const [isVotingOpen, toggleVoting] = useToggle();
|
||||
const [aye, setVoteValue] = useState(true);
|
||||
const convictionOpts = useMemo((): Option[] => {
|
||||
return [
|
||||
{ text: t('0.1x of voting balance, no lockup period'), value: 0 },
|
||||
{ text: t('1x of voting balance, locked for 1x enactment'), value: 1 },
|
||||
{ text: t('2x of voting balance, locked for 2x enactment'), value: 2 },
|
||||
{ text: t('3x of voting balance, locked for 4x enactment'), value: 3 },
|
||||
{ text: t('4x of voting balance, locked for 8x enactment'), value: 4 },
|
||||
{ text: t('5x of voting balance, locked for 16x enactment'), value: 5 },
|
||||
{ text: t('6x of voting balance, locked for 32x enactment'), value: 6 }
|
||||
];
|
||||
}, [t]);
|
||||
const convictionOpts = useMemo(() => [
|
||||
{ text: t('0.1x of voting balance, no lockup period'), value: 0 },
|
||||
{ text: t('1x of voting balance, locked for 1x enactment'), value: 1 },
|
||||
{ text: t('2x of voting balance, locked for 2x enactment'), value: 2 },
|
||||
{ text: t('3x of voting balance, locked for 4x enactment'), value: 3 },
|
||||
{ text: t('4x of voting balance, locked for 8x enactment'), value: 4 },
|
||||
{ text: t('5x of voting balance, locked for 16x enactment'), value: 5 },
|
||||
{ text: t('6x of voting balance, locked for 32x enactment'), value: 6 }
|
||||
], [t]);
|
||||
|
||||
if (!hasAccounts) {
|
||||
return null;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
||||
import uiSettings from '@polkadot/ui-settings';
|
||||
@ -23,6 +23,13 @@ const hidden = uiSettings.uiMode === 'full'
|
||||
|
||||
export default function DemocracyApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Democracy overview')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className='democracy--App'>
|
||||
@ -31,13 +38,7 @@ export default function DemocracyApp ({ basePath }: Props): React.ReactElement<P
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
hidden={hidden}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Democracy overview')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
import { KeyedEvent } from './types';
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
import React, { useContext, useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
// import styled from 'styled-components';
|
||||
import Tabs from '@polkadot/react-components/Tabs';
|
||||
@ -28,6 +28,26 @@ function ExplorerApp ({ basePath, className }: Props): React.ReactElement<Props>
|
||||
const { api } = useApi();
|
||||
const { lastHeaders } = useContext(BlockAuthorsContext);
|
||||
const events = useContext(EventsContext);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'chain',
|
||||
text: t('Chain info')
|
||||
},
|
||||
{
|
||||
hasParams: true,
|
||||
name: 'query',
|
||||
text: t('Block details')
|
||||
},
|
||||
{
|
||||
name: 'forks',
|
||||
text: t('Forks')
|
||||
},
|
||||
{
|
||||
name: 'node',
|
||||
text: t('Node info')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className={className}>
|
||||
@ -39,26 +59,7 @@ function ExplorerApp ({ basePath, className }: Props): React.ReactElement<Props>
|
||||
? api.query.babe ? [] : ['forks']
|
||||
: ['node', 'forks']
|
||||
}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'chain',
|
||||
text: t('Chain info')
|
||||
},
|
||||
{
|
||||
hasParams: true,
|
||||
name: 'query',
|
||||
text: t('Block details')
|
||||
},
|
||||
{
|
||||
name: 'forks',
|
||||
text: t('Forks')
|
||||
},
|
||||
{
|
||||
name: 'node',
|
||||
text: t('Node info')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -2,27 +2,28 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AppProps, I18nProps } from '@polkadot/react-components/types';
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
|
||||
import Selection from './Selection';
|
||||
import translate from './translate';
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
interface Props extends AppProps, I18nProps {}
|
||||
export default function ExtrinsicsApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [{
|
||||
isRoot: true,
|
||||
name: 'create',
|
||||
text: t('Extrinsic submission')
|
||||
}], [t]);
|
||||
|
||||
function ExtrinsicsApp ({ basePath, t }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<main className='extrinsics--App'>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[{
|
||||
isRoot: true,
|
||||
name: 'create',
|
||||
text: t('Extrinsic submission')
|
||||
}]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Selection />
|
||||
@ -31,5 +32,3 @@ function ExtrinsicsApp ({ basePath, t }: Props): React.ReactElement<Props> {
|
||||
}
|
||||
|
||||
export { ExtrinsicsApp };
|
||||
|
||||
export default translate(ExtrinsicsApp);
|
||||
|
||||
@ -2,36 +2,39 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types';
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
|
||||
import Transfer from './Transfer';
|
||||
import Assets from './Assets';
|
||||
|
||||
import translate from './translate';
|
||||
import { useTranslation } from './translate';
|
||||
|
||||
interface Props extends AppProps, BareProps, I18nProps {}
|
||||
interface Props extends AppProps, BareProps {}
|
||||
|
||||
export default function AssetApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'assets',
|
||||
text: t('Assets')
|
||||
},
|
||||
{
|
||||
name: 'transfer',
|
||||
text: t('Transfer')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
function AssetApp ({ basePath, t }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<main className='treasury--App'>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'assets',
|
||||
text: t('Assets')
|
||||
},
|
||||
{
|
||||
name: 'transfer',
|
||||
text: t('Transfer')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
@ -41,5 +44,3 @@ function AssetApp ({ basePath, t }: Props): React.ReactElement<Props> {
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(AssetApp);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
|
||||
@ -15,19 +15,20 @@ interface Props extends AppProps, BareProps {}
|
||||
|
||||
export default function ParachainsApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Parachains overview')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Parachains overview')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
|
||||
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
||||
@ -21,6 +21,17 @@ const hidden = uiSettings.uiMode === 'full'
|
||||
|
||||
export default function SettingsApp ({ basePath, onStatusChange }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'general',
|
||||
text: t('General')
|
||||
},
|
||||
{
|
||||
name: 'developer',
|
||||
text: t('Developer')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className='settings--App'>
|
||||
@ -29,17 +40,7 @@ export default function SettingsApp ({ basePath, onStatusChange }: Props): React
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
hidden={hidden}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'general',
|
||||
text: t('General')
|
||||
},
|
||||
{
|
||||
name: 'developer',
|
||||
text: t('Developer')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
|
||||
@ -15,19 +15,20 @@ interface Props extends AppProps, BareProps {}
|
||||
|
||||
export default function SocietyApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Society overview')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className={className}>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Society overview')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -2,18 +2,17 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { I18nProps } from '@polkadot/react-components/types';
|
||||
import { KeypairType } from '@polkadot/util-crypto/types';
|
||||
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import React, { useContext, useEffect, useMemo, useState } from 'react';
|
||||
import { Button, Dropdown, Icon, Input, Modal, StatusContext } from '@polkadot/react-components';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import { assert, u8aToHex } from '@polkadot/util';
|
||||
import { keyExtractSuri, mnemonicValidate } from '@polkadot/util-crypto';
|
||||
|
||||
import translate from '../../translate';
|
||||
import { useTranslation } from '../../translate';
|
||||
|
||||
interface Props extends I18nProps {
|
||||
interface Props {
|
||||
isOpen?: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
@ -28,17 +27,25 @@ const CRYPTO_MAP: Record<string, KeypairType[]> = {
|
||||
|
||||
const EMPTY_KEY = '0x';
|
||||
|
||||
function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<Props> | null {
|
||||
export default function InjectKeys ({ isOpen = true, onClose }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { queueRpc } = useContext(StatusContext);
|
||||
// this needs to align with what is set as the first value in `type`
|
||||
const [crypto, setCrypto] = useState<KeypairType>('sr25519');
|
||||
const [publicKey, setPublicKey] = useState(EMPTY_KEY);
|
||||
const [suri, setSuri] = useState('');
|
||||
const [type, setType] = useState('babe');
|
||||
const [keyType, setKeyType] = useState('babe');
|
||||
const keyTypeOpt = useMemo(() => [
|
||||
{ text: t('Aura'), value: 'aura' },
|
||||
{ text: t('Babe'), value: 'babe' },
|
||||
{ text: t('Grandpa'), value: 'gran' },
|
||||
{ text: t('I\'m Online'), value: 'imon' },
|
||||
{ text: t('Parachains'), value: 'para' }
|
||||
], [t]);
|
||||
|
||||
useEffect((): void => {
|
||||
setCrypto(CRYPTO_MAP[type][0]);
|
||||
}, [type]);
|
||||
setCrypto(CRYPTO_MAP[keyType][0]);
|
||||
}, [keyType]);
|
||||
|
||||
useEffect((): void => {
|
||||
try {
|
||||
@ -56,13 +63,12 @@ function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<P
|
||||
return null;
|
||||
}
|
||||
|
||||
const _onSubmit = (): void => {
|
||||
const _onSubmit = (): void =>
|
||||
queueRpc({
|
||||
rpc: { section: 'author', method: 'insertKey' } as any,
|
||||
values: [type, suri, publicKey]
|
||||
values: [keyType, suri, publicKey]
|
||||
});
|
||||
};
|
||||
const _cryptoOptions = CRYPTO_MAP[type].map((value): { text: string; value: KeypairType } => ({
|
||||
const _cryptoOptions = CRYPTO_MAP[keyType].map((value): { text: string; value: KeypairType } => ({
|
||||
text: value === 'ed25519'
|
||||
? t('ed25519, Edwards')
|
||||
: t('sr15519, Schnorrkel'),
|
||||
@ -83,15 +89,9 @@ function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<P
|
||||
/>
|
||||
<Dropdown
|
||||
label={t('key type to set')}
|
||||
onChange={setType}
|
||||
options={[
|
||||
{ text: t('Aura'), value: 'aura' },
|
||||
{ text: t('Babe'), value: 'babe' },
|
||||
{ text: t('Grandpa'), value: 'gran' },
|
||||
{ text: t('I\'m Online'), value: 'imon' },
|
||||
{ text: t('Parachains'), value: 'para' }
|
||||
]}
|
||||
value={type}
|
||||
onChange={setKeyType}
|
||||
options={keyTypeOpt}
|
||||
value={keyType}
|
||||
/>
|
||||
<Dropdown
|
||||
isDisabled={_cryptoOptions.length === 1}
|
||||
@ -120,5 +120,3 @@ function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<P
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default translate(InjectKeys);
|
||||
|
||||
@ -6,11 +6,10 @@ import { DerivedHeartbeats, DerivedStakingOverview } from '@polkadot/api-derive/
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import styled from 'styled-components';
|
||||
import { Option } from '@polkadot/types';
|
||||
import { HelpOverlay } from '@polkadot/react-components';
|
||||
import Tabs from '@polkadot/react-components/Tabs';
|
||||
import { useCall, useAccounts, useApi } from '@polkadot/react-hooks';
|
||||
@ -25,43 +24,51 @@ import { MAX_SESSIONS } from './constants';
|
||||
import { useTranslation } from './translate';
|
||||
import useSessionRewards from './useSessionRewards';
|
||||
|
||||
const EMPY_ACCOUNTS: string[] = [];
|
||||
const EMPTY_ALL: [string[], string[]] = [EMPY_ACCOUNTS, EMPY_ACCOUNTS];
|
||||
|
||||
function transformStakingControllers ([stashes, controllers]: [AccountId[], Option<AccountId>[]]): [string[], string[]] {
|
||||
return [
|
||||
stashes.map((accountId): string => accountId.toString()),
|
||||
controllers
|
||||
.filter((optId): boolean => optId.isSome)
|
||||
.map((accountId): string => accountId.unwrap().toString())
|
||||
];
|
||||
}
|
||||
|
||||
function StakingApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api, isSubstrateV2 } = useApi();
|
||||
const { api } = useApi();
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { pathname } = useLocation();
|
||||
const [next, setNext] = useState<string[]>([]);
|
||||
const [allStashes, allControllers] = (useCall<[string[], string[]]>(api.derive.staking.controllers, [], {
|
||||
defaultValue: EMPTY_ALL,
|
||||
transform: transformStakingControllers
|
||||
}) as [string[], string[]]);
|
||||
const allStashes = useCall<string[]>(api.derive.staking.controllers, [], {
|
||||
defaultValue: [],
|
||||
transform: ([stashes]: [AccountId[]]): string[] =>
|
||||
stashes.map((accountId): string => accountId.toString())
|
||||
}) as string[];
|
||||
const recentlyOnline = useCall<DerivedHeartbeats>(api.derive.imOnline.receivedHeartbeats, []);
|
||||
const stakingOverview = useCall<DerivedStakingOverview>(api.derive.staking.overview, []);
|
||||
const sessionRewards = useSessionRewards(MAX_SESSIONS);
|
||||
const hasQueries = hasAccounts && !!(api.query.imOnline?.authoredBlocks);
|
||||
const validators = stakingOverview?.validators;
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Staking overview')
|
||||
},
|
||||
{
|
||||
name: 'waiting',
|
||||
text: t('Waiting')
|
||||
},
|
||||
{
|
||||
name: 'returns',
|
||||
text: t('Returns')
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
text: t('Account actions')
|
||||
},
|
||||
{
|
||||
hasParams: true,
|
||||
name: 'query',
|
||||
text: t('Validator stats')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
useEffect((): void => {
|
||||
validators && setNext(
|
||||
isSubstrateV2
|
||||
// this is a V2 node currentValidators is a list of stashes
|
||||
? allStashes.filter((address): boolean => !validators.includes(address as any))
|
||||
// this is a V1 node currentValidators is a list of controllers
|
||||
: allControllers.filter((address): boolean => !validators.includes(address as any))
|
||||
stakingOverview && setNext(
|
||||
allStashes.filter((address): boolean => !stakingOverview.validators.includes(address as any))
|
||||
);
|
||||
}, [allControllers, allStashes, validators]);
|
||||
}, [allStashes, stakingOverview?.validators]);
|
||||
|
||||
return (
|
||||
<main className={`staking--App ${className}`}>
|
||||
@ -76,30 +83,7 @@ function StakingApp ({ basePath, className }: Props): React.ReactElement<Props>
|
||||
: ['query']
|
||||
: ['actions', 'query']
|
||||
}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Staking overview')
|
||||
},
|
||||
{
|
||||
name: 'waiting',
|
||||
text: t('Waiting')
|
||||
},
|
||||
{
|
||||
name: 'returns',
|
||||
text: t('Returns')
|
||||
},
|
||||
{
|
||||
name: 'actions',
|
||||
text: t('Account actions')
|
||||
},
|
||||
{
|
||||
hasParams: true,
|
||||
name: 'query',
|
||||
text: t('Validator stats')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Summary
|
||||
|
||||
@ -4,10 +4,9 @@
|
||||
|
||||
import { ComponentProps, QueryTypes, ParitalQueryTypes } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
import { useApi } from '@polkadot/react-hooks';
|
||||
|
||||
import Consts from './Consts';
|
||||
import Modules from './Modules';
|
||||
@ -23,7 +22,22 @@ let id = -1;
|
||||
|
||||
export default function Selection ({ basePath, onAdd }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { isSubstrateV2 } = useApi();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'modules',
|
||||
text: t('Storage')
|
||||
},
|
||||
{
|
||||
name: 'constants',
|
||||
text: t('Constants')
|
||||
},
|
||||
{
|
||||
name: 'raw',
|
||||
text: t('Raw storage')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
const _onAdd = (query: ParitalQueryTypes): void => onAdd({ ...query, id: ++id });
|
||||
const _renderComponent = (Component: React.ComponentType<ComponentProps>): () => React.ReactNode =>
|
||||
// eslint-disable-next-line react/display-name
|
||||
@ -34,26 +48,7 @@ export default function Selection ({ basePath, onAdd }: Props): React.ReactEleme
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
hidden={
|
||||
isSubstrateV2
|
||||
? []
|
||||
: ['constants']
|
||||
}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'modules',
|
||||
text: t('Storage')
|
||||
},
|
||||
{
|
||||
name: 'constants',
|
||||
text: t('Constants')
|
||||
},
|
||||
{
|
||||
name: 'raw',
|
||||
text: t('Raw storage')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
import { ComponentProps } from './types';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { Icon, Tabs } from '@polkadot/react-components';
|
||||
import { useCall, useAccounts, useApi } from '@polkadot/react-hooks';
|
||||
@ -22,6 +22,17 @@ export default function SudoApp ({ basePath }: Props): React.ReactElement<Props>
|
||||
const sudoKey = useCall<string>(api.query.sudo.key, [], { transform: (k): string => k.toString() });
|
||||
const { allAccounts } = useAccounts();
|
||||
const [isMine, setIsMine] = useState(false);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'index',
|
||||
text: t('Sudo access')
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
text: t('Set sudo key')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
useEffect((): void => {
|
||||
setIsMine(!!sudoKey && allAccounts.some((key): boolean => key === sudoKey));
|
||||
@ -45,17 +56,7 @@ export default function SudoApp ({ basePath }: Props): React.ReactElement<Props>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'index',
|
||||
text: t('Sudo access')
|
||||
},
|
||||
{
|
||||
name: 'key',
|
||||
text: t('Set sudo key')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
{isMine
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { AccountId, Hash } from '@polkadot/types/interfaces';
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { Tabs } from '@polkadot/react-components';
|
||||
@ -23,23 +23,24 @@ export default function TechCommApp ({ basePath, className }: Props): React.Reac
|
||||
const { api } = useApi();
|
||||
const members = useCall<AccountId[]>(api.query.technicalCommittee.members, []);
|
||||
const proposals = useCall<Hash[]>(api.query.technicalCommittee.proposals, []);
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Tech. committee')
|
||||
},
|
||||
{
|
||||
name: 'proposals',
|
||||
text: t('Proposals ({{count}})', { replace: { count: proposals?.length || 0 } })
|
||||
}
|
||||
], [proposals, t]);
|
||||
|
||||
return (
|
||||
<main className={className}>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Tech. committee')
|
||||
},
|
||||
{
|
||||
name: 'proposals',
|
||||
text: t('Proposals ({{count}})', { replace: { count: (proposals && proposals.length) || 0 } })
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps as Props } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import Tabs from '@polkadot/react-components/Tabs';
|
||||
import { useAccounts } from '@polkadot/react-hooks';
|
||||
@ -18,7 +18,7 @@ import { useTranslation } from './translate';
|
||||
export default function ToolboxApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { hasAccounts } = useAccounts();
|
||||
const tabs = [
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'rpc',
|
||||
@ -36,17 +36,19 @@ export default function ToolboxApp ({ basePath }: Props): React.ReactElement<Pro
|
||||
name: 'verify',
|
||||
text: t('Verify signature')
|
||||
}
|
||||
];
|
||||
const filteredTabs = hasAccounts
|
||||
? tabs
|
||||
: tabs.filter(({ name }): boolean => !['sign', 'verify'].includes(name));
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className='toolbox--App'>
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={filteredTabs}
|
||||
hidden={
|
||||
hasAccounts
|
||||
? []
|
||||
: ['sign', 'verify']
|
||||
}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -109,7 +109,7 @@ export default withMulti(
|
||||
['query.elections.members', {
|
||||
propName: 'threshold',
|
||||
transform: (value: [AccountId, BlockNumber][]): number =>
|
||||
1 + (value.length / 2)
|
||||
Math.ceil(value.length * 0.5)
|
||||
}]
|
||||
)
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import { DerivedCollectiveProposal } from '@polkadot/api-derive/types';
|
||||
import { ProposalIndex } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Button, Dropdown, InputAddress, Modal, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
|
||||
@ -21,21 +21,25 @@ export default function Submission ({ councilProposals, id, isDisabled }: Props)
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const councilThreshold = useCall<number>(api.query.electionsPhragmen?.members || api.query.elections.members, [], {
|
||||
transform: (value: any[]): number => (value.length / 2) + 1
|
||||
transform: (value: any[]): number =>
|
||||
Math.ceil(value.length * 0.5)
|
||||
});
|
||||
const [isOpen, toggleOpen] = useToggle();
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
const [councilType, setCouncilType] = useState('reject');
|
||||
const [hasProposals, setHasProposals] = useState(true);
|
||||
const councilTypeOpt = useMemo(() => [
|
||||
{ value: 'accept', text: t('Acceptance proposal to council') },
|
||||
{ value: 'reject', text: t('Rejection proposal to council') }
|
||||
], [t]);
|
||||
|
||||
useEffect((): void => {
|
||||
const available = councilProposals
|
||||
.map(({ votes }): number =>
|
||||
votes ? votes?.index.toNumber() : -1
|
||||
)
|
||||
.filter((index): boolean => index !== -1);
|
||||
|
||||
setHasProposals(!!available.length);
|
||||
setHasProposals(
|
||||
!!councilProposals
|
||||
.map(({ votes }): number => votes ? votes?.index.toNumber() : -1)
|
||||
.filter((index): boolean => index !== -1)
|
||||
.length
|
||||
);
|
||||
}, [councilProposals]);
|
||||
|
||||
if (hasProposals) {
|
||||
@ -61,10 +65,7 @@ export default function Submission ({ councilProposals, id, isDisabled }: Props)
|
||||
help={t('The type of council proposal to submit.')}
|
||||
label={t('council proposal type')}
|
||||
onChange={setCouncilType}
|
||||
options={[
|
||||
{ value: 'accept', text: t('Acceptance proposal to council') },
|
||||
{ value: 'reject', text: t('Rejection proposal to council') }
|
||||
]}
|
||||
options={councilTypeOpt}
|
||||
value={councilType}
|
||||
/>
|
||||
</Modal.Content>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import { AppProps, BareProps } from '@polkadot/react-components/types';
|
||||
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Route, Switch } from 'react-router';
|
||||
import { HelpOverlay, Tabs } from '@polkadot/react-components';
|
||||
|
||||
@ -19,6 +19,13 @@ interface Props extends AppProps, BareProps {}
|
||||
|
||||
export default function TreasuryApp ({ basePath }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Treasury overview')
|
||||
}
|
||||
], [t]);
|
||||
|
||||
return (
|
||||
<main className='treasury--App'>
|
||||
@ -26,13 +33,7 @@ export default function TreasuryApp ({ basePath }: Props): React.ReactElement<Pr
|
||||
<header>
|
||||
<Tabs
|
||||
basePath={basePath}
|
||||
items={[
|
||||
{
|
||||
isRoot: true,
|
||||
name: 'overview',
|
||||
text: t('Treasury overview')
|
||||
}
|
||||
]}
|
||||
items={items}
|
||||
/>
|
||||
</header>
|
||||
<Switch>
|
||||
|
||||
@ -12,11 +12,6 @@ import { Dropdown } from '@polkadot/react-components';
|
||||
import { useTranslation } from '../translate';
|
||||
import Bare from './Bare';
|
||||
|
||||
interface Option {
|
||||
text: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
function doChange (onChange?: (value: any) => void): (_: number) => void {
|
||||
return function (value: number): void {
|
||||
onChange && onChange({
|
||||
@ -28,13 +23,13 @@ function doChange (onChange?: (value: any) => void): (_: number) => void {
|
||||
|
||||
export default function Vote ({ className, defaultValue: { value }, isDisabled, isError, onChange, style, withLabel }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const optAye = useMemo((): Option[] => {
|
||||
const optAye = useMemo(() => {
|
||||
return [
|
||||
{ text: t('Nay'), value: 0 },
|
||||
{ text: t('Aye'), value: -1 }
|
||||
];
|
||||
}, [t]);
|
||||
const optConv = useMemo((): Option[] => {
|
||||
const optConv = useMemo(() => {
|
||||
return [
|
||||
{ text: t('None'), value: 0 },
|
||||
{ text: t('Locked1x'), value: 1 },
|
||||
|
||||
Loading…
Reference in New Issue
Block a user