Modal columns for democracy modals (#2654)

This commit is contained in:
Jaco Greeff 2020-04-29 10:26:00 +02:00 committed by GitHub
parent 6b4a8a2f77
commit 2b2b7d3695
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 167 additions and 126 deletions

View File

@ -8,6 +8,7 @@
"No active referendums": "No active referendums",
"No external proposal": "No external proposal",
"Nothing queued for execution": "Nothing queued for execution",
"Only applicable if the proposal has already passed and is ready for dispatch.": "Only applicable if the proposal has already passed and is ready for dispatch.",
"Preimage": "Preimage",
"Register the vote for or against the proposal.": "Register the vote for or against the proposal.",
"Second": "Second",
@ -21,17 +22,20 @@
"The account you want to register the proposal from": "The account you want to register the proposal from",
"The amount this total can be reduced by to change the referendum outcome. This assumes changes to the convictions of the existing votes, with no additional turnout.": "The amount this total can be reduced by to change the referendum outcome. This assumes changes to the convictions of the existing votes, with no additional turnout.",
"The amount this total should be increased by to change the referendum outcome. This assumes additional turnout with new votes at 1x conviction.": "The amount this total should be increased by to change the referendum outcome. This assumes additional turnout with new votes at 1x conviction.",
"The balance associated with the vote will be locked as per the conviction specified nd will not be available for transfer or spend during this period.": "The balance associated with the vote will be locked as per the conviction specified nd will not be available for transfer or spend during this period.",
"The balance associated with the vote will be locked as per the conviction specified and will not be available for transfer during this period.": "The balance associated with the vote will be locked as per the conviction specified and will not be available for transfer during this period.",
"The conviction to use for this vote, with an appropriate lock period.": "The conviction to use for this vote, with an appropriate lock period.",
"The delay period to apply in blocks": "The delay period to apply in blocks",
"The external proposal to send to the technical committee": "The external proposal to send to the technical committee",
"The hash of the selected proposal, use it for submitting the proposal": "The hash of the selected proposal, use it for submitting the proposal",
"The image (proposal) will be stored on-chain against the hash of the contents.": "The image (proposal) will be stored on-chain against the hash of the contents.",
"The locked value for this proposal": "The locked value for this proposal",
"The preimage hash of the proposal": "The preimage hash of the proposal",
"The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.": "The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.",
"The voting period to apply in blocks": "The voting period to apply in blocks",
"This account will pay the fees for the preimage, based on the size thereof.": "This account will pay the fees for the preimage, based on the size thereof.",
"Vote": "Vote",
"Vote on proposal": "Vote on proposal",
"When submitting a proposal the hash needs to be known. Proposals can be submitted with hash-only, but upon dispatch the preimage needs to be available.": "When submitting a proposal the hash needs to be known. Proposals can be submitted with hash-only, but upon dispatch the preimage needs to be available.",
"activate": "activate",
"aye": "aye",
"conviction": "conviction",

View File

@ -17,6 +17,7 @@
"Changing the key only takes effect at the start of the next session. The input here is generates from the author_rotateKeys command": "Changing the key only takes effect at the start of the next session. The input here is generates from the author_rotateKeys command",
"Display overview information for the selected validator, including blocks produced.": "Display overview information for the selected validator, including blocks produced.",
"Distinct stash and controller accounts are recommended to ensure fund security. You will be allowed to make the transaction, but take care to not tie up all funds, only use a portion of the available funds during this period.": "Distinct stash and controller accounts are recommended to ensure fund security. You will be allowed to make the transaction, but take care to not tie up all funds, only use a portion of the available funds during this period.",
"Ensure that not all funds are locked, funds need to be available for fees.": "Ensure that not all funds are locked, funds need to be available for fees.",
"Filter available candidates based on name, address or short account index.": "Filter available candidates based on name, address or short account index.",
"For fund security, your session key should not match your stash key.": "For fund security, your session key should not match your stash key.",
"Grandpa": "Grandpa",
@ -55,6 +56,7 @@
"Set nominees": "Set nominees",
"Set reward destination": "Set reward destination",
"Set validator preferences": "Set validator preferences",
"Since this transaction deals with funding, the stash account will be used.": "Since this transaction deals with funding, the stash account will be used.",
"Staking overview": "Staking overview",
"Stop": "Stop",
"Submit key": "Submit key",
@ -65,13 +67,16 @@
"The amount placed at-stake should be no more that 95% of your available amount to protect against slashing events.": "The amount placed at-stake should be no more that 95% of your available amount to protect against slashing events.",
"The amount that will be used on a per-validator basis to calculate profits for that validator.": "The amount that will be used on a per-validator basis to calculate profits for that validator.",
"The auto-selection is done on the current profitability of the validators taking your favorites into account. It is adjusted based on the commission and current range of backing for the validator. The calculation may and will change over time, so it is rather a selection based on the current state of the network, not a predictor of future profitability.": "The auto-selection is done on the current profitability of the validators taking your favorites into account. It is adjusted based on the commission and current range of backing for the validator. The calculation may and will change over time, so it is rather a selection based on the current state of the network, not a predictor of future profitability.",
"The bonding duration for any staked funds. After this period needs to be withdrawn.": "The bonding duration for any staked funds. After this period needs to be withdrawn.",
"The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.": "The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.",
"The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.": "The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.",
"The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.": "The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.",
"The destination account for any payments as either a nominator or validator": "The destination account for any payments as either a nominator or validator",
"The funds will only be available for withdrawal after the unbonding period, however will not be part of the staked amount after the next validator election. You can follow the unlock countdown in the UI.": "The funds will only be available for withdrawal after the unbonding period, however will not be part of the staked amount after the next validator election. You can follow the unlock countdown in the UI.",
"The percentage reward (0-100) that should be applied for the validator": "The percentage reward (0-100) that should be applied for the validator",
"The selected validators to nominate, either via the \"currently best algorithm\" or via a manual selection.": "The selected validators to nominate, either via the \"currently best algorithm\" or via a manual selection.",
"The specified value is greater than your free balance. The node will bond the maximum amount available.": "The specified value is greater than your free balance. The node will bond the maximum amount available.",
"The stash and controller pair, here the controller will be used to send the transaction.": "The stash and controller pair, here the controller will be used to send the transaction.",
"The stash that is to be affected. The transaction will be sent from the associated controller account.": "The stash that is to be affected. The transaction will be sent from the associated controller account.",
"The total amount of the stash balance that will be at stake in any forthcoming rounds (should be less than the total amount available)": "The total amount of the stash balance that will be at stake in any forthcoming rounds (should be less than the total amount available)",
"There is currently an ongoing election for new validator candidates. As such staking operations are not permitted.": "There is currently an ongoing election for new validator candidates. As such staking operations are not permitted.",
@ -135,7 +140,6 @@
"total issuance": "total issuance",
"total stake": "total stake",
"total staked": "total staked",
"transferrable": "transferrable",
"unbond amount": "unbond amount",
"validator to query": "validator to query",
"validators": "validators",

View File

@ -127,6 +127,7 @@
"Either approve or reject this call.": "",
"Endorse": "",
"Endorsements ({{count}})": "",
"Ensure that not all funds are locked, funds need to be available for fees.": "",
"Enter the Asset ID of the token you want to manage.": "",
"Enter the Asset ID of the token you want to transfer.": "",
"Erroneous": "",
@ -247,6 +248,7 @@
"Once bonded, it wil need to be unlocked/withdrawn and will be locked for at least the bonding duration.": "",
"Once transmitted the new selection will only take effect in 2 eras since the selection criteria for the next era was done at the end of the previous era. Until then, the nominations will show as inactive.": "",
"One of your available nomination accounts, keyed by the stash. The transaction will be sent from the controller.": "",
"Only applicable if the proposal has already passed and is ready for dispatch.": "",
"Override the default identity icon display with a specific theme": "",
"Override the default ss58 prefix for address generation": "",
"Owned": "",
@ -354,6 +356,7 @@
"Sign via Qr": "",
"Sign via {{hardwareType}}": "",
"Signed transaction": "",
"Since this transaction deals with funding, the stash account will be used.": "",
"Skeptics": "",
"Society": "",
"Society overview": "",
@ -412,8 +415,9 @@
"The amount this total can be reduced by to change the referendum outcome. This assumes changes to the convictions of the existing votes, with no additional turnout.": "",
"The amount this total should be increased by to change the referendum outcome. This assumes additional turnout with new votes at 1x conviction.": "",
"The auto-selection is done on the current profitability of the validators taking your favorites into account. It is adjusted based on the commission and current range of backing for the validator. The calculation may and will change over time, so it is rather a selection based on the current state of the network, not a predictor of future profitability.": "",
"The balance associated with the vote will be locked as per the conviction specified nd will not be available for transfer or spend during this period.": "",
"The balance associated with the vote will be locked as per the conviction specified and will not be available for transfer during this period.": "",
"The blake2b 256-bit hash of the actual input data.": "",
"The bonding duration for any staked funds. After this period needs to be withdrawn.": "",
"The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.": "",
"The call hashes that have not been executed as of yet.": "",
"The code hash for the on-chain deployed code.": "",
@ -439,10 +443,12 @@
"The existing account password as specified when this account was created or when it was last changed.": "",
"The external proposal to send to the technical committee": "",
"The final recipient balance is less or equal to {{existentialDeposit}} (the existential amount) and will not be reflected": "",
"The funds will only be available for withdrawal after the unbonding period, however will not be part of the staked amount after the next validator election. You can follow the unlock countdown in the UI.": "",
"The hash for the proposal this vote applies to": "",
"The hash of the selected proposal, use it for submitting the proposal": "",
"The id number to assign to this parachain.": "",
"The id of the parachain to be deregistered.": "",
"The image (proposal) will be stored on-chain against the hash of the contents.": "",
"The initial head state for the parachain.": "",
"The initial head state is invalid.": "",
"The input data to hash. This can be either specified as a hex value (0x-prefix) or as a string.": "",
@ -470,6 +476,7 @@
"The signatory to send the approval/cancel from": "",
"The signature as by the account being checked, supplied as a hex-formatted string.": "",
"The specified value is greater than your free balance. The node will bond the maximum amount available.": "",
"The stash and controller pair, here the controller will be used to send the transaction.": "",
"The stash that is to be affected. The transaction will be sent from the associated controller account.": "",
"The suggested value for this tip": "",
"The threshold for this multisig": "",
@ -487,6 +494,7 @@
"Think of the stash as your cold wallet and the controller as your hot wallet. Funding operations are controlled by the stash, any other non-funding actions by the controller itself.": "",
"This account is recoverable, with the following friends:": "",
"This account will be use to approve each candidate.": "",
"This account will pay the fees for the preimage, based on the size thereof.": "",
"This external account cannot be used to sign data. Only Limited support is currently available for signing from any non-internal accounts.": "",
"This injected account cannot be used to sign data since the extension does not support raw signing.": "",
"This is not a valid JSON object.": "",
@ -542,6 +550,7 @@
"Waiting": "",
"Waiting for authorization from the extension. Please open the installed extension and approve or reject access.": "",
"We will provide you with a generated backup file after your account is created. As long as you have access to your account you can always download this file later by clicking on \"Backup\" button from the Accounts section.": "",
"When submitting a proposal the hash needs to be known. Proposals can be submitted with hash-only, but upon dispatch the preimage needs to be available.": "",
"Withdraw these unbonded funds": "",
"Yes": "",
"You are about to remove this account from your list of available accounts. Once completed, should you need to access it again, you will have to re-create the account either via seed or via a backup file.": "",

View File

@ -45,38 +45,61 @@ function PreImage ({ className, imageHash, isImminent: propsIsImminent, onClose
<Modal
className={className}
header={t('Submit preimage')}
size='large'
>
<Modal.Content>
<InputAddress
help={t('The account you want to register the preimage from')}
label={t('send from account')}
labelExtra={
<Available
label={<span className='label'>{t('transferrable')}</span>}
params={accountId}
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t('The account you want to register the preimage from')}
label={t('send from account')}
labelExtra={
<Available
label={<span className='label'>{t('transferrable')}</span>}
params={accountId}
/>
}
onChange={setAccountId}
type='account'
/>
}
onChange={setAccountId}
type='account'
/>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t('propose')}
onChange={setProposal}
/>
<Input
help={t('The hash of the selected proposal, use it for submitting the proposal')}
isDisabled
isDisabledError={!isMatched}
label={t('preimage hash')}
value={encodedHash}
/>
<Toggle
className='toggleImminent'
label={t('imminent preimage (proposal already passed)')}
onChange={setIsImminent}
value={isImminent}
/>
</Modal.Column>
<Modal.Column>
<p>{t('This account will pay the fees for the preimage, based on the size thereof.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t('propose')}
onChange={setProposal}
/>
<Input
help={t('The hash of the selected proposal, use it for submitting the proposal')}
isDisabled
isDisabledError={!isMatched}
label={t('preimage hash')}
value={encodedHash}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The image (proposal) will be stored on-chain against the hash of the contents.')}</p>
<p>{t('When submitting a proposal the hash needs to be known. Proposals can be submitted with hash-only, but upon dispatch the preimage needs to be available.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Toggle
className='toggleImminent'
label={t('imminent preimage (proposal already passed)')}
onChange={setIsImminent}
value={isImminent}
/>
</Modal.Column>
<Modal.Column>
<p>{t('Only applicable if the proposal has already passed and is ready for dispatch.')}</p>
</Modal.Column>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>
<TxButton

View File

@ -103,7 +103,7 @@ function Voting ({ proposal, referendumId }: Props): React.ReactElement<Props> |
/>
</Modal.Column>
<Modal.Column>
<p>{t('The balance associated with the vote will be locked as per the conviction specified nd will not be available for transfer or spend during this period.')}</p>
<p>{t('The balance associated with the vote will be locked as per the conviction specified and will not be available for transfer during this period.')}</p>
<p>{t('Conviction locks do overlap and is additive, meaning that funds locked during a previous vote can be locked again.')}</p>
</Modal.Column>
</Modal.Columns>

View File

@ -4,7 +4,8 @@
import BN from 'bn.js';
import React, { useState } from 'react';
import { Available, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
import { InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
import { Available } from '@polkadot/react-query';
import { useTranslation } from '../../translate';
import ValidateAmount from './InputValidateAmount';
@ -26,35 +27,47 @@ function BondExtra ({ onClose, stashId }: Props): React.ReactElement<Props> {
<Modal
className='staking--BondExtra'
header= {t('Bond more funds')}
size='small'
size='large'
>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={stashId}
isDisabled
label={t('stash account')}
labelExtra={
<Available
label={<span className='label'>{t('transferrable')}</span>}
params={stashId}
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t('stash account')}
/>
}
/>
<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={setMaxAdditional}
/>
<ValidateAmount
accountId={stashId}
onError={setAmountError}
value={maxAdditional}
/>
</Modal.Column>
<Modal.Column>
<p>{t('Since this transaction deals with funding, the stash account will be used.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
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')}
labelExtra={
<Available
label={<span className='label'>{t('available')}</span>}
params={stashId}
/>
}
maxValue={maxBalance}
onChange={setMaxAdditional}
/>
<ValidateAmount
accountId={stashId}
onError={setAmountError}
value={maxAdditional}
/>
</Modal.Column>
<Modal.Column>
<p>{t('Ensure that not all funds are locked, funds need to be available for fees.')}</p>
</Modal.Column>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>
<TxButton

View File

@ -6,11 +6,9 @@ import { AccountId, StakingLedger } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import React, { useState } from 'react';
import { Trans } from 'react-i18next';
import styled from 'styled-components';
import { AddressInfo, InputAddress, InputBalance, Modal, TxButton } from '@polkadot/react-components';
import { Bonded, InputAddress, InputBalance, Modal, Static, TxButton } from '@polkadot/react-components';
import { BlockToTime } from '@polkadot/react-query';
import { formatNumber } from '@polkadot/util';
import { useTranslation } from '../../translate';
import useUnbondDuration from '../useUnbondDuration';
@ -25,7 +23,7 @@ interface Props {
function Unbond ({ className, controllerId, onClose, stakingLedger, stashId }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const duration = useUnbondDuration();
const bondedBlocks = useUnbondDuration();
const [maxBalance] = useState<BN | null>(stakingLedger?.active.unwrap() || null);
const [maxUnbond, setMaxUnbond] = useState<BN | null>(null);
@ -33,37 +31,55 @@ function Unbond ({ className, controllerId, onClose, stakingLedger, stashId }: P
<Modal
className={`staking--Unbond ${className}`}
header={t('Unbond funds')}
size='small'
size='large'
>
<Modal.Content className='ui--signer-Signer-Content'>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t('controller account')}
/>
<div className='staking--Unbond--max'>
<AddressInfo
accountId={stashId}
withBalance={{
bonded: true
}}
/>
</div>
<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={setMaxUnbond}
withMax
/>
{duration?.gtn(0) && (
<article className='warning'>
<Trans key='unlockDuration'>Once unbonded, funds will only be available for withdrawal in <BlockToTime blocks={duration} /> ({formatNumber(duration)} blocks)</Trans>
</article>
)}
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The stash and controller pair, here the controller will be used to send the transaction.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
help={t('The amount of funds to unbond, this is adjusted using the bonded funds on the stash account.')}
label={t('unbond amount')}
labelExtra={
<Bonded
label={<span className='label'>{t('bonded')}</span>}
params={stashId}
/>
}
maxValue={maxBalance}
onChange={setMaxUnbond}
withMax
/>
{bondedBlocks?.gtn(0) && (
<Static
help={t('The bonding duration for any staked funds. After this period needs to be withdrawn.')}
label={t('on-chain bonding duration')}
>
<BlockToTime blocks={bondedBlocks} />
</Static>
)}
</Modal.Column>
<Modal.Column>
<p>{t('The funds will only be available for withdrawal after the unbonding period, however will not be part of the staked amount after the next validator election. You can follow the unlock countdown in the UI.')}</p>
</Modal.Column>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>
<TxButton
@ -82,10 +98,6 @@ function Unbond ({ className, controllerId, onClose, stakingLedger, stashId }: P
}
export default React.memo(styled(Unbond)`
article.warning > div {
display: inline-block;
}
.staking--Unbond--max > div {
justify-content: flex-end;

View File

@ -14,7 +14,7 @@ import { useTranslation } from '../translate';
import InputValidateAmount from './Account/InputValidateAmount';
import InputValidationController from './Account/InputValidationController';
import { rewardDestinationOptions } from './constants';
import useBondBlocks from './useBondBlocks';
import useUnbondDuration from './useUnbondDuration';
interface Props {
className?: string;
@ -32,7 +32,7 @@ function NewStake ({ className, isInElection }: Props): React.ReactElement<Props
const [destination, setDestination] = useState(0);
const [extrinsic, setExtrinsic] = useState<SubmittableExtrinsic<'promise'> | null>(null);
const [stashId, setStashId] = useState<string | null>(null);
const bondedBlocks = useBondBlocks();
const bondedBlocks = useUnbondDuration();
useEffect((): void => {
setExtrinsic(
@ -104,7 +104,7 @@ function NewStake ({ className, isInElection }: Props): React.ReactElement<Props
}
onChange={setAmount}
/>
{bondedBlocks && (
{bondedBlocks?.gtn(0) && (
<Static
help={t('The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.')}
label={t('on-chain bonding duration')}

View File

@ -1,25 +0,0 @@
// Copyright 2017-2020 @polkadot/app-staking 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 { DeriveSessionProgress } from '@polkadot/api-derive/types';
import BN from 'bn.js';
import { useEffect, useState } from 'react';
import { useApi, useCall } from '@polkadot/react-hooks';
const ONE = new BN(1);
export default function useBondBlocks (): BN | undefined {
const { api } = useApi();
const progress = useCall<DeriveSessionProgress>(api.derive.session.progress, []);
const [duration, setDuration] = useState<BN | undefined>();
useEffect((): void => {
progress?.sessionLength.gt(ONE) && setDuration(
progress.eraLength.mul(api.consts.staking.bondingDuration)
);
}, [api, progress]);
return duration;
}

View File

@ -161,7 +161,7 @@ function getValues (value: BN | string, si: SiDef | null, bitLength: BitLength,
: getValuesFromString(value, si, bitLength, isZeroable, maxValue);
}
function InputNumber ({ bitLength = DEFAULT_BITLENGTH, className, defaultValue = ZERO, help, isDecimal, isFull, isSi, isDisabled, isError = false, isZeroable = true, label, labelExtra, maxLength, maxValue, onChange, onEnter, onEscape, placeholder, style, value: propsValue }: Props): React.ReactElement<Props> {
function InputNumber ({ autoFocus, bitLength = DEFAULT_BITLENGTH, className, defaultValue = ZERO, help, isDecimal, isFull, isSi, isDisabled, isError = false, isZeroable = true, label, labelExtra, maxLength, maxValue, onChange, onEnter, onEscape, placeholder, style, value: propsValue }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [si, setSi] = useState<SiDef | null>(isSi ? formatBalance.findSi('-') : null);
const [isPreKeyDown, setIsPreKeyDown] = useState(false);
@ -239,6 +239,7 @@ function InputNumber ({ bitLength = DEFAULT_BITLENGTH, className, defaultValue =
return (
<Input
autoFocus={autoFocus}
className={classes('ui--InputNumber', className)}
help={help}
isAction={isSi}