Add header prop on Modal (#2025)

* Add header prop on Modal

* Bump API, fixed electionsPhragmen

* s/HEADER/header/
This commit is contained in:
Jaco Greeff 2019-12-09 23:35:12 +01:00 committed by GitHub
parent c77effb70f
commit 2f899cef4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 283 additions and 437 deletions

View File

@ -10,10 +10,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^0.99.0-beta.11",
"@polkadot/api-contract": "^0.99.0-beta.11",
"@polkadot/api": "^0.99.0-beta.13",
"@polkadot/api-contract": "^0.99.0-beta.13",
"@polkadot/keyring": "^1.7.1",
"@polkadot/types": "^0.99.0-beta.11",
"@polkadot/types": "^0.99.0-beta.13",
"@polkadot/util": "^1.7.1",
"@polkadot/util-crypto": "^1.7.1",
"babel-core": "^7.0.0-bridge.0",

View File

@ -67,9 +67,9 @@ export default function ({ address, onClose }: Props): React.ReactElement<Props>
return (
<Modal
className='app--accounts-Modal'
header={t('Backup account')}
open
>
<Modal.Header>{t('Backup account')}</Modal.Header>
<Content
address={address}
doBackup={_doBackup}

View File

@ -37,9 +37,9 @@ class ChangePass extends TxComponent<Props, State> {
return (
<Modal
className='app--accounts-Modal'
header={t('Change account password')}
open
>
<Modal.Header>{t('Change account password')}</Modal.Header>
{this.renderContent()}
{this.renderButtons()}
</Modal>

View File

@ -189,9 +189,9 @@ function Create ({ className, onClose, onStatusChange, seed: propsSeed, t, type:
return (
<Modal
className={className}
header={t('Add an account via seed')}
open
>
<Modal.Header>{t('Add an account via seed')}</Modal.Header>
{address && isConfirmationOpen && (
<CreateConfirmation
address={address}

View File

@ -18,10 +18,10 @@ interface Props extends I18nProps {
function CreateConfirmation ({ address, name, onClose, onCommit, t }: Props): React.ReactElement<Props> | null {
return (
<Modal open>
<Modal.Header>
{t('Important notice')}
</Modal.Header>
<Modal
header={t('Important notice')}
open
>
<Modal.Content>
<AddressRow
defaultName={name}

View File

@ -136,9 +136,9 @@ function Derive ({ className, from, onClose, t }: Props): React.ReactElement {
return (
<Modal
className={className}
header={t('Derive account from pair')}
open
>
<Modal.Header>{t('Derive account from pair')}</Modal.Header>
{address && isConfirmationOpen && (
<CreateConfirmation
address={address}

View File

@ -38,8 +38,10 @@ class Import extends TxComponent<Props, State> {
const { isFileValid, isPassValid } = this.state;
return (
<Modal open>
<Modal.Header>{t('Add via backup file')}</Modal.Header>
<Modal
header={t('Add via backup file')}
open
>
{this.renderInput()}
<Modal.Actions>
<Button.Group>

View File

@ -49,9 +49,9 @@ function QrModal ({ className, onClose, onStatusChange, t }: Props): React.React
return (
<Modal
className={className}
header={t('Add account via Qr')}
open
>
<Modal.Header>{t('Add account via Qr')}</Modal.Header>
<Modal.Content>
{
scanned

View File

@ -89,9 +89,9 @@ function Transfer ({ className, onClose, recipientId: propRecipientId, senderId:
return (
<Modal
className='app--accounts-Modal'
header={t('Send funds')}
open
>
<Modal.Header>{t('Send funds')}</Modal.Header>
<Modal.Content>
<div className={className}>
<InputAddress

View File

@ -77,8 +77,10 @@ function Create ({ onClose, onStatusChange, t }: Props): React.ReactElement<Prop
};
return (
<Modal open>
<Modal.Header>{t('Add an address')}</Modal.Header>
<Modal
header={t('Add an address')}
open
>
<Modal.Content>
<AddressRow
defaultName={name}

View File

@ -11,7 +11,7 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.7.5",
"@polkadot/api-contract": "^0.99.0-beta.11",
"@polkadot/api-contract": "^0.99.0-beta.13",
"@polkadot/react-components": "^0.38.0-beta.54"
}
}

View File

@ -113,12 +113,10 @@ function Call (props: Props): React.ReactElement<Props> | null {
return (
<Modal
className={[className || '', 'app--contracts-Modal'].join(' ')}
header={t('Call a contract')}
onClose={onClose}
open={isOpen}
>
<Modal.Header>
{t('Call a contract')}
</Modal.Header>
<Modal.Content>
{callContract && (
<div className='contracts--CallControls'>

View File

@ -54,12 +54,10 @@ class ContractModal<P extends ContractModalProps, S extends ContractModalState>
return (
<Modal
className='app--contracts-Modal'
header={t(this.headerText)}
onClose={this.onClose}
open={isOpen}
>
<Modal.Header>
{t(this.headerText)}
</Modal.Header>
<Modal.Content>
{this.renderContent()}
</Modal.Content>

View File

@ -24,12 +24,10 @@ function RemoveABI ({ code, onClose, onRemove, t }: Props): React.ReactElement<P
return (
<Modal
className='app--accounts-Modal'
header={t('Confirm ABI removal')}
onClose={onClose}
open
>
<Modal.Header>
{t('Confirm ABI removal')}
</Modal.Header>
<Modal.Content>
<CodeRow
code={code}

View File

@ -2,17 +2,15 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiProps } from '@polkadot/react-api/types';
import { AccountId, VoteIndex } from '@polkadot/types/interfaces';
import { Codec } from '@polkadot/types/types';
import { DerivedVoterPositions } from '@polkadot/api-derive/types';
import { ApiProps } from '@polkadot/react-api/types';
import { ComponentProps } from './types';
import BN from 'bn.js';
import React from 'react';
import { withApi } from '@polkadot/react-api';
import styled from 'styled-components';
import { createType } from '@polkadot/types';
import { registry, withCalls, withMulti } from '@polkadot/react-api';
import { AddressMini, Button, Toggle } from '@polkadot/react-components';
import TxModal, { TxModalState, TxModalProps } from '@polkadot/react-components/TxModal';
@ -21,32 +19,15 @@ import VoteValue from './VoteValue';
type VoteType = 'member' | 'runnerup' | 'candidate';
interface Props extends ApiProps, ComponentProps, TxModalProps {
voterPositions?: DerivedVoterPositions;
}
interface Props extends ApiProps, ComponentProps, TxModalProps {}
interface State extends TxModalState {
votes: Record<string, boolean>;
voteValue: BN;
// voterPositions: DerivedVoterPositions;
}
// const MAX_VOTES = 16;
// const AlreadyVoted = styled.article`
// display: flex;
// align-items: center;
// margin: 0.5rem 0;
// & > :first-child {
// flex: 1 1;
// }
// & > :not(:first-child) {
// margin: 0;
// }
// `;
const Candidates = styled.div`
display: flex;
flex-wrap: wrap;
@ -121,29 +102,17 @@ class Vote extends TxModal<Props, State> {
protected txMethod = (): string =>
this.props.api.tx.electionsPhragmen
? 'electionsPhragmen.vote'
: 'elections.setApprovals';
: 'elections.vote';
protected txParams = (): [boolean[] | null, VoteIndex, BN | null] | [string[], BN] => {
const { api, electionsInfo: { candidates, nextVoterSet, voteCount }, voterPositions } = this.props;
const { accountId, votes, voteValue } = this.state;
if (api.tx.electionsPhragmen) {
return [
Object.entries(votes).filter(([, vote]): boolean => vote).map(([accountId]): string => accountId),
voteValue
];
}
const approvals = candidates.map((accountId): boolean => votes[accountId.toString()] === true);
const { votes, voteValue } = this.state;
return [
approvals
? approvals.slice(0, 1 + approvals.lastIndexOf(true))
: [],
createType(registry, 'VoteIndex', voteCount),
voterPositions && accountId && voterPositions[accountId]
? voterPositions[accountId].setIndex
: nextVoterSet || null
Object
.entries(votes)
.filter(([, vote]): boolean => vote)
.map(([accountId]): string => accountId),
voteValue
];
}
@ -155,13 +124,11 @@ class Vote extends TxModal<Props, State> {
}
protected renderTrigger = (): React.ReactNode => {
const { api, electionsInfo: { candidates, members, runnersUp }, t } = this.props;
const available = api.tx.electionsPhragmen
? members
.map(([accountId]): AccountId => accountId)
.concat(runnersUp.map(([accountId]): AccountId => accountId))
.concat(candidates)
: candidates;
const { electionsInfo: { candidates, members, runnersUp }, t } = this.props;
const available = members
.map(([accountId]): AccountId => accountId)
.concat(runnersUp.map(([accountId]): AccountId => accountId))
.concat(candidates);
return (
<Button
@ -175,43 +142,20 @@ class Vote extends TxModal<Props, State> {
}
protected renderContent = (): React.ReactNode => {
const { api, electionsInfo: { candidates, members, runnersUp }, t } = this.props;
const { electionsInfo: { candidates, members, runnersUp }, t } = this.props;
const { accountId, votes } = this.state;
const _candidates = candidates.map((accountId): [AccountId, VoteType] => [accountId, 'candidate']);
const available = api.tx.electionsPhragmen
? members
.map(([accountId]): [AccountId, VoteType] => [accountId, 'member'])
.concat(runnersUp.map(([accountId]): [AccountId, VoteType] => [accountId, 'runnerup']))
.concat(_candidates)
: _candidates;
const available = members
.map(([accountId]): [AccountId, VoteType] => [accountId, 'member'])
.concat(runnersUp.map(([accountId]): [AccountId, VoteType] => [accountId, 'runnerup']))
.concat(_candidates);
return (
<>
{api.tx.electionsPhragmen && (
<VoteValue
accountId={accountId}
onChange={this.setVoteValue}
/>
)}
{/* {(oldApprovals && accountId && voterPositions && voterPositions[accountId]) && (
<AlreadyVoted className='warning padded'>
<div>
<Icon name='warning sign' />
{t('You have already voted in this round')}
</div>
<Button.Group>
<TxButton
accountId={accountId}
isNegative
label={t('Retract vote')}
icon='delete'
onSuccess={this.onRetractVote}
params={[voterPositions[accountId].globalIndex]}
tx='elections.retractVoter'
/>
</Button.Group>
</AlreadyVoted>
)} */}
<VoteValue
accountId={accountId}
onChange={this.setVoteValue}
/>
<Candidates>
{available.map(([accountId, type]): React.ReactNode => {
const key = accountId.toString();
@ -246,50 +190,20 @@ class Vote extends TxModal<Props, State> {
this.setState({ voteValue });
}
private fetchApprovals = (accountId: string | null): void => {
const { api, electionsInfo: { candidates, voteCount } } = this.props;
if (!accountId || !voteCount) {
return;
}
// FIXME This any is a mismatch in api-derive
api.derive.elections
.approvalsOfAt(accountId as any, voteCount)
.then((approvals: boolean[]): void => {
this.setState({
votes: candidates.reduce((votes: Record<string, boolean>, accountId, index): Record<string, boolean> => ({
...votes,
[accountId.toString()]: approvals[index] || false
}), {})
});
});
}
private fetchVotes = (accountId: string | null): void => {
const { api } = this.props;
if (!accountId || !api.tx.electionsPhragmen) {
return;
}
api.query.electionsPhragmen
.votesOf<[AccountId[]] & Codec>(accountId)
.then(([existingVotes]): void => {
existingVotes.forEach((accountId): void => {
this.onChangeVote(accountId.toString())(true);
});
});
}
protected onChangeAccount = (accountId: string | null): void => {
const { api } = this.props;
this.setState({ accountId });
api.tx.electionsPhragmen
? this.fetchVotes(accountId)
: this.fetchApprovals(accountId);
if (accountId) {
(api.query.electionsPhragmen || api.query.elections)
.votesOf<[AccountId[]] & Codec>(accountId)
.then(([existingVotes]): void => {
existingVotes.forEach((accountId): void => {
this.onChangeVote(accountId.toString())(true);
});
});
}
}
private onChangeVote = (accountId: string): (isChecked: boolean) => void =>
@ -303,10 +217,4 @@ class Vote extends TxModal<Props, State> {
}
}
export default withMulti(
Vote,
translate,
withCalls<Props>(
['derive.elections.voterPositions', { propName: 'voterPositions' }]
)
);
export default translate(withApi(Vote));

View File

@ -39,9 +39,9 @@ function PreImage ({ className, onClose, t }: Props): React.ReactElement<Props>
return (
<Modal
className={className}
header={t('Submit preimage')}
open
>
<Modal.Header>{t('Submit preimage')}</Modal.Header>
<Modal.Content>
<InputAddress
help={t('The account you want to register the preimage from')}

View File

@ -32,11 +32,7 @@ function ProposalCell ({ className, proposal, proposalHash, t }: Props): React.R
<td className={`${className} all`}>
<div>{section}.{method}</div>
<details>
<summary>{
meta && meta.documentation
? meta.documentation.join(' ')
: t('Details')
}</summary>
<summary>{meta?.documentation.join(' ') || t('Details')}</summary>
<Call
labelHash={t('proposal hash')}
value={proposal}

View File

@ -29,9 +29,9 @@ function Propose ({ className, onClose, t }: Props): React.ReactElement<Props> {
return (
<Modal
className={className}
header={t('Submit proposal')}
open
>
<Modal.Header>{t('Submit proposal')}</Modal.Header>
<Modal.Content>
<InputAddress
help={t('The account you want to register the proposal from')}

View File

@ -33,10 +33,10 @@ function Seconding ({ depositors, proposalId, t }: Props): React.ReactElement<Pr
<>
{isSecondingOpen && (
<Modal
header={t('Second proposal')}
open
size='small'
>
<Modal.Header>{t('Second proposal')}</Modal.Header>
<Modal.Content>
<InputAddress
help={t('Select the account you wish to second with. This will lock your funds until the proposal is either approved or rejected')}

View File

@ -33,10 +33,10 @@ function Voting ({ referendumId, t }: Props): React.ReactElement<Props> | null {
<>
{isVotingOpen && (
<Modal
header={t('Vote on proposal')}
open
size='small'
>
<Modal.Header>{t('Vote on proposal')}</Modal.Header>
<Modal.Content>
<VoteAccount onChange={setAccountId} />
<VoteToggle

View File

@ -19,24 +19,6 @@ interface Props extends I18nProps {
value?: Extrinsic[] | null;
}
function renderSigner ({ t }: Props, extrinsic: Extrinsic): React.ReactNode {
if (!extrinsic.isSigned) {
return null;
}
return (
<div className='explorer--BlockByHash-header'>
<div>
<AddressMini value={extrinsic.signer} />
</div>
<div className='explorer--BlockByHash-nonce'>
{t('index')} {formatNumber(extrinsic.nonce)}
</div>
</div>
);
}
// FIXME This is _very_ similar to what we have in democracy/Item
function renderExtrinsic (props: Props, extrinsic: Extrinsic, index: number): React.ReactNode {
const { blockNumber, t } = props;
const { meta, method, section } = registry.findMetaCall(extrinsic.callIndex);
@ -57,14 +39,19 @@ function renderExtrinsic (props: Props, extrinsic: Extrinsic, index: number): Re
<h3>
{section}.{method}&nbsp;(#{formatNumber(index)})
</h3>
{renderSigner(props, extrinsic)}
{extrinsic.isSigned && (
<div className='explorer--BlockByHash-header'>
<div>
<AddressMini value={extrinsic.signer} />
</div>
<div className='explorer--BlockByHash-nonce'>
{t('index')} {formatNumber(extrinsic.nonce)}
</div>
</div>
)}
</div>
<details>
<summary>{
meta && meta.documentation
? meta.documentation.join(' ')
: t('Details')
}</summary>
<summary>{meta?.documentation.join(' ') || t('Details')}</summary>
<Call
className='details'
mortality={
@ -93,22 +80,8 @@ function renderExtrinsic (props: Props, extrinsic: Extrinsic, index: number): Re
);
}
function renderContent (props: Props): React.ReactNode {
const { value = [] } = props;
return (value || []).map((extrinsic, index): React.ReactNode => {
try {
return renderExtrinsic(props, extrinsic, index);
} catch (error) {
console.error(error);
return props.t('Unable to render extrinsic');
}
});
}
function Extrinsics (props: Props): React.ReactElement<Props> {
const { className, label, t } = props;
const { className, label, t, value } = props;
return (
<Column
@ -116,7 +89,15 @@ function Extrinsics (props: Props): React.ReactElement<Props> {
emptyText={t('No pending extrinsics are in the queue')}
headerText={label || t('extrinsics')}
>
{renderContent(props)}
{value?.map((extrinsic, index): React.ReactNode => {
try {
return renderExtrinsic(props, extrinsic, index);
} catch (error) {
console.error(error);
return props.t('Unable to render extrinsic');
}
})}
</Column>
);
}

View File

@ -28,8 +28,10 @@ function Create ({ onClose, onRegister, t }: Props): React.ReactElement<Props> {
};
return (
<Modal open>
<Modal.Header>{t('Register an Asset')}</Modal.Header>
<Modal
header={t('Register an Asset')}
open
>
<Modal.Content>
<InputNumber
help={t('Enter the Asset ID of the token you want to manage.')}

View File

@ -67,6 +67,7 @@ class BondExtra extends TxComponent<Props, State> {
return (
<Modal
className='staking--BondExtra'
header= {t('Bond more funds')}
open
size='small'
>
@ -103,36 +104,31 @@ class BondExtra extends TxComponent<Props, State> {
const isUnsafeChain = detectUnsafe(systemChain);
return (
<>
<Modal.Header>
{t('Bond more funds')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={stashId}
isDisabled
label={t('stash account')}
labelExtra={<Available label={transferrable} params={stashId} />}
/>
<InputBalance
autoFocus
className='medium'
help={t('Amount to add to the currently bonded funds. This is adjusted using the available funds on the account.')}
isError={!!amountError || !maxAdditional || maxAdditional.eqn(0)}
label={t('additional bonded funds')}
maxValue={maxBalance}
onChange={this.onChangeValue}
onEnter={this.sendTx}
withMax={!isUnsafeChain}
/>
<ValidateAmount
accountId={stashId}
onError={this.setAmountError}
value={maxAdditional}
/>
</Modal.Content>
</>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={stashId}
isDisabled
label={t('stash account')}
labelExtra={<Available label={transferrable} params={stashId} />}
/>
<InputBalance
autoFocus
className='medium'
help={t('Amount to add to the currently bonded funds. This is adjusted using the available funds on the account.')}
isError={!!amountError || !maxAdditional || maxAdditional.eqn(0)}
label={t('additional bonded funds')}
maxValue={maxBalance}
onChange={this.onChangeValue}
onEnter={this.sendTx}
withMax={!isUnsafeChain}
/>
<ValidateAmount
accountId={stashId}
onError={this.setAmountError}
value={maxAdditional}
/>
</Modal.Content>
);
}

View File

@ -71,12 +71,10 @@ function InjectKeys ({ isOpen = true, onClose, t }: Props): React.ReactElement<P
return (
<Modal
header={t('Inject Keys')}
open
size='small'
>
<Modal.Header>
{t('Inject Keys')}
</Modal.Header>
<Modal.Content>
<Input
isError={publicKey.length !== 66}

View File

@ -72,11 +72,9 @@ function Nominate ({ className, controllerId, nominees, onClose, stashId, stashO
return (
<Modal
className={`staking--Nominating ${className}`}
header={t('Nominate Validators')}
open
>
<Modal.Header>
{t('Nominate Validators')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'

View File

@ -44,12 +44,10 @@ class SetControllerAccount extends TxComponent<Props, State> {
return (
<Modal
className='staking--SetControllerAccount'
header={t('Change controller account')}
open
size='small'
>
<Modal.Header>
{t('Change controller account')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
{isValidating && (
<article className='warning'>

View File

@ -38,6 +38,7 @@ class SetRewardDestination extends TxComponent<Props, State> {
return (
<Modal
className='staking--Bonding'
header={t('Bonding Preferences')}
open
size='small'
>
@ -73,29 +74,24 @@ class SetRewardDestination extends TxComponent<Props, State> {
const { destination } = this.state;
return (
<>
<Modal.Header>
{t('Bonding Preferences')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
isDisabled
defaultValue={controllerId}
help={t('The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.')}
label={t('controller account')}
/>
<Dropdown
className='medium'
defaultValue={defaultDestination}
help={t('The destination account for any payments as either a nominator or validator')}
label={t('payment destination')}
onChange={this.onChangeDestination}
options={rewardDestinationOptions}
value={destination}
/>
</Modal.Content>
</>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
isDisabled
defaultValue={controllerId}
help={t('The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.')}
label={t('controller account')}
/>
<Dropdown
className='medium'
defaultValue={defaultDestination}
help={t('The destination account for any payments as either a nominator or validator')}
label={t('payment destination')}
onChange={this.onChangeDestination}
options={rewardDestinationOptions}
value={destination}
/>
</Modal.Content>
);
}

View File

@ -41,12 +41,10 @@ function SetSessionKey ({ controllerId, isOpen, onClose, sessionIds, stashId, t
return (
<Modal
className='staking--SetSessionAccount'
header={t('Set Session Key')}
open
size='small'
>
<Modal.Header>
{t('Set Session Key')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'

View File

@ -62,6 +62,7 @@ class Unbond extends TxComponent<Props, State> {
return (
<Modal
className='staking--Unbond'
header={t('Unbond funds')}
open
size='small'
>
@ -97,37 +98,32 @@ class Unbond extends TxComponent<Props, State> {
const { maxBalance } = this.state;
return (
<>
<Modal.Header>
{t('Unbond funds')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t('controller account')}
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t('controller account')}
/>
<BalanceWrapper>
<AddressInfo
accountId={stashId}
withBalance={{
bonded: true
}}
/>
<BalanceWrapper>
<AddressInfo
accountId={stashId}
withBalance={{
bonded: true
}}
/>
</BalanceWrapper>
<InputBalance
autoFocus
className='medium'
help={t('The amount of funds to unbond, this is adjusted using the bonded funds on the stash account.')}
label={t('unbond amount')}
maxValue={maxBalance}
onChange={this.onChangeValue}
onEnter={this.sendTx}
withMax
/>
</Modal.Content>
</>
</BalanceWrapper>
<InputBalance
autoFocus
className='medium'
help={t('The amount of funds to unbond, this is adjusted using the bonded funds on the stash account.')}
label={t('unbond amount')}
maxValue={maxBalance}
onChange={this.onChangeValue}
onEnter={this.sendTx}
withMax
/>
</Modal.Content>
);
}

View File

@ -74,7 +74,7 @@ class Validate extends TxComponent<Props, State> {
// }
public render (): React.ReactNode {
const { isOpen } = this.props;
const { isOpen, t } = this.props;
if (!isOpen) {
return null;
@ -83,6 +83,7 @@ class Validate extends TxComponent<Props, State> {
return (
<Modal
className='staking--Staking'
header={t('Set validator preferences')}
open
size='small'
>
@ -134,65 +135,60 @@ class Validate extends TxComponent<Props, State> {
const defaultThreshold = validatorPrefs && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold && (validatorPrefs as ValidatorPrefsTo145).unstakeThreshold.toBn();
return (
<>
<Modal.Header>
{t('Set validator preferences')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={stashId.toString()}
isDisabled
label={t('stash account')}
/>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t('controller account')}
/>
{!isSubstrateV2 && (
<>
<InputNumber
autoFocus
bitLength={32}
className='medium'
defaultValue={defaultThreshold}
help={t('The number of time this validator can get slashed before being automatically unstaked (maximum of 10 allowed)')}
isError={!!unstakeThresholdError}
label={t('automatic unstake threshold')}
onChange={this.onChangeThreshold}
onEnter={this.sendTx}
/>
<InputValidationUnstakeThreshold
onError={this.onUnstakeThresholdError}
unstakeThreshold={unstakeThreshold}
/>
</>
)}
{
hasCommission
? <InputNumber
className='medium'
help={t('The percentage reward (0-100) that should be applied for the validator')}
isZeroable
label={t('reward commission percentage')}
maxValue={MAX_COMM}
onChange={this.onChangeCommission}
onEnter={this.sendTx}
/>
: <InputBalance
className='medium'
defaultValue={(validatorPrefs as ValidatorPrefsTo196)?.validatorPayment?.toBn()}
help={t('Amount taken up-front from the reward by the validator before splitting the remainder between themselves and the nominators')}
isZeroable
label={t('validator payment')}
onChange={this.onChangePayment}
onEnter={this.sendTx}
/>
}
</Modal.Content>
</>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={stashId.toString()}
isDisabled
label={t('stash account')}
/>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t('controller account')}
/>
{!isSubstrateV2 && (
<>
<InputNumber
autoFocus
bitLength={32}
className='medium'
defaultValue={defaultThreshold}
help={t('The number of time this validator can get slashed before being automatically unstaked (maximum of 10 allowed)')}
isError={!!unstakeThresholdError}
label={t('automatic unstake threshold')}
onChange={this.onChangeThreshold}
onEnter={this.sendTx}
/>
<InputValidationUnstakeThreshold
onError={this.onUnstakeThresholdError}
unstakeThreshold={unstakeThreshold}
/>
</>
)}
{
hasCommission
? <InputNumber
className='medium'
help={t('The percentage reward (0-100) that should be applied for the validator')}
isZeroable
label={t('reward commission percentage')}
maxValue={MAX_COMM}
onChange={this.onChangeCommission}
onEnter={this.sendTx}
/>
: <InputBalance
className='medium'
defaultValue={(validatorPrefs as ValidatorPrefsTo196)?.validatorPayment?.toBn()}
help={t('Amount taken up-front from the reward by the validator before splitting the remainder between themselves and the nominators')}
isZeroable
label={t('validator payment')}
onChange={this.onChangePayment}
onEnter={this.sendTx}
/>
}
</Modal.Content>
);
}

View File

@ -58,12 +58,10 @@ class NewStake extends TxComponent<Props, State> {
return (
<Modal
className='staking--Bonding'
header={t('Bonding Preferences')}
open
size='small'
>
<Modal.Header>
{t('Bonding Preferences')}
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'

View File

@ -41,7 +41,7 @@ function Consts ({ onAdd, t }: Props): React.ReactElement<Props> {
defaultValue={defaultValue}
label={t('selected constant query')}
onChange={setValue}
help={meta && meta.documentation && meta.documentation.join(' ')}
help={meta?.documentation.join(' ')}
/>
</div>
<div className='storage--actionrow-buttons'>

View File

@ -91,7 +91,7 @@ function Modules ({ onAdd, t }: Props): React.ReactElement<Props> {
defaultValue={api.query.timestamp.now}
label={t('selected state query')}
onChange={_onChangeKey}
help={meta && meta.documentation && meta.documentation.join(' ')}
help={meta?.documentation.join(' ')}
/>
<Params
key={`${section}.${method}:params` /* force re-render on change */}

View File

@ -34,10 +34,10 @@ function Voting ({ hash, proposalId, t }: Props): React.ReactElement<Props> | nu
<>
{isVotingOpen && (
<Modal
header={t('Vote on proposal')}
open
size='small'
>
<Modal.Header>{t('Vote on proposal')}</Modal.Header>
<Modal.Content>
<VoteAccount onChange={setAccountId} />
<VoteToggle

View File

@ -45,11 +45,9 @@ class Unlock extends TxComponent<Props, State> {
return (
<Modal
className='toolbox--Unlock'
header={t('Unlock account')}
open
>
<Modal.Header>
{t('Unlock account')}
</Modal.Header>
{this.renderContent()}
{this.renderActions()}
</Modal>

View File

@ -64,10 +64,10 @@ function Voting ({ proposals, t }: Props): React.ReactElement<Props> | null {
<>
{isVotingOpen && (
<Modal
header={t('Vote on proposal')}
open
size='small'
>
<Modal.Header>{t('Vote on proposal')}</Modal.Header>
<Modal.Content>
<VoteAccount onChange={setAccountId} />
<Dropdown

View File

@ -18,9 +18,9 @@ function NetworkModal ({ className, onClose, t }: Props): React.ReactElement<Pro
return (
<Modal
className={className}
header={t('Select Network')}
open
>
<Modal.Header>{t('Select Network')}</Modal.Header>
<Modal.Content>
<General
isModalContent

View File

@ -31,7 +31,7 @@
"homepage": "https://github.com/polkadot-js/ui/tree/master/packages/ui-reactive#readme",
"dependencies": {
"@babel/runtime": "^7.7.5",
"@polkadot/api": "^0.99.0-beta.11",
"@polkadot/api": "^0.99.0-beta.13",
"@polkadot/extension-dapp": "^0.14.0-beta.9",
"edgeware-node-types": "^1.0.10",
"rxjs-compat": "^6.5.3"

View File

@ -190,7 +190,7 @@ export default function withCall<P extends ApiProps> (endpoint: string, {
const meta = apiSection[method].meta;
if (area === 'query' && meta && meta.type.isMap) {
if (area === 'query' && meta?.type.isMap) {
const arg = newParams[0];
assert((!isUndefined(arg) && !isNull(arg)) || meta.type.asMap.kind.isLinkedMap, `${meta.name} expects one argument`);

View File

@ -77,7 +77,7 @@ export default function ExtrinsicDisplay ({ defaultValue, isDisabled, isError, i
label={label}
onChange={_onChangeMethod}
withLabel={withLabel}
help={meta && meta.documentation && meta.documentation.join(' ')}
help={meta?.documentation.join(' ')}
/>
<Params
key={`${section}.${method}:params` /* force re-render on change */}

View File

@ -98,15 +98,11 @@ function Forget (props: Props): React.ReactElement<Props> {
return (
<Modal
className='app--accounts-Modal'
header={getHeaderText(props)}
onClose={onClose}
open
>
<Modal.Header>
{getHeaderText(props)}
</Modal.Header>
<Modal.Content>
{renderContent(props)}
</Modal.Content>
<Modal.Content>{renderContent(props)}</Modal.Content>
<Modal.Actions>
<Button.Group>
<Button

View File

@ -23,6 +23,7 @@ function Modal (props: Props): React.ReactElement<Props> {
{...props}
className={classes('theme--default', 'ui--Modal', className)}
dimmer='inverted'
header={undefined}
>
{header && (
<SUIModal.Header>{header}</SUIModal.Header>

View File

@ -55,7 +55,7 @@ function ProposedAction (props: Props): React.ReactElement<Props> {
const { meta, method, section } = registry.findMetaCall(proposal.callIndex);
const header = `#${idNumber}: ${section}.${method}`;
const documentation = (meta && meta.documentation)
const documentation = meta?.documentation
? (
<summary>{meta.documentation.join(' ')}</summary>
)

View File

@ -37,12 +37,10 @@ export default class TxModal<P extends TxModalProps, S extends TxModalState> ext
{this.renderTrigger && this.renderTrigger()}
<Modal
className='ui--Modal'
header={this.headerText()}
onClose={this.hideModal}
open={isOpen}
>
<Modal.Header>
{this.headerText()}
</Modal.Header>
<Modal.Content>
{this.renderPreContent()}
{this.renderInputAccount()}

View File

@ -88,6 +88,7 @@ function TxModal<P extends Props> ({
const allModalProps = {
className: ['ui--Modal', modalProps.className || ''].join(' '),
dimmer: 'inverted',
header,
...modalProps,
onClose,
open: isOpen
@ -97,9 +98,6 @@ function TxModal<P extends Props> ({
<>
{Trigger ? <Trigger onOpen={onOpen} /> : null}
<Modal {...allModalProps}>
<Modal.Header>
{header}
</Modal.Header>
<Modal.Content>
{preContent}
<InputAddress

View File

@ -33,11 +33,7 @@ function Transaction ({ children, hideDetails, isSendable, value: { accountId, e
<>
<Modal.Header>
{section}.{method}
<label><details><summary>{
meta && meta.documentation
? meta.documentation.join(' ')
: ''
}</summary></details></label>
<label><details><summary>{meta?.documentation.join(' ') || t('Details')}</summary></details></label>
</Modal.Header>
<Modal.Content className='ui--signer-Signer-Content'>
{!hideDetails && (

View File

@ -2044,35 +2044,35 @@
dependencies:
"@types/node" ">= 8"
"@polkadot/api-contract@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.99.0-beta.11.tgz#0cd0ae086df816331e5b23bed444ce0ac0dc17f5"
integrity sha512-uj8azbdTr6M75QVQhVKeOOc+u4MMnJv02MsU1V30VHuSVlcjSqJeLgGTNKA/YkchaZGgd2jk59mtaisI/mtclg==
"@polkadot/api-contract@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/api-contract/-/api-contract-0.99.0-beta.13.tgz#6020d04034c1f6c309d514aa2a661f26235f2f0b"
integrity sha512-eGFJ9LdOzbKmQzbxI3NLrF4Rnwe7P/MImq7MtmKBNOWD9mf+Bxg81+74EHCu4ijizuUjTAmtLIf9C2w+r1vaqQ==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/types" "^0.99.0-beta.11"
"@polkadot/types" "^0.99.0-beta.13"
"@polkadot/api-derive@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.99.0-beta.11.tgz#b4d7a6df49d960d4b29be16a1d5b15b09764e2d2"
integrity sha512-pLQkIPO7Z1zBuE1TX6Lerb39itYRs41wm5lE+yGFVvlCprwXr6Z9WXQRo80gIbYJDA+PUNXGyoblGKFuGCvmCg==
"@polkadot/api-derive@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-0.99.0-beta.13.tgz#347ebc6ad7ca8a5491e2bff8c9045b8709484189"
integrity sha512-0D9dr3+KsFPvUZ3uQkL7a4nbfdtI3cmcIqGYXqPxmsiTacn0FQR1rN3j9yQa+rIHLIKPjBlpcQXXFAm2xxrPtA==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/api" "^0.99.0-beta.11"
"@polkadot/types" "^0.99.0-beta.11"
"@polkadot/api" "^0.99.0-beta.13"
"@polkadot/types" "^0.99.0-beta.13"
"@polkadot/api@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.99.0-beta.11.tgz#781dc1405adceca52cd17afdfeeed90fc243e1da"
integrity sha512-gM0rov3xYEox3NoVRnmWfm6cLHRKvsSrr8RnO9xyDiWKcUH1f6CfOSHN49Bsxcin6MlhYoL80N5RvRVJQYg4MQ==
"@polkadot/api@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-0.99.0-beta.13.tgz#eab4ee8d838f7fa000b14cb279b9aa50dd62f904"
integrity sha512-GOrvZvRkoiYIJy8I+9wGHdMsg7A4p5gsPphkTSViy0umeiKbGPg3yxLAm82DJsPoFiXaU1lf+CKQbT40YBYpyQ==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/api-derive" "^0.99.0-beta.11"
"@polkadot/api-derive" "^0.99.0-beta.13"
"@polkadot/keyring" "^1.7.1"
"@polkadot/metadata" "^0.99.0-beta.11"
"@polkadot/rpc-core" "^0.99.0-beta.11"
"@polkadot/rpc-provider" "^0.99.0-beta.11"
"@polkadot/types" "^0.99.0-beta.11"
"@polkadot/metadata" "^0.99.0-beta.13"
"@polkadot/rpc-core" "^0.99.0-beta.13"
"@polkadot/rpc-provider" "^0.99.0-beta.13"
"@polkadot/types" "^0.99.0-beta.13"
"@polkadot/util-crypto" "^1.7.1"
"@polkadot/dev-react@^0.32.0-beta.17":
@ -2177,10 +2177,10 @@
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/jsonrpc@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.99.0-beta.11.tgz#43f0849f395a5e012629bf0ef65ca3e9d8d9771c"
integrity sha512-wZ8vl2feOuOOi8gghnlIjdCfbCW8MbXXgUgC6SEQAn1UhlxE3OFvSLhjzHA1oKNXnBmvtxdLvKwh5w16McubCA==
"@polkadot/jsonrpc@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.99.0-beta.13.tgz#8c92b9a7b3449601a6175fbfb0ab6aaa652bb580"
integrity sha512-mVfSWAeCihBj50IoNGPsPglqtPdE2ahy7dSbOoEhmHhnoOxnbmyd/izt/Nj0OakDWMeXOphXAfX/C9c5HM9KhQ==
dependencies:
"@babel/runtime" "^7.7.5"
@ -2193,13 +2193,13 @@
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
"@polkadot/metadata@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-0.99.0-beta.11.tgz#c2e7fdba62b336b20178b633ce1092d7b5eb4190"
integrity sha512-Li6xi+KK7muvzOBib2s830na+PhbAuG4Mti9TrUgWK/hk7JxYZGBw3RwHvXT7P1kaYXrCIexQVEYP+B5W34q4A==
"@polkadot/metadata@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-0.99.0-beta.13.tgz#1f370a34aac9d1a03367659735ffc11b66a470ae"
integrity sha512-tTN3x+wmomq/bKxBEB0sJJCkiqr2nCymDDx9W/UbI+kPBhlWpdJ6OO3AGkDmdYwV8RSSK+71q3A57kTntB3n3Q==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/types" "^0.99.0-beta.11"
"@polkadot/types" "^0.99.0-beta.13"
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
@ -2228,25 +2228,25 @@
qrcode-generator "^1.4.4"
react-qr-reader "^2.2.1"
"@polkadot/rpc-core@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.99.0-beta.11.tgz#7a4ef79f00387a337e5da0b24367aadd44f0df31"
integrity sha512-dri7vdrSlRtUNERNxshH3hFyX5aHfB+TtjYP0rmYWwsWkdI0c+RdvTkgdM/I3bsdjU5622G2qm+w9RDXSO1NhQ==
"@polkadot/rpc-core@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-0.99.0-beta.13.tgz#d2edcc86f35360c85b782951f5d2e5bcc2fd21cb"
integrity sha512-uORlJKZh4PvkLgiWcuZmsVYrSuXF04jd95wFzaB8VIxm60q0c7tu40rs9QyPkggSE/rj6xdhu4syjP58iD18cw==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/jsonrpc" "^0.99.0-beta.11"
"@polkadot/rpc-provider" "^0.99.0-beta.11"
"@polkadot/types" "^0.99.0-beta.11"
"@polkadot/jsonrpc" "^0.99.0-beta.13"
"@polkadot/rpc-provider" "^0.99.0-beta.13"
"@polkadot/types" "^0.99.0-beta.13"
"@polkadot/util" "^1.7.1"
rxjs "^6.5.3"
"@polkadot/rpc-provider@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.99.0-beta.11.tgz#d3b022c0489c13bf52213fdc521609dbcf87681e"
integrity sha512-ssR9sTicJvvkV60Fq9P5wHWo2gYHtOCBiA0v96PquZVyu2f5hZepatSlGSO7Rx72Z2Nr+ntvEfivQo2ue9r+/w==
"@polkadot/rpc-provider@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-0.99.0-beta.13.tgz#00de8fab8b6c4089a95e9faf299246c9b32e0b35"
integrity sha512-yQxPtiLID9N4rjWjKg67UFpUzyZVH7ms3RQ82fVBfNXo7/y3N8e8P8o/6ny+yzMdkQ4Bz1J6jTwYjW2hx+CEGw==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/metadata" "^0.99.0-beta.11"
"@polkadot/metadata" "^0.99.0-beta.13"
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
eventemitter3 "^4.0.0"
@ -2260,13 +2260,13 @@
dependencies:
"@types/chrome" "^0.0.91"
"@polkadot/types@^0.99.0-beta.11":
version "0.99.0-beta.11"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.99.0-beta.11.tgz#eed812c1ef9c315394cafc6fc06f94a82a3898bf"
integrity sha512-Fb2aJ0xUuVQUUFpur8AwK0QgGBakVWjruhbWKFYo2xSUT9xVelpgUhF+7PUYAhL6w/uXaiuSPSeTX3L0KTHqsg==
"@polkadot/types@^0.99.0-beta.13":
version "0.99.0-beta.13"
resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-0.99.0-beta.13.tgz#a7332127109f3d9b09561622cd79f90519418d26"
integrity sha512-8hr6azJuqttDA1InDrTJDgLZbtplE7Fo2Dtfkm+YR7O6QosCKoBRxTZB62whqy9xc4vAv4wcR4ymdcGpIpXhyQ==
dependencies:
"@babel/runtime" "^7.7.5"
"@polkadot/metadata" "^0.99.0-beta.11"
"@polkadot/metadata" "^0.99.0-beta.13"
"@polkadot/util" "^1.7.1"
"@polkadot/util-crypto" "^1.7.1"
"@types/memoizee" "^0.4.3"