Flatten modal columns (#4841)

* Flatten modal columns

* Additional

* Additional

* Additional

* Additional

* Additional

* Adjust tests

* No bids outside ending

* s/winners/bids/

* Adjust

* lease offsets
This commit is contained in:
Jaco Greeff 2021-03-14 14:36:49 +01:00 committed by GitHub
parent b20773e47b
commit a86bc3284a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
85 changed files with 1959 additions and 2703 deletions

View File

@ -98,47 +98,37 @@ function ChangePass ({ address, className = '', onClose }: Props): React.ReactEl
isInline
value={address}
/>
<Modal.Columns>
<Modal.Column>
<Password
autoFocus
help={t<string>('The existing account password as specified when this account was created or when it was last changed.')}
isError={!isOldValid}
label={t<string>('your current password')}
onChange={_onChangeOld}
tabIndex={1}
value={oldPass}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The existing account password as specified when this account was created or when it was last changed.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The existing account password as specified when this account was created or when it was last changed.')}>
<Password
autoFocus
help={t<string>('The existing account password as specified when this account was created or when it was last changed.')}
isError={!isOldValid}
label={t<string>('your current password')}
onChange={_onChangeOld}
tabIndex={1}
value={oldPass}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Password
help={t<string>('The new account password. Once set, all future account unlocks will be performed with this new password.')}
isError={!newPass1.isValid}
label={t<string>('your new password')}
onChange={_onChangeNew1}
onEnter={_doChange}
tabIndex={2}
value={newPass1.password}
/>
<Password
help={t<string>('Verify the password entered above.')}
isError={!newPass2.isValid}
label={t<string>('password (repeat)')}
onChange={_onChangeNew2}
onEnter={_doChange}
tabIndex={2}
value={newPass2.password}
/>
<PasswordStrength value={newPass1.password} />
</Modal.Column>
<Modal.Column>
<p>{t<string>('This will apply to any future use of this account as stored on this browser. Ensure that you securely store this new password and that it is strong and unique to the account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This will apply to any future use of this account as stored on this browser. Ensure that you securely store this new password and that it is strong and unique to the account.')}>
<Password
help={t<string>('The new account password. Once set, all future account unlocks will be performed with this new password.')}
isError={!newPass1.isValid}
label={t<string>('your new password')}
onChange={_onChangeNew1}
onEnter={_doChange}
tabIndex={2}
value={newPass1.password}
/>
<Password
help={t<string>('Verify the password entered above.')}
isError={!newPass2.isValid}
label={t<string>('password (repeat)')}
onChange={_onChangeNew2}
onEnter={_doChange}
tabIndex={2}
value={newPass2.password}
/>
<PasswordStrength value={newPass1.password} />
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -306,81 +306,69 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<AddressRow
defaultName={name}
fullLength
isEditableName={false}
noDefaultNameOpacity
value={isSeedValid ? address : ''}
/>
</Modal.Column>
<AddressRow
defaultName={name}
fullLength
isEditableName={false}
noDefaultNameOpacity
value={isSeedValid ? address : ''}
/>
</Modal.Columns>
{step === 1 && <>
<Modal.Columns>
<Modal.Column>
<TextArea
help={isEthereum
? t<string>("Your ethereum key pair is derived from your private key. Don't divulge this key.")
: t<string>('The private key for your account is derived from this seed. This seed must be kept secret as anyone in its possession has access to the funds of this account. If you validate, use the seed of the session account as the "--key" parameter of your node.')}
isAction
isError={!isSeedValid}
isReadOnly={seedType === 'dev'}
label={
seedType === 'bip'
? t<string>('mnemonic seed')
: seedType === 'dev'
? t<string>('development seed')
: isEthereum
? t<string>('ethereum private key')
: t<string>('seed (hex or string)')
}
onChange={_onChangeSeed}
seed={seed}
withLabel
>
<CopyButton
className='copyMoved'
type={seedType === 'bip' ? t<string>('mnemonic') : seedType === 'raw' ? isEthereum ? t<string>('private key') : 'seed' : t<string>('raw seed')}
value={seed}
/>
<Dropdown
defaultValue={seedType}
isButton
onChange={_selectSeedType}
options={seedOpt.current}
/>
</TextArea>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The secret seed value for this account. Ensure that you keep this in a safe place, with access to the seed you can re-create the account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The secret seed value for this account. Ensure that you keep this in a safe place, with access to the seed you can re-create the account.')}>
<TextArea
help={isEthereum
? t<string>("Your ethereum key pair is derived from your private key. Don't divulge this key.")
: t<string>('The private key for your account is derived from this seed. This seed must be kept secret as anyone in its possession has access to the funds of this account. If you validate, use the seed of the session account as the "--key" parameter of your node.')}
isAction
isError={!isSeedValid}
isReadOnly={seedType === 'dev'}
label={
seedType === 'bip'
? t<string>('mnemonic seed')
: seedType === 'dev'
? t<string>('development seed')
: isEthereum
? t<string>('ethereum private key')
: t<string>('seed (hex or string)')
}
onChange={_onChangeSeed}
seed={seed}
withLabel
>
<CopyButton
className='copyMoved'
type={seedType === 'bip' ? t<string>('mnemonic') : seedType === 'raw' ? isEthereum ? t<string>('private key') : 'seed' : t<string>('raw seed')}
value={seed}
/>
<Dropdown
defaultValue={seedType}
isButton
onChange={_selectSeedType}
options={seedOpt.current}
/>
</TextArea>
</Modal.Columns>
<Expander
className='accounts--Creator-advanced'
isPadded
summary={t<string>('Advanced creation options')}
>
<Modal.Columns>
<Modal.Column>
<Dropdown
defaultValue={pairType}
help={t<string>('Determines what cryptography will be used to create this account. Note that to validate on Polkadot, the session account must use "ed25519".')}
label={t<string>('keypair crypto type')}
onChange={_onChangePairType}
options={
isEthereum
? settings.availableCryptosEth
: isLedgerEnabled
? settings.availableCryptosLedger
: settings.availableCryptos
}
tabIndex={-1}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('If you are moving accounts between applications, ensure that you use the correct type.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('If you are moving accounts between applications, ensure that you use the correct type.')}>
<Dropdown
defaultValue={pairType}
help={t<string>('Determines what cryptography will be used to create this account. Note that to validate on Polkadot, the session account must use "ed25519".')}
label={t<string>('keypair crypto type')}
onChange={_onChangePairType}
options={
isEthereum
? settings.availableCryptosEth
: isLedgerEnabled
? settings.availableCryptosLedger
: settings.availableCryptos
}
tabIndex={-1}
/>
</Modal.Columns>
{pairType === 'ed25519-ledger'
? (
@ -390,9 +378,13 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
/>
)
: (
<Modal.Columns>
<Modal.Column>
{(pairType !== 'ethereum' || seedType !== 'raw') && (<Input
<Modal.Columns hint={
pairType === 'ethereum' && seedType === 'raw'
? t<string>('The derivation path is only relevant when deriving keys from a mnemonic.')
: t<string>('The derivation path allows you to create different accounts from the same base mnemonic.')
}>
{(pairType !== 'ethereum' || seedType !== 'raw') && (
<Input
help={(pairType === 'ethereum' ? t<string>('You can set a custom derivation path for this account using the following syntax "m/<purpose>/<coin_type>/<account>/<change>/<address_index>') : t<string>('You can set a custom derivation path for this account using the following syntax "/<soft-key>//<hard-key>". The "/<soft-key>" and "//<hard-key>" may be repeated and mixed`. An optional "///<password>" can be used with a mnemonic seed, and may only be specified once.'))}
isDisabled={pairType === 'ethereum' && seedType === 'raw'}
isError={!!deriveValidation?.error}
@ -411,59 +403,47 @@ function Create ({ className = '', onClose, onStatusChange, seed: propsSeed, typ
}
tabIndex={-1}
value={derivePath}
/>)}
{deriveValidation?.error && (
<MarkError content={errorIndex.current[deriveValidation.error] || deriveValidation.error} />
)}
{deriveValidation?.warning && (
<MarkWarning content={errorIndex.current[deriveValidation.warning]} />
)}
</Modal.Column>
<Modal.Column>
<p>{pairType === 'ethereum' && seedType === 'raw' ? t<string>('The derivation path is only relevant when deriving keys from a mnemonic.') : t<string>('The derivation path allows you to create different accounts from the same base mnemonic.')}</p>
</Modal.Column>
/>
)}
{deriveValidation?.error && (
<MarkError content={errorIndex.current[deriveValidation.error] || deriveValidation.error} />
)}
{deriveValidation?.warning && (
<MarkWarning content={errorIndex.current[deriveValidation.warning]} />
)}
</Modal.Columns>
)}
</Expander>
<Modal.Columns>
<Modal.Column>
<ExternalWarning />
<div className='saveToggle'>
<Checkbox
label={<>{t<string>('I have saved my mnemonic seed safely')}</>}
onChange={_toggleMnemonicSaved}
value={isMnemonicSaved}
/>
</div>
</Modal.Column>
<ExternalWarning />
<div className='saveToggle'>
<Checkbox
label={<>{t<string>('I have saved my mnemonic seed safely')}</>}
onChange={_toggleMnemonicSaved}
value={isMnemonicSaved}
/>
</div>
</Modal.Columns>
</>}
{step === 2 && <>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t<string>('Name given to this account. You can edit it. To use the account to validate or nominate, it is a good practice to append the function of the account in the name, e.g "name_you_want - stash".')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
onEnter={_onCommit}
placeholder={t<string>('new account')}
value={name}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The name for this account and how it will appear under your addresses. With an on-chain identity, it can be made available to others.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The name for this account and how it will appear under your addresses. With an on-chain identity, it can be made available to others.')}>
<Input
autoFocus
help={t<string>('Name given to this account. You can edit it. To use the account to validate or nominate, it is a good practice to append the function of the account in the name, e.g "name_you_want - stash".')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
onEnter={_onCommit}
placeholder={t<string>('new account')}
value={name}
/>
</Modal.Columns>
<PasswordInput
onChange={_onPasswordChange}
onEnter={_onCommit}
/>
<Modal.Columns>
<Modal.Column>
<ExternalWarning />
</Modal.Column>
<ExternalWarning />
</Modal.Columns>
</>}
{step === 3 && address && (

View File

@ -29,33 +29,32 @@ function CreateConfirmation ({ address, derivePath, name, pairType, seed }: Prop
return (
<Modal.Content>
<Modal.Columns>
<Modal.Column>
{address && name && <AddressRow
defaultName={name}
isInline
noDefaultNameOpacity
value={address}
/>}
{shortSeed && (
<Static
label={t<string>('partial seed')}
value={shortSeed}
/>
)}
<Static
label={t<string>('keypair type')}
value={pairType}
/>
<Static
label={t<string>('derivation path')}
value={derivePath || t<string>('<none provided>')}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('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.')}</p>
<p>{t<string>('Please make sure to save this file in a secure location as it is required, together with your password, to restore your account.')}</p>
</Modal.Column>
</>
}>
{address && name && <AddressRow
defaultName={name}
isInline
noDefaultNameOpacity
value={address}
/>}
{shortSeed && (
<Static
label={t<string>('partial seed')}
value={shortSeed}
/>
)}
<Static
label={t<string>('keypair type')}
value={pairType}
/>
<Static
label={t<string>('derivation path')}
value={derivePath || t<string>('<none provided>')}
/>
</Modal.Columns>
</Modal.Content>
);

View File

@ -45,40 +45,38 @@ function CreateSuriLedger ({ className, onChange, seedType }: Props): React.Reac
}, [accIndex, addIndex, chainType, onChange]);
return (
<Modal.Columns className={className}>
<Modal.Column>
{seedType === 'bip'
? (
<>
<Dropdown
help={t('The network to derive on')}
label={t('Ledger app type (originated from)')}
onChange={setChainType}
options={netOpts.current}
value={chainType}
/>
<Dropdown
help={t('The account type (derivation) to use')}
label={t('account type')}
onChange={setAccIndex}
options={accOps.current}
value={accIndex}
/>
<Dropdown
help={t('The address index (derivation on account) to use')}
label={t('address index')}
onChange={setAddIndex}
options={addOps.current}
value={addIndex}
/>
</>
)
: <MarkError content={t<string>('Derivation for Ledger-type accounts are only available on mnemonic seeds.')} />
}
</Modal.Column>
<Modal.Column>
<p>{t<string>('The derivation will be constructed from the values you specify.')}</p>
</Modal.Column>
<Modal.Columns
className={className}
hint={t<string>('The derivation will be constructed from the values you specify.')}
>
{seedType === 'bip'
? (
<>
<Dropdown
help={t('The network to derive on')}
label={t('Ledger app type (originated from)')}
onChange={setChainType}
options={netOpts.current}
value={chainType}
/>
<Dropdown
help={t('The account type (derivation) to use')}
label={t('account type')}
onChange={setAccIndex}
options={accOps.current}
value={accIndex}
/>
<Dropdown
help={t('The address index (derivation on account) to use')}
label={t('address index')}
onChange={setAddIndex}
options={addOps.current}
value={addIndex}
/>
</>
)
: <MarkError content={t<string>('Derivation for Ledger-type accounts are only available on mnemonic seeds.')} />
}
</Modal.Columns>
);
}

View File

@ -51,59 +51,53 @@ function Delegate ({ onClose, previousAmount, previousConviction, previousDelega
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
label={t<string>('delegating account')}
onChange={setDelegatingAccount}
type='account'
value={delegatingAccount}
/>
<InputAddress
label={t<string>('delegated account')}
onChange={setDelegatedAccount}
type='account'
value={delegatedAccount}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('Any democracy vote performed by the delegated account will result in an additional vote from the delegating account')}</p>
<p>{t<string>('If the delegated account is currently voting in a referendum, the delegating vote and conviction will be added.')}</p>
</Modal.Column>
</>
}>
<InputAddress
label={t<string>('delegating account')}
onChange={setDelegatingAccount}
type='account'
value={delegatingAccount}
/>
<InputAddress
label={t<string>('delegated account')}
onChange={setDelegatedAccount}
type='account'
value={delegatedAccount}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
help={t<string>('Amount to delegate for any democracy vote. This is adjusted using the available funds on the account.')}
isError={!!amountError?.error}
isZeroable={false}
label={t<string>('delegating amount')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={delegatingAccount}
/>
}
maxValue={maxBalance}
onChange={setAmount}
value={amount}
/>
<ValidateAmount
amount={amount}
delegatingAccount={delegatingAccount}
onError={setAmountError}
/>
<ConvictionDropdown
help={t<string>('The conviction that will be used for each delegated vote.')}
label={t<string>('conviction')}
onChange={setConviction}
value={conviction}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The amount to allocate and the conviction that will be applied to all votes made on a referendum.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The amount to allocate and the conviction that will be applied to all votes made on a referendum.')}>
<InputBalance
autoFocus
help={t<string>('Amount to delegate for any democracy vote. This is adjusted using the available funds on the account.')}
isError={!!amountError?.error}
isZeroable={false}
label={t<string>('delegating amount')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={delegatingAccount}
/>
}
maxValue={maxBalance}
onChange={setAmount}
value={amount}
/>
<ValidateAmount
amount={amount}
delegatingAccount={delegatingAccount}
onError={setAmountError}
/>
<ConvictionDropdown
help={t<string>('The conviction that will be used for each delegated vote.')}
label={t<string>('conviction')}
onChange={setConviction}
value={conviction}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -102,49 +102,37 @@ function Import ({ className = '', onClose, onStatusChange }: Props): React.Reac
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<AddressRow
defaultName={(pair?.meta.name as string) || null}
noDefaultNameOpacity
value={pair?.address || null}
/>
</Modal.Column>
<AddressRow
defaultName={(pair?.meta.name as string) || null}
noDefaultNameOpacity
value={pair?.address || null}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputFile
accept={acceptedFormats}
className='full'
help={t<string>('Select the JSON key file that was downloaded when you created the account. This JSON file contains your private key encrypted with your password.')}
isError={!pair}
label={t<string>('backup file')}
onChange={_onChangeFile}
withLabel
/>
{differentGenesis && (
<MarkWarning content={t<string>('The network from which this account was originally generated is different than the network you are currently connected to. Once imported ensure you toggle the "allow on any network" option for the account to keep it visible on the current network.')} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('Supply a backed-up JSON file, encrypted with your account-specific password.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Supply a backed-up JSON file, encrypted with your account-specific password.')}>
<InputFile
accept={acceptedFormats}
className='full'
help={t<string>('Select the JSON key file that was downloaded when you created the account. This JSON file contains your private key encrypted with your password.')}
isError={!pair}
label={t<string>('backup file')}
onChange={_onChangeFile}
withLabel
/>
{differentGenesis && (
<MarkWarning content={t<string>('The network from which this account was originally generated is different than the network you are currently connected to. Once imported ensure you toggle the "allow on any network" option for the account to keep it visible on the current network.')} />
)}
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Password
autoFocus
className='full'
help={t<string>('Type the password chosen at the account creation. It was used to encrypt your account\'s private key in the backup file.')}
isError={!isPassValid}
label={t<string>('password')}
onChange={_onChangePass}
onEnter={_onSave}
value={password}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The password previously used to encrypt this account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The password previously used to encrypt this account.')}>
<Password
autoFocus
className='full'
help={t<string>('Type the password chosen at the account creation. It was used to encrypt your account\'s private key in the backup file.')}
isError={!isPassValid}
label={t<string>('password')}
onChange={_onChangePass}
onEnter={_onSave}
value={password}
/>
</Modal.Columns>
<ExternalWarning />
</Modal.Content>

View File

@ -86,53 +86,38 @@ function LedgerModal ({ className, onClose }: Props): React.ReactElement<Props>
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
className='full'
help={t<string>('Name given to this account to uniquely identity the account to yourself.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('account name')}
value={name}
/>
</Modal.Column>
<Modal.Column>
{t<string>('The name for this account as it will appear under your accounts.')}
</Modal.Column>
<Modal.Columns hint={t<string>('The name for this account as it will appear under your accounts.')}>
<Input
autoFocus
className='full'
help={t<string>('Name given to this account to uniquely identity the account to yourself.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('account name')}
value={name}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
help={t('The account type (derivation) to use')}
label={t('account type')}
onChange={setAccIndex}
options={accOps.current}
value={accIndex}
/>
</Modal.Column>
<Modal.Column>
{t('The account type that you wish to create. This is the top-level derivation.')}
</Modal.Column>
<Modal.Columns hint={t('The account type that you wish to create. This is the top-level derivation.')}>
<Dropdown
help={t('The account type (derivation) to use')}
label={t('account type')}
onChange={setAccIndex}
options={accOps.current}
value={accIndex}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
help={t('The address index (derivation on account) to use')}
label={t('address index')}
onChange={setAddIndex}
options={addOps.current}
value={addIndex}
/>
{error && (
<MarkError content={error.message} />
)}
</Modal.Column>
<Modal.Column>
{t('The address index on the account that you wish to add. This is the second-level derivation.')}
</Modal.Column>
<Modal.Columns hint={t('The address index on the account that you wish to add. This is the second-level derivation.')}>
<Dropdown
help={t('The address index (derivation on account) to use')}
label={t('address index')}
onChange={setAddIndex}
options={addOps.current}
value={addIndex}
/>
{error && (
<MarkError content={error.message} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -149,83 +149,58 @@ function MultisigApprove ({ className = '', onClose, ongoing, threshold, who }:
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<Dropdown
help={t<string>('The call hashes that have not been executed as of yet.')}
label={t<string>('pending hashes')}
onChange={setHash}
options={hashes}
value={hash}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The call hash from the list of available and unapproved calls.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The call hash from the list of available and unapproved calls.')}>
<Dropdown
help={t<string>('The call hashes that have not been executed as of yet.')}
label={t<string>('pending hashes')}
onChange={setHash}
options={hashes}
value={hash}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
help={t<string>('Either approve or reject this call.')}
label={t<string>('approval type')}
onChange={setType}
options={calltypes}
value={type}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The operation type to apply. For approvals both non-final and final approvals are supported.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The operation type to apply. For approvals both non-final and final approvals are supported.')}>
<Dropdown
help={t<string>('Either approve or reject this call.')}
label={t<string>('approval type')}
onChange={setType}
options={calltypes}
value={type}
/>
</Modal.Columns>
{whoFilter.length !== 0 && (
<>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={whoFilter}
help={t<string>('The signatory to send the approval/cancel from')}
label={t<string>('signatory')}
onChange={setSignatory}
/>
</Modal.Column>
<Modal.Column>
<p>{t('For approvals outstanding approvers will be shown, for hashes that should be cancelled the first approver is required.')}</p>
</Modal.Column>
<Modal.Columns hint={t('For approvals outstanding approvers will be shown, for hashes that should be cancelled the first approver is required.')}>
<InputAddress
filter={whoFilter}
help={t<string>('The signatory to send the approval/cancel from')}
label={t<string>('signatory')}
onChange={setSignatory}
/>
</Modal.Columns>
{type === 'aye' && isMultiCall && (
<>
{isCallOverride && (
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t('For final approvals, the actual full call data is required to execute the transaction')}
isError={!callData}
label={t('call data for final approval')}
onChange={_setCallData}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The call data for this transaction matching the hash. Once sent, the multisig will be executed against this.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The call data for this transaction matching the hash. Once sent, the multisig will be executed against this.')}>
<Input
autoFocus
help={t('For final approvals, the actual full call data is required to execute the transaction')}
isError={!callData}
label={t('call data for final approval')}
onChange={_setCallData}
/>
</Modal.Columns>
)}
<Modal.Columns>
<Modal.Column>
<Toggle
className='tipToggle'
label={
isMultiCall
? t<string>('Multisig message with call (for final approval)')
: t<string>('Multisig approval with hash (non-final approval)')
}
onChange={setCallOverride}
value={isCallOverride}
/>
</Modal.Column>
<Modal.Column>
<p>{t('Swap to a non-executing approval type, with subsequent calls providing the actual call data.')}</p>
</Modal.Column>
<Modal.Columns hint={t('Swap to a non-executing approval type, with subsequent calls providing the actual call data.')}>
<Toggle
className='tipToggle'
label={
isMultiCall
? t<string>('Multisig message with call (for final approval)')
: t<string>('Multisig approval with hash (non-final approval)')
}
onChange={setCallOverride}
value={isCallOverride}
/>
</Modal.Columns>
</>
)}

View File

@ -87,52 +87,41 @@ function Multisig ({ className = '', onClose, onStatusChange }: Props): React.Re
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddressMulti
available={availableSignatories}
availableLabel={t<string>('available signatories')}
help={t<string>('The addresses that are able to approve multisig transactions. You can select up to {{maxHelpers}} trusted addresses.', { replace: { maxHelpers: MAX_SIGNATORIES } })}
maxCount={MAX_SIGNATORIES}
onChange={setSignatories}
value={signatories}
valueLabel={t<string>('selected signatories')}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The signatories has the ability to create transactions using the multisig and approve transactions sent by others.Once the threshold is reached with approvals, the multisig transaction is enacted on-chain.')}</p>
<p>{t<string>('Since the multisig function like any other account, once created it is available for selection anywhere accounts are used and needs to be funded before use.')}</p>
</Modal.Column>
</>
}>
<InputAddressMulti
available={availableSignatories}
availableLabel={t<string>('available signatories')}
help={t<string>('The addresses that are able to approve multisig transactions. You can select up to {{maxHelpers}} trusted addresses.', { replace: { maxHelpers: MAX_SIGNATORIES } })}
maxCount={MAX_SIGNATORIES}
onChange={setSignatories}
value={signatories}
valueLabel={t<string>('selected signatories')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputNumber
help={t<string>('The threshold for this multisig')}
isError={!isThresholdValid}
label={t<string>('threshold')}
onChange={_onChangeThreshold}
value={threshold}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The threshold for approval should be less or equal to the number of signatories for this multisig.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The threshold for approval should be less or equal to the number of signatories for this multisig.')}>
<InputNumber
help={t<string>('The threshold for this multisig')}
isError={!isThresholdValid}
label={t<string>('threshold')}
onChange={_onChangeThreshold}
value={threshold}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
className='full'
help={t<string>('Name given to this multisig. You can edit it at any later point in time.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('multisig name')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The name is for unique identification of the account in your owner lists.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The name is for unique identification of the account in your owner lists.')}>
<Input
autoFocus
className='full'
help={t<string>('Name given to this multisig. You can edit it at any later point in time.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('multisig name')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -46,32 +46,31 @@ export default function PasswordInput ({ onChange, onEnter }: Props): React.Reac
);
return (
<Modal.Columns>
<Modal.Column>
<Password
className='full'
help={t<string>('This password is used to encrypt your private key. It must be strong and unique! You will need it to sign transactions with this account. You can recover this account using this password together with the backup file (generated in the next step).')}
isError={!isPass1Valid}
label={t<string>('password')}
onChange={_onPassword1Change}
onEnter={onEnter}
value={password1}
/>
<Password
className='full'
help={t<string>('Verify the password entered above.')}
isError={!isPass2Valid}
label={t<string>('password (repeat)')}
onChange={onPassword2Change}
onEnter={onEnter}
value={password2}
/>
<PasswordStrength value={password1} />
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The password and password confirmation for this account. This is required to authenticate any transactions made and to encrypt the keypair.')}</p>
<p>{t<string>('Ensure you are using a strong password for proper account protection.')}</p>
</Modal.Column>
</>
}>
<Password
className='full'
help={t<string>('This password is used to encrypt your private key. It must be strong and unique! You will need it to sign transactions with this account. You can recover this account using this password together with the backup file (generated in the next step).')}
isError={!isPass1Valid}
label={t<string>('password')}
onChange={_onPassword1Change}
onEnter={onEnter}
value={password1}
/>
<Password
className='full'
help={t<string>('Verify the password entered above.')}
isError={!isPass2Valid}
label={t<string>('password (repeat)')}
onChange={onPassword2Change}
onEnter={onEnter}
value={password2}
/>
<PasswordStrength value={password1} />
</Modal.Columns>
);
}

View File

@ -77,35 +77,25 @@ function ProxyAdd ({ className = '', onClose, onStatusChange }: Props): React.Re
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddressSimple
autoFocus
help={t<string>('The address that you have a valid proxy setup for.')}
isError={!hasOwned}
label={t<string>('proxied account')}
onChange={setStashAddress}
placeholder={t<string>('stash address')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The address that has previously setup a proxy to one of the accounts that you control.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The address that has previously setup a proxy to one of the accounts that you control.')}>
<InputAddressSimple
autoFocus
help={t<string>('The address that you have a valid proxy setup for.')}
isError={!hasOwned}
label={t<string>('proxied account')}
onChange={setStashAddress}
placeholder={t<string>('stash address')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
className='full'
help={t<string>('Name given to this proxied account. You can edit it at any later point in time.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('proxied name')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The name is for unique identification of the account in your owner lists.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The name is for unique identification of the account in your owner lists.')}>
<Input
className='full'
help={t<string>('Name given to this proxied account. You can edit it at any later point in time.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onChangeName}
placeholder={t<string>('proxied name')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -241,58 +241,46 @@ function ProxyOverview ({ className, onClose, previousProxy: [existing] = EMPTY_
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
isDisabled={true}
label={t<string>('proxied account')}
type='account'
value={proxiedAccount}
<Modal.Columns hint={t<string>('Any account set as proxy will be able to perform actions in place of the proxied account')}>
<InputAddress
isDisabled={true}
label={t<string>('proxied account')}
type='account'
value={proxiedAccount}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('If you add several proxy accounts for the same proxy type (e.g 2 accounts set as proxy for Governance), then any of those 2 accounts will be able to perfom governance actions on behalf of the proxied account')}>
{previous.map((value, index) => (
<PrevProxy
index={index}
key={`${value.toString()}-${index}`}
onRemove={_delPrev}
typeOpts={typeOpts.current}
value={value}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Any account set as proxy will be able to perform actions in place of the proxied account')}</p>
</Modal.Column>
))}
{added.map((value, index) => (
<NewProxy
index={index}
key={`${value.toString()}-${index}`}
onChangeAccount={_changeProxyAccount}
onChangeType={_changeProxyType}
onRemove={_delProxy}
proxiedAccount={proxiedAccount}
typeOpts={typeOpts.current}
value={value}
/>
))}
<Button.Group>
<Button
icon='plus'
label={t<string>('Add proxy')}
onClick={_addProxy}
/>
</Button.Group>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{previous.map((value, index) => (
<PrevProxy
index={index}
key={`${value.toString()}-${index}`}
onRemove={_delPrev}
typeOpts={typeOpts.current}
value={value}
/>
))}
{added.map((value, index) => (
<NewProxy
index={index}
key={`${value.toString()}-${index}`}
onChangeAccount={_changeProxyAccount}
onChangeType={_changeProxyType}
onRemove={_delProxy}
proxiedAccount={proxiedAccount}
typeOpts={typeOpts.current}
value={value}
/>
))}
<Button.Group>
<Button
icon='plus'
label={t<string>('Add proxy')}
onClick={_addProxy}
/>
</Button.Group>
</Modal.Column>
<Modal.Column>
<p>{t<string>('If you add several proxy accounts for the same proxy type (e.g 2 accounts set as proxy for Governance), then any of those 2 accounts will be able to perfom governance actions on behalf of the proxied account')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<BatchWarning />
</Modal.Column>
<BatchWarning />
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -109,30 +109,23 @@ function QrModal ({ className = '', onClose, onStatusChange }: Props): React.Rea
? (
<>
<Modal.Columns>
<Modal.Column>
<AddressRow
defaultName={name}
noDefaultNameOpacity
value={scanned.content}
/>
</Modal.Column>
<AddressRow
defaultName={name}
noDefaultNameOpacity
value={scanned.content}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
className='full'
help={t<string>('Name given to this account. You can change it at any point in the future.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onNameChange}
onEnter={_onSave}
value={name}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The local name for this account. Changing this does not affect your on-line identity, so this is only used to indicate the name of the account locally.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The local name for this account. Changing this does not affect your on-line identity, so this is only used to indicate the name of the account locally.')}>
<Input
autoFocus
className='full'
help={t<string>('Name given to this account. You can change it at any point in the future.')}
isError={!isNameValid}
label={t<string>('name')}
onChange={_onNameChange}
onEnter={_onSave}
value={name}
/>
</Modal.Columns>
{!isAddress && (
<PasswordInput
@ -143,15 +136,10 @@ function QrModal ({ className = '', onClose, onStatusChange }: Props): React.Rea
</>
)
: (
<Modal.Columns>
<Modal.Column>
<div className='qr-wrapper'>
<QrScanAddress onScan={_onScan} />
</div>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Provide the account QR from the module/external application for scanning. Once detected as valid, you will be taken to the next step to add the account to your list.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Provide the account QR from the module/external application for scanning. Once detected as valid, you will be taken to the next step to add the account to your list.')}>
<div className='qr-wrapper'>
<QrScanAddress onScan={_onScan} />
</div>
</Modal.Columns>
)
}

View File

@ -38,54 +38,43 @@ function RecoverSetup ({ address, className = '', onClose }: Props): React.React
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
isDisabled
label={t<string>('the account to make recoverable')}
value={address}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The recoverable account is protected against the loss of seed/access by a social process.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The recoverable account is protected against the loss of seed/access by a social process.')}>
<InputAddress
isDisabled
label={t<string>('the account to make recoverable')}
value={address}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddressMulti
available={availableHelpers}
availableLabel={t<string>('available social recovery helpers')}
help={t<string>('The addresses that are able to help in recovery. You can select up to {{maxHelpers}} trusted helpers.', { replace: { maxHelpers: MAX_HELPERS } })}
maxCount={MAX_HELPERS}
onChange={setHelpers}
value={helpers}
valueLabel={t<string>('trusted social recovery helpers')}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('These are trusted individuals that can verify and approve any recovery actions. With recovery, once the threshold is reached, the funds associated with the account can be moved to a new destination.')}</p>
<p>{t<string>('The helpers should be able to verify, via an off-chain mechanism, that the account owner indeed wishes to recover access and as such provide any approvals. In the cases of malicious recovery procedures, they will have the power to stop it.')}</p>
</Modal.Column>
</>
}>
<InputAddressMulti
available={availableHelpers}
availableLabel={t<string>('available social recovery helpers')}
help={t<string>('The addresses that are able to help in recovery. You can select up to {{maxHelpers}} trusted helpers.', { replace: { maxHelpers: MAX_HELPERS } })}
maxCount={MAX_HELPERS}
onChange={setHelpers}
value={helpers}
valueLabel={t<string>('trusted social recovery helpers')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputNumber
help={t<string>('The threshold of vouches that is to be reached for the account to be recovered.')}
isError={isErrorThreshold}
label={t<string>('recovery threshold')}
onChange={setThreshold}
/>
<InputNumber
help={t<string>('The delay between vouching and the availability of the recovered account.')}
isError={isErrorDelay}
isZeroable
label={t<string>('recovery block delay')}
onChange={setDelay}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The threshold for approvals and the delay is the protection associated with the account. The delay should be such that any colluding recovery attempts does have a window to stop.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The threshold for approvals and the delay is the protection associated with the account. The delay should be such that any colluding recovery attempts does have a window to stop.')}>
<InputNumber
help={t<string>('The threshold of vouches that is to be reached for the account to be recovered.')}
isError={isErrorThreshold}
label={t<string>('recovery threshold')}
onChange={setThreshold}
/>
<InputNumber
help={t<string>('The delay between vouching and the availability of the recovered account.')}
isError={isErrorDelay}
isZeroable
label={t<string>('recovery block delay')}
onChange={setDelay}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -105,114 +105,103 @@ function Transfer ({ className = '', onClose, recipientId: propRecipientId, send
>
<Modal.Content>
<div className={className}>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={propSenderId}
help={t<string>('The account you will send funds from.')}
isDisabled={!!propSenderId}
label={t<string>('send from account')}
labelExtra={
<Available
label={t<string>('transferrable')}
params={propSenderId || senderId}
/>
}
onChange={setSenderId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The transferred balance will be subtracted (along with fees) from the sender account.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={propRecipientId}
help={t<string>('Select a contact or paste the address you want to send funds to.')}
isDisabled={!!propRecipientId}
label={t<string>('send to address')}
labelExtra={
<Available
label={t<string>('transferrable')}
params={propRecipientId || recipientId}
/>
}
onChange={setRecipientId}
type='allPlus'
/>
{recipientPhish && (
<MarkError content={t<string>('The recipient is associated with a known phishing site on {{url}}', { replace: { url: recipientPhish } })} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('The beneficiary will have access to the transferred fees when the transaction is included in a block.')}</p>
</Modal.Column>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{canToggleAll && isAll
? (
<InputBalance
autoFocus
defaultValue={maxTransfer}
help={t<string>('The full account balance to be transferred, minus the transaction fees')}
isDisabled
key={maxTransfer?.toString()}
label={t<string>('transferrable minus fees')}
/>
)
: (
<>
<InputBalance
autoFocus
help={t<string>('Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 milli is equivalent to sending 0.001.')}
isError={!hasAvailable}
isZeroable
label={t<string>('amount')}
onChange={setAmount}
/>
<InputBalance
defaultValue={api.consts.balances.existentialDeposit}
help={t<string>('The minimum amount that an account should have to be deemed active')}
isDisabled
label={t<string>('existential deposit')}
/>
</>
)
<Modal.Columns hint={t<string>('The transferred balance will be subtracted (along with fees) from the sender account.')}>
<InputAddress
defaultValue={propSenderId}
help={t<string>('The account you will send funds from.')}
isDisabled={!!propSenderId}
label={t<string>('send from account')}
labelExtra={
<Available
label={t<string>('transferrable')}
params={propSenderId || senderId}
/>
}
{isFunction(api.tx.balances.transferKeepAlive) && (
<Toggle
className='typeToggle'
label={
isProtected
? t<string>('Transfer with account keep-alive checks')
: t<string>('Normal transfer without keep-alive checks')
}
onChange={setIsProtected}
value={isProtected}
onChange={setSenderId}
type='account'
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The beneficiary will have access to the transferred fees when the transaction is included in a block.')}>
<InputAddress
defaultValue={propRecipientId}
help={t<string>('Select a contact or paste the address you want to send funds to.')}
isDisabled={!!propRecipientId}
label={t<string>('send to address')}
labelExtra={
<Available
label={t<string>('transferrable')}
params={propRecipientId || recipientId}
/>
)}
{canToggleAll && (
<Toggle
className='typeToggle'
label={t<string>('Transfer the full account balance, reap the sender')}
onChange={setIsAll}
value={isAll}
/>
)}
{!isProtected && !noReference && (
<MarkWarning content={t<string>('There is an existing reference count on the sender account. As such the account cannot be reaped from the state.')} />
)}
{noFees && (
<MarkWarning content={t<string>('The transaction, after application of the transfer fees, will drop the available balance below the existential deposit. As such the transfer will fail. The account needs more free funds to cover the transaction fees.')} />
)}
</Modal.Column>
<Modal.Column>
}
onChange={setRecipientId}
type='allPlus'
/>
{recipientPhish && (
<MarkError content={t<string>('The recipient is associated with a known phishing site on {{url}}', { replace: { url: recipientPhish } })} />
)}
</Modal.Columns>
<Modal.Columns hint={
<>
<p>{t<string>('If the recipient account is new, the balance needs to be more than the existential deposit. Likewise if the sending account balance drops below the same value, the account will be removed from the state.')}</p>
<p>{t('With the keep-alive option set, the account is protected against removal due to low balances.')}</p>
</Modal.Column>
</>
}>
{canToggleAll && isAll
? (
<InputBalance
autoFocus
defaultValue={maxTransfer}
help={t<string>('The full account balance to be transferred, minus the transaction fees')}
isDisabled
key={maxTransfer?.toString()}
label={t<string>('transferrable minus fees')}
/>
)
: (
<>
<InputBalance
autoFocus
help={t<string>('Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 milli is equivalent to sending 0.001.')}
isError={!hasAvailable}
isZeroable
label={t<string>('amount')}
onChange={setAmount}
/>
<InputBalance
defaultValue={api.consts.balances.existentialDeposit}
help={t<string>('The minimum amount that an account should have to be deemed active')}
isDisabled
label={t<string>('existential deposit')}
/>
</>
)
}
{isFunction(api.tx.balances.transferKeepAlive) && (
<Toggle
className='typeToggle'
label={
isProtected
? t<string>('Transfer with account keep-alive checks')
: t<string>('Normal transfer without keep-alive checks')
}
onChange={setIsProtected}
value={isProtected}
/>
)}
{canToggleAll && (
<Toggle
className='typeToggle'
label={t<string>('Transfer the full account balance, reap the sender')}
onChange={setIsAll}
value={isAll}
/>
)}
{!isProtected && !noReference && (
<MarkWarning content={t<string>('There is an existing reference count on the sender account. As such the account cannot be reaped from the state.')} />
)}
{noFees && (
<MarkWarning content={t<string>('The transaction, after application of the transfer fees, will drop the available balance below the existential deposit. As such the transfer will fail. The account needs more free funds to cover the transaction fees.')} />
)}
</Modal.Columns>
</div>
</Modal.Content>

View File

@ -24,17 +24,12 @@ function Undelegate ({ accountDelegating, onClose }: Props): React.ReactElement<
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={accountDelegating}
isDisabled
label={t<string>('delegating account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('You will remove any delegation made by this acccount')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('You will remove any delegation made by this acccount')}>
<InputAddress
defaultValue={accountDelegating}
isDisabled
label={t<string>('delegating account')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -41,36 +41,23 @@ function AwardBounty ({ curatorId, description, index }: Props): React.ReactElem
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will reward the Beneficiary and close the bounty after a delay period.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={curatorId}
help={t<string>("Curator's account that will reward the bounty to the implementer.")}
isDisabled={true}
label={t<string>('award with account')}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The Curator account that will be used to send this transaction. Any applicable fees will be paid by this account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The Curator account that will be used to send this transaction. Any applicable fees will be paid by this account.')}>
<InputAddress
defaultValue={curatorId}
help={t<string>("Curator's account that will reward the bounty to the implementer.")}
isDisabled={true}
label={t<string>('award with account')}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Choose the Beneficiary for this bounty.')}
label={t<string>('implementer account')}
onChange={setBeneficiaryId}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>("Reward the bounty to an implementer's account. The implementer will be able to claim the funds after a delay period.")}</p>
</Modal.Column>
<Modal.Columns hint={t<string>("Reward the bounty to an implementer's account. The implementer will be able to claim the funds after a delay period.")}>
<InputAddress
help={t<string>('Choose the Beneficiary for this bounty.')}
label={t<string>('implementer account')}
onChange={setBeneficiaryId}
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -44,48 +44,30 @@ function BountyAcceptCurator ({ curatorId, description, fee, index }: Props) {
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will accept your candidacy for the curator of the bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('This account will accept the curator role.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Only the account proposed as curator by the council can create the assign curator transaction ')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Only the account proposed as curator by the council can create the assign curator transaction')}>
<InputAddress
help={t<string>('This account will accept the curator role.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={fee.toString()}
isDisabled
label={t<string>("curator's fee")}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>("This amount will be sent to your account after bounty is rewarded and you claim curator's fee.")}</p>
</Modal.Column>
<Modal.Columns hint={t<string>("This amount will be sent to your account after bounty is rewarded and you claim curator's fee.")}>
<InputBalance
defaultValue={fee.toString()}
isDisabled
label={t<string>("curator's fee")}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={deposit.toString()}
help={t<string>("Curator's deposit is calculated based on the accepted curator's fee for this bounty.")}
isDisabled
label={t<string>("curator's deposit")}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This amount will be reserved from your account and returned after bounty claim is confirmed or if you give up, unless you are slashed earlier.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This amount will be reserved from your account and returned after bounty claim is confirmed or if you give up, unless you are slashed earlier.')}>
<InputBalance
defaultValue={deposit.toString()}
help={t<string>("Curator's deposit is calculated based on the accepted curator's fee for this bounty.")}
isDisabled
label={t<string>("curator's deposit")}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -58,23 +58,15 @@ function BountyInitiateVoting ({ description, index, proposals }: Props): React.
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will create a Council motion to either approve or reject the Bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a motion for the Bounty.')}
label={t<string>('vote with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council member that will create a motion, submission equates to an "aye" vote for chosen option.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council member that will create a motion, submission equates to an "aye" vote for chosen option.')}>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a motion for the Bounty.')}
label={t<string>('vote with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -67,54 +67,36 @@ function ProposeCuratorAction ({ description, index, proposals, value }: Props):
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will create a Council motion to propose a Curator for the Bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a motion for the Bounty.')}
label={t<string>('proposing account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council member that will create the motion.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council member that will create the motion.')}>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a motion for the Bounty.')}
label={t<string>('proposing account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select an account which (after a successful vote) will act as a curator.')}
label={t<string>('select curator')}
onChange={setCuratorId}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Choose a curator whose background and expertise is such that they are capable of determining when the task is complete.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Choose a curator whose background and expertise is such that they are capable of determining when the task is complete.')}>
<InputAddress
help={t<string>('Select an account which (after a successful vote) will act as a curator.')}
label={t<string>('select curator')}
onChange={setCuratorId}
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
help={t<string>('A reward for a curator, this amount is included in the total value of the bounty.')}
isError={!isFeeValid}
isZeroable
label={t<string>("curator's fee")}
onChange={setFee}
value={fee}
/>
{!isFeeValid && (
<MarkError content={t<string>("Curator's fee can't be higher than bounty value.")} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('Part of the bounty value that will go to the Curator as a reward for their work')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Part of the bounty value that will go to the Curator as a reward for their work')}>
<InputBalance
help={t<string>('A reward for a curator, this amount is included in the total value of the bounty.')}
isError={!isFeeValid}
isZeroable
label={t<string>("curator's fee")}
onChange={setFee}
value={fee}
/>
{!isFeeValid && (
<MarkError content={t<string>("Curator's fee can't be higher than bounty value.")} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -63,73 +63,53 @@ function BountyCreate () {
header={t<string>('Add Bounty')}
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
defaultValue={TITLE_DEFAULT_VALUE}
help={t<string>('The description of this bounty')}
isError={!isTitleValid}
label={t<string>('bounty title')}
onChange={onTitleChange}
value={title}
/>
{!isTitleValid && (title !== TITLE_DEFAULT_VALUE) && (
<MarkError content={t<string>('Title too long')} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('Description of the Bounty (to be stored on-chain)')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Description of the Bounty (to be stored on-chain)')}>
<Input
autoFocus
defaultValue={TITLE_DEFAULT_VALUE}
help={t<string>('The description of this bounty')}
isError={!isTitleValid}
label={t<string>('bounty title')}
onChange={onTitleChange}
value={title}
/>
{!isTitleValid && (title !== TITLE_DEFAULT_VALUE) && (
<MarkError content={t<string>('Title too long')} />
)}
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
help={t<string>("The total payment amount of this bounty, curator's fee included.")}
isError={!isValueValid}
isZeroable
label={t<string>('bounty requested allocation')}
onChange={setValue}
value={value}
/>
{!isValueValid && !value?.eq(BOUNTY_DEFAULT_VALUE) && (
<MarkError content={t<string>('Allocation value is smaller than the minimum bounty value.')} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('How much should be paid out for completed Bounty. Upon funding, the amount will be reserved in treasury.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('How much should be paid out for completed Bounty. Upon funding, the amount will be reserved in treasury.')}>
<InputBalance
help={t<string>("The total payment amount of this bounty, curator's fee included.")}
isError={!isValueValid}
isZeroable
label={t<string>('bounty requested allocation')}
onChange={setValue}
value={value}
/>
{!isValueValid && !value?.eq(BOUNTY_DEFAULT_VALUE) && (
<MarkError content={t<string>('Allocation value is smaller than the minimum bounty value.')} />
)}
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={bond.toString()}
help={t<string>('This amount will be reserved from origin account and returned on approval or slashed upon rejection.')}
isDisabled
label={t<string>('bounty bond')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Proposer bond depends on bounty title length.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Proposer bond depends on bounty title length.')}>
<InputBalance
defaultValue={bond.toString()}
help={t<string>('This amount will be reserved from origin account and returned on approval or slashed upon rejection.')}
isDisabled
label={t<string>('bounty bond')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select the account you wish to propose the bounty from.')}
isError={!hasFunds}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
{!hasFunds && (
<MarkError content={t<string>('Account does not have enough funds.')} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account will propose the bounty. Bond amount will be reserved on its balance.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account will propose the bounty. Bond amount will be reserved on its balance.')}>
<InputAddress
help={t<string>('Select the account you wish to propose the bounty from.')}
isError={!hasFunds}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
{!hasFunds && (
<MarkError content={t<string>('Account does not have enough funds.')} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleIsOpen}>

View File

@ -28,23 +28,15 @@ function BountyRejectCurator ({ curatorId, description, index, toggleOpen }: Pro
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will reject your candidacy for the curator of the bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('This account will be used to create the unassign curator transaction.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Only the account proposed as curator by the council can create the unassign curator transaction ')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Only the account proposed as curator by the council can create the unassign curator transaction ')}>
<InputAddress
help={t<string>('This account will be used to create the unassign curator transaction.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -42,23 +42,15 @@ function CloseBounty ({ description, index, toggleOpen }: Props): React.ReactEle
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will create a Council proposal to close the Bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a proposal for closing bounty.')}
label={t<string>('propose with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council member that will create the close bounty proposal, submission equates to an "aye" vote.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council member that will create the close bounty proposal, submission equates to an "aye" vote.')}>
<InputAddress
filter={members}
help={t<string>('Select the council member account you wish to use to create a proposal for closing bounty.')}
label={t<string>('propose with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -39,53 +39,35 @@ function ExtendBountyExpiryAction ({ curatorId, description, index, toggleOpen }
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will extend expiry time of the selected bounty.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('This account will be used to create an extend bounty expire transaction.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Only curator can extend the bounty time.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Only curator can extend the bounty time.')}>
<InputAddress
help={t<string>('This account will be used to create an extend bounty expire transaction.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Columns>
{expiryDate &&
<Modal.Columns>
<Modal.Column>
<Input
help={t<string>('The extended expiry date does not depend on the current expiry date.')}
isDisabled
label={t<string>('new expiry date and time')}
value={`${expiryDate.toLocaleDateString()} ${expiryDate.toLocaleTimeString()}`}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>(`Bounty expiry time will be set to ${timeAsText} from now.`)}</p>
</Modal.Column>
<Modal.Columns hint={t<string>(`Bounty expiry time will be set to ${timeAsText} from now.`)}>
<Input
help={t<string>('The extended expiry date does not depend on the current expiry date.')}
isDisabled
label={t<string>('new expiry date and time')}
value={`${expiryDate.toLocaleDateString()} ${expiryDate.toLocaleTimeString()}`}
/>
</Modal.Columns>
}
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
defaultValue={''}
help={t<string>('The note linked to the extension call, explaining the reason behind it.')}
label={t<string>('bounty remark')}
onChange={onRemarkChange}
value={remark}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>("The note that will be added to the transaction. It won't be stored on chain")}</p>
</Modal.Column>
<Modal.Columns hint={t<string>("The note that will be added to the transaction. It won't be stored on chain")}>
<Input
autoFocus
defaultValue={''}
help={t<string>('The note linked to the extension call, explaining the reason behind it.')}
label={t<string>('bounty remark')}
onChange={onRemarkChange}
value={remark}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -28,23 +28,15 @@ function BountyGiveUpCurator ({ curatorId, description, index, toggleOpen }: Pro
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{t<string>('This action will unassign you from the curator role.')}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The Curator account that will give up on it\'s role.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('You are giving up your curator role, the bounty will return to the Funded state. You will get your deposit back.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('You are giving up your curator role, the bounty will return to the Funded state. You will get your deposit back.')}>
<InputAddress
help={t<string>('The Curator account that will give up on it\'s role.')}
isDisabled
label={t<string>('curator account')}
type='account'
value={curatorId.toString()}
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -85,7 +85,7 @@ function SlashCurator ({ action, curatorId, description, index, toggleOpen }: Pr
}
}), [t, index, unassignCurator, api.tx.council.propose, allAccounts, members, threshold, unassignCuratorProposal]);
const { filter, header, helpMessage, params, proposingAccountTip, tip, title, tx } = actionProperties[action];
const { filter, helpMessage, params, proposingAccountTip, tip, title, tx } = actionProperties[action];
return (
<Modal
@ -93,37 +93,24 @@ function SlashCurator ({ action, curatorId, description, index, toggleOpen }: Pr
size='large'
>
<Modal.Content>
<Modal.Column>
<p>{header}</p>
</Modal.Column>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={filter}
help={t<string>('The account that will sign the transaction.')}
label={t<string>('proposing account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{proposingAccountTip}</p>
</Modal.Column>
<Modal.Columns hint={proposingAccountTip}>
<InputAddress
filter={filter}
help={t<string>('The account that will sign the transaction.')}
label={t<string>('proposing account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={curatorId}
help={helpMessage}
isDisabled
label={t<string>('current curator')}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{tip}</p>
</Modal.Column>
<Modal.Columns hint={tip}>
<InputAddress
defaultValue={curatorId}
help={helpMessage}
isDisabled
label={t<string>('current curator')}
withLabel
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -142,7 +142,7 @@ export class BountiesPage {
const proposeCuratorButton = await this.findByText('Propose curator');
fireEvent.click(proposeCuratorButton);
await this.expectText('This action will create a Council motion to propose a Curator for the Bounty.');
// await this.expectText('This action will create a Council motion to propose a Curator for the Bounty.');
}
async enterCuratorsFee (fee: string): Promise<void> {
@ -224,7 +224,7 @@ export class BountiesPage {
await clickElementWithText('Close', this.findByText);
await this.expectText('This action will create a Council proposal to close the Bounty.');
// await this.expectText('This action will create a Council proposal to close the Bounty.');
}
async clickButton (buttonName: string): Promise<void> {
@ -245,7 +245,7 @@ export class BountiesPage {
async openRejectCuratorRole (): Promise<void> {
await this.openExtraActions();
await this.clickButtonByText('Reject curator');
await this.expectText('This action will reject your candidacy for the curator of the bounty.');
// await this.expectText('This action will reject your candidacy for the curator of the bounty.');
}
async openExtraActions (): Promise<void> {
@ -254,7 +254,7 @@ export class BountiesPage {
async openAcceptCuratorRole (): Promise<void> {
await this.clickButton('Accept');
await this.expectText('This action will accept your candidacy for the curator of the bounty.');
// await this.expectText('This action will accept your candidacy for the curator of the bounty.');
}
async findCuratorsFee (): Promise<string> {
@ -272,7 +272,7 @@ export class BountiesPage {
async openExtendExpiry (): Promise<void> {
await this.openExtraActions();
await this.clickButtonByText('Extend expiry');
await this.expectText('This action will extend expiry time of the selected bounty.');
// await this.expectText('This action will extend expiry time of the selected bounty.');
}
async enterExpiryRemark (remark: string): Promise<void> {
@ -285,18 +285,18 @@ export class BountiesPage {
async openGiveUpCuratorsRole (): Promise<void> {
await this.openExtraActions();
await this.clickButtonByText('Give up');
await this.expectText('This action will unassign you from the curator role.');
// await this.expectText('This action will unassign you from the curator role.');
}
async openSlashCuratorByCouncil (): Promise<void> {
await this.openExtraActions();
await this.clickButtonByText('Slash curator (Council)');
await this.expectText('This action will create a Council motion to slash the Curator.');
// await this.expectText('This action will create a Council motion to slash the Curator.');
}
async openAwardBeneficiary (): Promise<void> {
await this.clickButton('Reward implementer');
await this.expectText('This action will reward the Beneficiary and close the bounty after a delay period.');
// await this.expectText('This action will reward the Beneficiary and close the bounty after a delay period.');
}
enterBeneficiary (beneficiary: string): void {

View File

@ -38,30 +38,20 @@ function Close ({ hasFailed, hash, idNumber, members, proposal }: Props): React.
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted to council for a subsequent voting round.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted to council for a subsequent voting round.')}>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish close the proposal with.')}
label={t<string>('sending account')}
onChange={setAccountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council account that will apply the close for the current round.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council account that will apply the close for the current round.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish close the proposal with.')}
label={t<string>('sending account')}
onChange={setAccountId}
type='account'
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -74,34 +74,24 @@ function ProposeExternal ({ className = '', isMember, members }: Props): React.R
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council account for the proposal. The selection is filtered by the current members.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council account for the proposal. The selection is filtered by the current members.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t<string>('The preimage hash of the proposal')}
label={t<string>('preimage hash')}
onChange={_onChangeHash}
value={hash}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The hash of the proposal image, either already submitted or valid for the specific call.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The hash of the proposal image, either already submitted or valid for the specific call.')}>
<Input
autoFocus
help={t<string>('The preimage hash of the proposal')}
label={t<string>('preimage hash')}
onChange={_onChangeHash}
value={hash}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleVisible}>

View File

@ -73,48 +73,33 @@ function Propose ({ isMember, members }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council account for the proposal. The selection is filtered by the current members.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council account for the proposal. The selection is filtered by the current members.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputNumber
className='medium'
help={t<string>('The minimum number of council votes required to approve this motion')}
isError={!threshold || threshold.eqn(0) || threshold.gtn(members.length)}
label={t<string>('threshold')}
onChange={_setThreshold}
placeholder={t<string>('Positive number between 1 and {{memberCount}}', { replace: { memberCount: members.length } })}
value={threshold || BN_ZERO}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The desired threshold. Here set to a default of 50%+1, as applicable for general proposals.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The desired threshold. Here set to a default of 50%+1, as applicable for general proposals.')}>
<InputNumber
className='medium'
help={t<string>('The minimum number of council votes required to approve this motion')}
isError={!threshold || threshold.eqn(0) || threshold.gtn(members.length)}
label={t<string>('threshold')}
onChange={_setThreshold}
placeholder={t<string>('Positive number between 1 and {{memberCount}}', { replace: { memberCount: members.length } })}
value={threshold || BN_ZERO}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t<string>('proposal')}
onChange={_setMethod}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The actual proposal to make, based on the selected call and parameters thereof.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The actual proposal to make, based on the selected call and parameters thereof.')}>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t<string>('proposal')}
onChange={_setMethod}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -78,45 +78,35 @@ function Slashing ({ className = '', isMember, members }: Props): React.ReactEle
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council account for the proposal. The selection is filtered by the current members.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council account for the proposal. The selection is filtered by the current members.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to make the proposal with.')}
label={t<string>('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{eras.length
? (
<Dropdown
defaultValue={eras[0].value}
help={t<string>('The unapplied slashed era to cancel.')}
label={t<string>('the era to cancel for')}
onChange={setSelectedEra}
options={eras}
/>
)
: (
<Input
isDisabled
label={t<string>('the era to cancel for')}
value={t<string>('no unapplied slashes found')}
/>
)
}
</Modal.Column>
<Modal.Column>
<p>{t<string>('The specific eras on which there are unapplied slashes. For each era a separate proposal is to be made.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The specific eras on which there are unapplied slashes. For each era a separate proposal is to be made.')}>
{eras.length
? (
<Dropdown
defaultValue={eras[0].value}
help={t<string>('The unapplied slashed era to cancel.')}
label={t<string>('the era to cancel for')}
onChange={setSelectedEra}
options={eras}
/>
)
: (
<Input
isDisabled
label={t<string>('the era to cancel for')}
value={t<string>('no unapplied slashes found')}
/>
)
}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleVisible}>

View File

@ -40,30 +40,20 @@ function Voting ({ hash, idNumber, isDisabled, members, prime, proposal }: Props
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The proposal that is being voted on. It will pass when the threshold is reached.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The proposal that is being voted on. It will pass when the threshold is reached.')}>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<VoteAccount
filter={members}
onChange={setAccountId}
/>
{isPrime && (
<MarkWarning content={t<string>('You are voting with this collective\'s prime account. The vote will be the default outcome in case of any abstentions.')} />
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council account for this vote. The selection is filtered by the current members.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council account for this vote. The selection is filtered by the current members.')}>
<VoteAccount
filter={members}
onChange={setAccountId}
/>
{isPrime && (
<MarkWarning content={t<string>('You are voting with this collective\'s prime account. The vote will be the default outcome in case of any abstentions.')} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleVoting}>

View File

@ -26,31 +26,21 @@ function SubmitCandidacy ({ electionsInfo }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select the account you wish to submit for candidacy.')}
label={t<string>('candidate account')}
onChange={setAcountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account will appear in the list of candidates. With enough votes in an election, it will become either a runner-up or a council member.')}>
<InputAddress
help={t<string>('Select the account you wish to submit for candidacy.')}
label={t<string>('candidate account')}
onChange={setAcountId}
type='account'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={api.consts[modLocation].candidacyBond}
help={t<string>('The bond that is reserved')}
isDisabled
label={t<string>('candidacy bond')}
/>
</Modal.Column>
<Modal.Column>
<p>{t('The bond will be reserved for the duration of your candidacy and membership.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The bond will be reserved for the duration of your candidacy and membership.')}>
<InputBalance
defaultValue={api.consts[modLocation].candidacyBond}
help={t<string>('The bond that is reserved')}
isDisabled
label={t<string>('candidacy bond')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -65,47 +65,36 @@ function Vote ({ electionsInfo }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('This account will be use to approve each candidate.')}
label={t<string>('voting account')}
onChange={setAccountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The vote will be recorded for the selected account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The vote will be recorded for the selected account.')}>
<InputAddress
help={t<string>('This account will be use to approve each candidate.')}
label={t<string>('voting account')}
onChange={setAccountId}
type='account'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<VoteValue
accountId={accountId}
isCouncil
onChange={setVoteValue}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The value associated with this vote. The amount will be locked (not available for transfer) and used in all subsequent elections.')}>
<VoteValue
accountId={accountId}
isCouncil
onChange={setVoteValue}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddressMulti
available={available}
availableLabel={t<string>('council candidates')}
defaultValue={defaultVotes}
help={t<string>('Select and order council candidates you wish to vote for.')}
maxCount={MAX_VOTES}
onChange={setVotes}
valueLabel={t<string>('my ordered votes')}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The votes for the members, runner-ups and candidates. These should be ordered based on your priority.')}</p>
<p>{t<string>('In calculating the election outcome, this prioritized vote ordering will be used to determine the final score for the candidates.')}</p>
</Modal.Column>
</>
}>
<InputAddressMulti
available={available}
availableLabel={t<string>('council candidates')}
defaultValue={defaultVotes}
help={t<string>('Select and order council candidates you wish to vote for.')}
maxCount={MAX_VOTES}
onChange={setVotes}
valueLabel={t<string>('my ordered votes')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleVisible}>

View File

@ -60,58 +60,47 @@ function PreImage ({ className = '', imageHash, isImminent = false, onClose }: P
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The account you want to register the preimage from')}
label={t<string>('send from account')}
labelExtra={
<Available
label={<span className='label'>{t<string>('transferrable')}</span>}
params={accountId}
/>
}
onChange={setAccountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account will pay the fees for the preimage, based on the size thereof.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account will pay the fees for the preimage, based on the size thereof.')}>
<InputAddress
help={t<string>('The account you want to register the preimage from')}
label={t<string>('send from account')}
labelExtra={
<Available
label={<span className='label'>{t<string>('transferrable')}</span>}
params={accountId}
/>
}
onChange={setAccountId}
type='account'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t<string>('propose')}
onChange={setProposal}
/>
<Input
className='disabledLook'
help={t<string>('The hash of the selected proposal, use it for submitting the proposal')}
isDisabledError={!isMatched}
label={t<string>('preimage hash')}
value={encodedHash}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The image (proposal) will be stored on-chain against the hash of the contents.')}</p>
<p>{t<string>('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>
</>
}>
<Extrinsic
defaultValue={apiDefaultTxSudo}
label={t<string>('propose')}
onChange={setProposal}
/>
<Input
className='disabledLook'
help={t<string>('The hash of the selected proposal, use it for submitting the proposal')}
isDisabledError={!isMatched}
label={t<string>('preimage hash')}
value={encodedHash}
/>
</Modal.Columns>
{!isImminent && (
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={storageFee}
help={t<string>('The amount reserved to store this image')}
isDisabled
label={t<string>('calculated storage fee')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The calculated storage costs based on the size and the per-bytes fee.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The calculated storage costs based on the size and the per-bytes fee.')}>
<InputBalance
defaultValue={storageFee}
help={t<string>('The amount reserved to store this image')}
isDisabled
label={t<string>('calculated storage fee')}
/>
</Modal.Columns>
)}
</Modal.Content>

View File

@ -43,58 +43,43 @@ function Propose ({ className = '', onClose }: Props): React.ReactElement<Props>
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The account you want to register the proposal from')}
label={t<string>('send from account')}
labelExtra={
<Available
label={<span className='label'>{t<string>('transferrable')}</span>}
params={accountId}
/>
}
onChange={setAccountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The proposal will be registered from this account and the balance lock will be applied here.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The proposal will be registered from this account and the balance lock will be applied here.')}>
<InputAddress
help={t<string>('The account you want to register the proposal from')}
label={t<string>('send from account')}
labelExtra={
<Available
label={<span className='label'>{t<string>('transferrable')}</span>}
params={accountId}
/>
}
onChange={setAccountId}
type='account'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t<string>('The preimage hash of the proposal')}
label={t<string>('preimage hash')}
onChange={_onChangeHash}
value={hash}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The hash of the preimage for the proposal as previously submitted or intended.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The hash of the preimage for the proposal as previously submitted or intended.')}>
<Input
autoFocus
help={t<string>('The preimage hash of the proposal')}
label={t<string>('preimage hash')}
onChange={_onChangeHash}
value={hash}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
defaultValue={api.consts.democracy.minimumDeposit}
help={t<string>('The locked value for this proposal')}
isError={!hasMinLocked}
label={t<string>('locked balance')}
onChange={setBalance}
/>
<InputBalance
defaultValue={api.consts.democracy.minimumDeposit}
help={t<string>('The minimum deposit required')}
isDisabled
label={t<string>('minimum deposit')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The associated deposit for this proposal should be more then the minimum on-chain deposit required. It will be locked until the proposal passes.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The associated deposit for this proposal should be more then the minimum on-chain deposit required. It will be locked until the proposal passes.')}>
<InputBalance
defaultValue={api.consts.democracy.minimumDeposit}
help={t<string>('The locked value for this proposal')}
isError={!hasMinLocked}
label={t<string>('locked balance')}
onChange={setBalance}
/>
<InputBalance
defaultValue={api.consts.democracy.minimumDeposit}
help={t<string>('The minimum deposit required')}
isDisabled
label={t<string>('minimum deposit')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -39,42 +39,27 @@ function Seconding ({ deposit, depositors, image, proposalId }: Props): React.Re
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<ProposedAction
idNumber={proposalId}
proposal={image?.proposal}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The proposal is in the queue for future referendums. One proposal from this list will move forward to voting.')}>
<ProposedAction
idNumber={proposalId}
proposal={image?.proposal}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select the account you wish to second with. This will lock your funds until the proposal is either approved or rejected')}
label={t<string>('second with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Seconding a proposal that indicates your backing for the proposal. Proposals with greater interest moves up the queue for potential next referendums.')}>
<InputAddress
help={t<string>('Select the account you wish to second with. This will lock your funds until the proposal is either approved or rejected')}
label={t<string>('second with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
isDisabled
label={t<string>('deposit required')}
value={deposit || api.consts.democracy.minimumDeposit}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The deposit will be locked for the lifetime of the proposal.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The deposit will be locked for the lifetime of the proposal.')}>
<InputBalance
isDisabled
label={t<string>('deposit required')}
value={deposit || api.consts.democracy.minimumDeposit}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleSeconding}>

View File

@ -44,45 +44,34 @@ function Voting ({ proposal, referendumId }: Props): React.ReactElement<Props> |
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<ProposedAction
idNumber={referendumId}
proposal={proposal}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('If this proposal is passed, the changes will be applied via dispatch and the deposit returned.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('If this proposal is passed, the changes will be applied via dispatch and the deposit returned.')}>
<ProposedAction
idNumber={referendumId}
proposal={proposal}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<VoteAccount onChange={setAccountId} />
</Modal.Column>
<Modal.Column>
<p>{t<string>('The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The vote will be recorded for this account. If another account delegated to this one, the delegated votes will also be counted.')}>
<VoteAccount onChange={setAccountId} />
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{isCurrentVote && (
<VoteValue
accountId={accountId}
autoFocus
onChange={setBalance}
/>
)}
<ConvictionDropdown
help={t<string>('The conviction to use for this vote, with an appropriate lock period.')}
label={t<string>('conviction')}
onChange={setConviction}
value={conviction}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('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<string>('Conviction locks do overlap and is additive, meaning that funds locked during a previous vote can be locked again.')}</p>
</Modal.Column>
</>
}>
{isCurrentVote && (
<VoteValue
accountId={accountId}
autoFocus
onChange={setBalance}
/>
)}
<ConvictionDropdown
help={t<string>('The conviction to use for this vote, with an appropriate lock period.')}
label={t<string>('conviction')}
onChange={setConviction}
value={conviction}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleVoting}>

View File

@ -9,7 +9,7 @@ import React, { useRef } from 'react';
import { Table } from '@polkadot/react-components';
import { useTranslation } from '../translate';
import WinBlock from './WinBlock';
import WinRange from './WinRange';
interface Props {
auctionInfo: [LeasePeriodOf, BlockNumber] | null;
@ -22,32 +22,36 @@ function Auction ({ auctionInfo, className, numAuctions, winningData }: Props):
const { t } = useTranslation();
const headerRef = useRef([
[t('winners'), 'start', 4],
[t('bids'), 'start', 4],
[t('slots')],
[t('value')]
]);
const endBlock = auctionInfo && auctionInfo[1];
return (
<Table
className={className}
empty={numAuctions && winningData && (
endBlock && !winningData.length
? t<string>('No winners in this auction')
: t<string>('No ongoing auction')
)}
empty={
numAuctions && winningData && (
auctionInfo && auctionInfo[1] && !winningData.length
? t<string>('No winners in this auction')
: t<string>('No ongoing auction')
)
}
header={headerRef.current}
>
{auctionInfo && winningData?.map((value, count) => (
<WinBlock
auctionInfo={auctionInfo}
isEven={!!(count % 2)}
isLatest={count === 0}
key={value.blockNumber.toString()}
value={value}
/>
))}
{auctionInfo && winningData?.map(({ blockNumber, winners }, round) =>
winners.map((value, index) => (
<WinRange
auctionInfo={auctionInfo}
blockNumber={blockNumber}
className={`${(round % 2) ? 'isEven' : 'isOdd'} ${index === (winners.length - 1) ? '' : 'noBorder'}`}
isFirst={index === 0}
isLatest={round === 0}
key={`${blockNumber.toString()}:${index}`}
value={value}
/>
))
)}
</Table>
);
}

View File

@ -7,7 +7,7 @@ import type { AuctionIndex, BlockNumber, LeasePeriodOf } from '@polkadot/types/i
import React, { useMemo, useState } from 'react';
import { Button, Dropdown, InputAddress, InputBalance, InputNumber, Modal, TxButton } from '@polkadot/react-components';
import { useAccounts, useApi, useToggle } from '@polkadot/react-hooks';
import { useAccounts, useApi, useCall, useToggle } from '@polkadot/react-hooks';
import { BN_ZERO, formatNumber } from '@polkadot/util';
import { useTranslation } from '../translate';
@ -28,6 +28,7 @@ function Bid ({ auctionInfo, className, id }: Props): React.ReactElement<Props>
const { t } = useTranslation();
const { api } = useApi();
const { hasAccounts } = useAccounts();
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
const [accountId, setAccountId] = useState<string | null>(null);
const [amount, setAmount] = useState<BN | undefined>(BN_ZERO);
const [paraId, setParaId] = useState<BN | undefined>(BN_ZERO);
@ -50,13 +51,13 @@ function Bid ({ auctionInfo, className, id }: Props): React.ReactElement<Props>
[auctionInfo]
);
const [leasePeriod] = auctionInfo || [null, null];
const [leasePeriod, endBlock] = auctionInfo || [null, null];
return (
<>
<Button
icon='plus'
isDisabled={!hasAccounts || !id || !leasePeriod}
isDisabled={!hasAccounts || !id || !leasePeriod || !endBlock || bestNumber?.gte(endBlock.add(api.consts.auctions.endingPeriod as BlockNumber))}
label={t<string>('Bid')}
onClick={toggleOpen}
/>
@ -68,44 +69,36 @@ function Bid ({ auctionInfo, className, id }: Props): React.ReactElement<Props>
>
<Modal.Content>
<Modal.Columns hint={t<string>('This account will be associated with the bid. This should match the registrar for the parachain.')}>
<Modal.Column>
<InputAddress
label={t<string>('bid from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Column>
<InputAddress
label={t<string>('bid from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The parachain id this bid is placed for')}>
<Modal.Column>
<InputNumber
autoFocus
defaultValue={paraId?.toString()}
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Column>
<InputNumber
autoFocus
defaultValue={paraId?.toString()}
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The amount to to bid for this parachain slot')}>
<Modal.Column>
<InputBalance
isZeroable={false}
label={t<string>('bid amount')}
onChange={setAmount}
/>
</Modal.Column>
<InputBalance
isZeroable={false}
label={t<string>('bid amount')}
onChange={setAmount}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The first and last slots for this bid. The last slot should be after the first and a maximum of 3 slots more than the first')}>
<Modal.Column>
<Dropdown
label={t<string>('bid slot range')}
onChange={setRange}
options={rangeOpts}
value={range}
/>
</Modal.Column>
<Dropdown
label={t<string>('bid slot range (start slot, end slot)')}
onChange={setRange}
options={rangeOpts}
value={range}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -1,7 +1,6 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { UInt } from '@polkadot/types';
import type { AuctionIndex, Balance, BlockNumber, LeasePeriodOf } from '@polkadot/types/interfaces';
import type { Winning } from './types';
@ -78,7 +77,7 @@ function Summary ({ auctionInfo, className, lastWinner, numAuctions }: Props): R
<CardSummary
label={t<string>('ending period')}
progress={{
total: api.consts.auctions.endingPeriod as UInt,
total: api.consts.auctions.endingPeriod as BlockNumber,
value: bestNumber.sub(ending),
withTime: true
}}

View File

@ -1,37 +0,0 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { BlockNumber, LeasePeriodOf } from '@polkadot/types/interfaces';
import type { Winning } from './types';
import React from 'react';
import WinRange from './WinRange';
interface Props {
auctionInfo: [LeasePeriodOf, BlockNumber];
className?: string;
isEven: boolean;
isLatest: boolean;
value: Winning;
}
function WinBlock ({ auctionInfo, className = '', isEven, isLatest, value: { blockNumber, winners } }: Props): React.ReactElement<Props> {
return (
<>
{winners.map((value, index) => (
<WinRange
auctionInfo={auctionInfo}
blockNumber={blockNumber}
className={`${className} ${isEven ? 'isEven' : 'isOdd'} ${index === (winners.length - 1) ? '' : 'noBorder'}`}
isFirst={index === 0}
isLatest={isLatest}
key={index}
value={value}
/>
))}
</>
);
}
export default React.memo(WinBlock);

View File

@ -100,10 +100,8 @@ export default function useWinningData (auctionInfo: [LeasePeriodOf, BlockNumber
// should be fired once, all entries as an initial round
useEffect((): void => {
const [, endBlock] = auctionInfo || [null, null];
allEntries && setResult(
extractData(endBlock, allEntries)
extractData(auctionInfo && auctionInfo[1], allEntries)
);
}, [allEntries, auctionInfo]);
@ -121,7 +119,7 @@ export default function useWinningData (auctionInfo: [LeasePeriodOf, BlockNumber
const [, endBlock] = auctionInfo || [null, null];
if (!endBlock) {
setResult((prev) => prev && prev.length ? null : prev);
setResult((prev) => prev && prev.length ? [] : prev);
} else if (bestNumber && bestNumber.gt(endBlock) && triggerRef.current !== trigger) {
const blockOffset = bestNumber.sub(endBlock).iadd(BN_ONE);

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { UInt } from '@polkadot/types';
import type { BlockNumber } from '@polkadot/types/interfaces';
import type { Campaign } from './types';
import React, { useMemo } from 'react';
@ -35,7 +35,7 @@ function Fund ({ bestNumber, className, isOngoing, value: { info: { cap, deposit
const [percentage, isCapped] = useMemo(
() => [
`${(raised.muln(10000).div(cap).toNumber() / 100).toFixed(2)}%`,
cap.sub(raised).lt(api.consts.crowdloan.minContribution as UInt)
cap.sub(raised).lt(api.consts.crowdloan.minContribution as BlockNumber)
],
[api, cap, raised]
);

View File

@ -49,55 +49,45 @@ function FundAdd ({ bestNumber, className }: Props): React.ReactElement<Props> {
>
<Modal.Content>
<Modal.Columns hint={t<string>('This account will be associated with the fund and pay the deposit. This should match the registrar for the parachain.')}>
<Modal.Column>
<InputAddress
label={t<string>('propose from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Column>
<InputAddress
label={t<string>('propose from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The parachain id this fund applies to')}>
<Modal.Column>
<InputNumber
autoFocus
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Column>
<InputNumber
autoFocus
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The amount to be raised in this funding campaign')}>
<Modal.Column>
<InputBalance
isZeroable={false}
label={t<string>('crowdfund cap')}
onChange={setCap}
/>
</Modal.Column>
<InputBalance
isZeroable={false}
label={t<string>('crowdfund cap')}
onChange={setCap}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The block until which this fund is active for')}>
<Modal.Column>
<InputNumber
isError={isEndError}
label={t<string>('ending block')}
onChange={setEndBlock}
/>
</Modal.Column>
<InputNumber
isError={isEndError}
label={t<string>('ending block')}
onChange={setEndBlock}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The first and last slots for this funding campaign. The last slot should be after the first and a maximum of 3 slots more than the first')}>
<Modal.Column>
<InputNumber
label={t<string>('first slot')}
onChange={setFirstSlot}
/>
<InputNumber
isError={isLastError}
label={t<string>('last slot')}
onChange={setLastSlot}
/>
</Modal.Column>
<InputNumber
label={t<string>('first slot')}
onChange={setFirstSlot}
/>
<InputNumber
isError={isLastError}
label={t<string>('last slot')}
onChange={setLastSlot}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -2,8 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { UInt } from '@polkadot/types';
import type { Balance, ParaId } from '@polkadot/types/interfaces';
import type { Balance, BlockNumber, ParaId } from '@polkadot/types/interfaces';
import React, { useState } from 'react';
@ -31,7 +30,7 @@ function FundContribute ({ cap, className, paraId, raised }: Props): React.React
// TODO verifier signature
const remaining = cap.sub(raised);
const isAmountBelow = !amount || amount.lt(api.consts.crowdloan.minContribution as UInt);
const isAmountBelow = !amount || amount.lt(api.consts.crowdloan.minContribution as BlockNumber);
const isAmountOver = !!(amount && amount.gt(remaining));
const isAmountError = isAmountBelow || isAmountOver;
@ -51,31 +50,27 @@ function FundContribute ({ cap, className, paraId, raised }: Props): React.React
>
<Modal.Content>
<Modal.Columns hint={t<string>('This account will contribute to the crowdloan.')}>
<Modal.Column>
<InputAddress
label={t<string>('contribute from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Column>
<InputAddress
label={t<string>('contribute from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The amount to contribute. Should be less than the remaining value and more than the minimum contribution amount.')}>
<Modal.Column>
<InputBalance
autoFocus
isError={isAmountError}
isZeroable={false}
label={t<string>('contribution')}
onChange={setAmount}
/>
{isAmountBelow && (
<MarkWarning content={t<string>('The amount is less than the minimum allowed contribution of {{value}}', { replace: { value: formatBalance(api.consts.crowdloan.minContribution as UInt) } })} />
)}
{isAmountOver && (
<MarkWarning content={t<string>('The amount is more than the remaining contribution needed {{value}}', { replace: { value: formatBalance(remaining) } })} />
)}
</Modal.Column>
<InputBalance
autoFocus
isError={isAmountError}
isZeroable={false}
label={t<string>('contribution')}
onChange={setAmount}
/>
{isAmountBelow && (
<MarkWarning content={t<string>('The amount is less than the minimum allowed contribution of {{value}}', { replace: { value: formatBalance(api.consts.crowdloan.minContribution as BlockNumber) } })} />
)}
{isAmountOver && (
<MarkWarning content={t<string>('The amount is more than the remaining contribution needed {{value}}', { replace: { value: formatBalance(remaining) } })} />
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -47,45 +47,37 @@ function RegisterThread ({ className, onClose }: Props): React.ReactElement<Prop
>
<Modal.Content>
<Modal.Columns hint={t<string>('This account will be associated with the parachain and pay the deposit.')}>
<Modal.Column>
<InputAddress
label={t<string>('register from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Column>
<InputAddress
label={t<string>('register from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The id of this parachain as known on the network')}>
<Modal.Column>
<InputNumber
autoFocus
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Column>
<InputNumber
autoFocus
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The WASM validation function for this parachain.')}>
<Modal.Column>
<InputWasm
help={t<string>('The compiled runtime WASM for the parachain you wish to register.')}
isError={!isWasmValid}
label={t<string>('code')}
onChange={_setWasm}
placeholder={wasm && !isWasmValid && t<string>('The code is not recognized as being in valid WASM format')}
/>
</Modal.Column>
<InputWasm
help={t<string>('The compiled runtime WASM for the parachain you wish to register.')}
isError={!isWasmValid}
label={t<string>('code')}
onChange={_setWasm}
placeholder={wasm && !isWasmValid && t<string>('The code is not recognized as being in valid WASM format')}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The genesis state for this parachain.')}>
<Modal.Column>
<InputFile
help={t<string>('The genesis state for the parachain.')}
isError={!genesisState}
label={t<string>('initial state')}
onChange={_setGenesisState}
/>
</Modal.Column>
<InputFile
help={t<string>('The genesis state for the parachain.')}
isError={!genesisState}
label={t<string>('initial state')}
onChange={_setGenesisState}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -1,6 +1,8 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { LeasePeriod } from './types';
import React from 'react';
import SummarySession from '@polkadot/app-explorer/SummarySession';
@ -10,18 +12,17 @@ import { BestNumber } from '@polkadot/react-query';
import { formatNumber, isNumber } from '@polkadot/util';
import { useTranslation } from '../translate';
import useLeasePeriod from '../useLeasePeriod';
interface Props {
leasePeriod: LeasePeriod | null;
parachainCount?: number;
proposalCount?: number;
upcomingCount?: number;
}
function Summary ({ parachainCount, proposalCount, upcomingCount }: Props): React.ReactElement<Props> {
function Summary ({ leasePeriod, parachainCount, proposalCount, upcomingCount }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const leaseInfo = useLeasePeriod();
return (
<SummaryBox>
@ -48,16 +49,16 @@ function Summary ({ parachainCount, proposalCount, upcomingCount }: Props): Reac
</CardSummary>
)}
</section>
{leaseInfo && (
{leasePeriod && (
<CardSummary
label={t<string>('lease period')}
progress={{
total: leaseInfo.length,
value: leaseInfo.remainder,
total: leasePeriod.length,
value: leasePeriod.remainder,
withTime: true
}}
>
{formatNumber(leaseInfo.currentPeriod)}
{formatNumber(leasePeriod.currentPeriod)}
</CardSummary>
)}
<section>

View File

@ -1,6 +1,7 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { Option, Vec } from '@polkadot/types';
import type { AccountId, BalanceOf, ParaGenesisArgs, ParaId } from '@polkadot/types/interfaces';
import type { ITuple } from '@polkadot/types/types';
@ -15,6 +16,7 @@ import { useTranslation } from '../translate';
import { sliceHex } from '../util';
interface Props {
currentPeriod: BN | null;
id: ParaId;
}
@ -56,7 +58,7 @@ const optMulti = {
})
};
function Upcoming ({ id }: Props): React.ReactElement<Props> {
function Upcoming ({ currentPeriod, id }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const { leases, upcomingGenesis } = useCallMulti<MultiState>([
@ -73,7 +75,11 @@ function Upcoming ({ id }: Props): React.ReactElement<Props> {
sliceHex(upcomingGenesis.genesisHead, 8)
)}
</td>
<td className='start together'>{leases.map(({ period }) => formatNumber(period)).join(', ')}</td>
<td className='start together'>
{currentPeriod &&
leases.map(({ period }) => formatNumber(currentPeriod.addn(period))).join(', ')
}
</td>
<td className='number'>
{upcomingGenesis && (
upcomingGenesis.parachain ? t('Yes') : t('No')

View File

@ -1,6 +1,7 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { ParaId } from '@polkadot/types/interfaces';
import React, { useRef } from 'react';
@ -11,10 +12,11 @@ import { useTranslation } from '../translate';
import Upcoming from './Upcoming';
interface Props {
currentPeriod: BN | null;
ids?: ParaId[];
}
function UpcomingList ({ ids }: Props): React.ReactElement<Props> {
function UpcomingList ({ currentPeriod, ids }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const headerRef = useRef([
@ -31,6 +33,7 @@ function UpcomingList ({ ids }: Props): React.ReactElement<Props> {
>
{ids?.map((id): React.ReactNode => (
<Upcoming
currentPeriod={currentPeriod}
id={id}
key={id.toString()}
/>

View File

@ -12,6 +12,7 @@ import Actions from './Actions';
import Parachains from './ParachainList';
import Summary from './Summary';
import Upcoming from './UpcomingList';
import useLeasePeriod from './useLeasePeriod';
interface Props {
className?: string;
@ -21,8 +22,9 @@ interface Props {
function Overview ({ className, proposals }: Props): React.ReactElement<Props> {
const { api } = useApi();
const paraIds = useCall<ParaId[]>(api.query.paras?.parachains);
const sessionTrigger = useEventTrigger([api.events.session.NewSession, api.events.registrar?.Registered]);
const mountedRef = useIsMountedRef();
const leasePeriod = useLeasePeriod();
const sessionTrigger = useEventTrigger([api.events.session.NewSession, api.events.registrar?.Registered]);
const [upcomingIds, setUpcomingIds] = useState<ParaId[]>([]);
useEffect((): void => {
@ -41,6 +43,7 @@ function Overview ({ className, proposals }: Props): React.ReactElement<Props> {
return (
<div className={className}>
<Summary
leasePeriod={leasePeriod}
parachainCount={paraIds?.length}
proposalCount={proposals?.proposalIds.length}
upcomingCount={upcomingIds?.length}
@ -52,7 +55,10 @@ function Overview ({ className, proposals }: Props): React.ReactElement<Props> {
ids={paraIds}
scheduled={proposals?.scheduled}
/>
<Upcoming ids={upcomingIds} />
<Upcoming
currentPeriod={leasePeriod && leasePeriod.currentPeriod}
ids={upcomingIds}
/>
</>
)}
</div>

View File

@ -0,0 +1,10 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
export interface LeasePeriod {
currentPeriod: BN;
length: BN;
remainder: BN;
}

View File

@ -2,23 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
import type { BlockNumber } from '@polkadot/types/interfaces';
import type { LeasePeriod } from './types';
import BN from 'bn.js';
import { useMemo } from 'react';
import { useApi, useCall } from '@polkadot/react-hooks';
interface Result {
currentPeriod: BN;
length: BN;
remainder: BN;
}
export default function useLeasePeriod (): Result | null {
export default function useLeasePeriod (): LeasePeriod | null {
const { api } = useApi();
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
return useMemo((): Result | null => {
return useMemo((): LeasePeriod | null => {
if (api.consts.slots?.leasePeriod && bestNumber) {
const length = api.consts.slots.leasePeriod as BlockNumber;

View File

@ -91,96 +91,76 @@ function Propose ({ className, onClose }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
label={t<string>('propose from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account will be associated with the parachain and pay the deposit.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account will be associated with the parachain and pay the deposit.')}>
<InputAddress
label={t<string>('propose from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
isError={!isNameValid}
label={t<string>('parachain name')}
onChange={setName}
/>
<InputNumber
isZeroable={false}
label={t<string>('requested id')}
onChange={setParaId}
/>
<InputBalance
defaultValue={balance}
label={t<string>('initial balance')}
onChange={setBalance}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The name for this parachain, the id and the allocated/requested balance.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The name for this parachain, the id and the allocated/requested balance.')}>
<Input
autoFocus
isError={!isNameValid}
label={t<string>('parachain name')}
onChange={setName}
/>
<InputNumber
isZeroable={false}
label={t<string>('requested id')}
onChange={setParaId}
/>
<InputBalance
defaultValue={balance}
label={t<string>('initial balance')}
onChange={setBalance}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputWasm
help={t<string>('The compiled runtime WASM for the parachain you wish to register.')}
isError={!isWasmValid}
label={t<string>('validation code')}
onChange={_setWasm}
placeholder={wasm && !isWasmValid && t<string>('The code is not recognized as being in valid WASM format')}
/>
<InputFile
help={t<string>('The genesis state for the parachain.')}
isError={!genesisState}
label={t<string>('genesis state')}
onChange={_setGenesisState}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The WASM validation function as well as the genesis state for this parachain.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The WASM validation function as well as the genesis state for this parachain.')}>
<InputWasm
help={t<string>('The compiled runtime WASM for the parachain you wish to register.')}
isError={!isWasmValid}
label={t<string>('validation code')}
onChange={_setWasm}
placeholder={wasm && !isWasmValid && t<string>('The code is not recognized as being in valid WASM format')}
/>
<InputFile
help={t<string>('The genesis state for the parachain.')}
isError={!genesisState}
label={t<string>('genesis state')}
onChange={_setGenesisState}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{validators.map((address, index) => (
<Validator
address={address}
index={index}
key={index}
setAddress={_setAddress}
t={t}
/>
))}
{!validators.length && (
<MarkWarning content={t<string>('You need to supply at last one running validator for your parachain alongside this request.')} />
)}
{isValDuplicate && (
<MarkWarning content={t<string>('You have duplicated validator entries, ensure each is unique.')} />
)}
<Button.Group>
<Button
icon='plus'
label={t<string>('Add validator')}
onClick={_addValidator}
/>
<Button
icon='minus'
isDisabled={validators.length === 0}
label={t<string>('Remove validator')}
onClick={_delValidator}
/>
</Button.Group>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The validators for this parachain. At least one is required and where multiple is supplied, they need to be unique.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The validators for this parachain. At least one is required and where multiple is supplied, they need to be unique.')}>
{validators.map((address, index) => (
<Validator
address={address}
index={index}
key={index}
setAddress={_setAddress}
t={t}
/>
))}
{!validators.length && (
<MarkWarning content={t<string>('You need to supply at last one running validator for your parachain alongside this request.')} />
)}
{isValDuplicate && (
<MarkWarning content={t<string>('You have duplicated validator entries, ensure each is unique.')} />
)}
<Button.Group>
<Button
icon='plus'
label={t<string>('Add validator')}
onClick={_addValidator}
/>
<Button
icon='minus'
isDisabled={validators.length === 0}
label={t<string>('Remove validator')}
onClick={_delValidator}
/>
</Button.Group>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -64,34 +64,24 @@ function Unlock ({ onClose, onUnlock, pair }: Props): React.ReactElement<Props>
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The selected account to be unlocked.')}
isDisabled
label={t<string>('account')}
value={address}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account that will perform the message signing.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account that will perform the message signing.')}>
<InputAddress
help={t<string>('The selected account to be unlocked.')}
isDisabled
label={t<string>('account')}
value={address}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Password
autoFocus
help={t<string>('The account\'s password specified at the creation of this account.')}
isError={!!unlockError}
label={t<string>('password')}
onChange={setPassword}
onEnter={_onUnlock}
value={password}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Unlock the account for signing. Once active the signature will be generated based on the content provided.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Unlock the account for signing. Once active the signature will be generated based on the content provided.')}>
<Password
autoFocus
help={t<string>('The account\'s password specified at the creation of this account.')}
isError={!!unlockError}
label={t<string>('password')}
onChange={setPassword}
onEnter={_onUnlock}
value={password}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -25,31 +25,21 @@ function BidNew ({ onClose }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The actual account you wish to submit the bid with')}
label={t<string>('bid account')}
onChange={setAccount}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Your candidate/bid account. Once accepted this account will become a member.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Your candidate/bid account. Once accepted this account will become a member.')}>
<InputAddress
help={t<string>('The actual account you wish to submit the bid with')}
label={t<string>('bid account')}
onChange={setAccount}
type='account'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
help={t<string>('The amount to associate with your bid, should be less than the pot.')}
label={t<string>('bid amount')}
onChange={setAmount}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The amount to tie to your bid. The lowest bidder moves forward.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The amount to tie to your bid. The lowest bidder moves forward.')}>
<InputBalance
autoFocus
help={t<string>('The amount to associate with your bid, should be less than the pot.')}
label={t<string>('bid amount')}
onChange={setAmount}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -60,46 +60,36 @@ function BondExtra ({ controllerId, onClose, stakingInfo, stashId }: Props): Rea
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Since this transaction deals with funding, the stash account will be used.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Since this transaction deals with funding, the stash account will be used.')}>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
</Modal.Columns>
{startBalance && (
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
defaultValue={startBalance}
help={t<string>('Amount to add to the currently bonded funds. This is adjusted using the available funds on the account.')}
isError={!!amountError?.error || !maxAdditional || maxAdditional.eqn(0)}
label={t<string>('additional bonded funds')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={stashId}
/>
}
onChange={setMaxAdditional}
/>
<ValidateAmount
controllerId={controllerId}
currentAmount={currentAmount}
onError={setAmountError}
stashId={stashId}
value={maxAdditional}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The amount placed at-stake should allow some free funds for future transactions.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The amount placed at-stake should allow some free funds for future transactions.')}>
<InputBalance
autoFocus
defaultValue={startBalance}
help={t<string>('Amount to add to the currently bonded funds. This is adjusted using the available funds on the account.')}
isError={!!amountError?.error || !maxAdditional || maxAdditional.eqn(0)}
label={t<string>('additional bonded funds')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={stashId}
/>
}
onChange={setMaxAdditional}
/>
<ValidateAmount
controllerId={controllerId}
currentAmount={currentAmount}
onError={setAmountError}
stashId={stashId}
value={maxAdditional}
/>
</Modal.Columns>
)}
</Modal.Content>

View File

@ -84,52 +84,37 @@ function InjectKeys ({ onClose }: Props): React.ReactElement<Props> | null {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
isError={publicKey.length !== 66}
label={t<string>('suri (seed & derivation)')}
onChange={setSuri}
value={suri}
/>
<MarkWarning content={t<string>('This operation will submit the seed via an RPC call. Do not perform this operation on a public RPC node, but ensure that the node is local, connected to your validator and secure.')} />
</Modal.Column>
<Modal.Column>
<p>{t<string>('The seed and derivation path will be submitted to the validator node. this is an advanced operation, only to be performed when you are sure of the security and connection risks.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The seed and derivation path will be submitted to the validator node. this is an advanced operation, only to be performed when you are sure of the security and connection risks.')}>
<Input
autoFocus
isError={publicKey.length !== 66}
label={t<string>('suri (seed & derivation)')}
onChange={setSuri}
value={suri}
/>
<MarkWarning content={t<string>('This operation will submit the seed via an RPC call. Do not perform this operation on a public RPC node, but ensure that the node is local, connected to your validator and secure.')} />
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
label={t<string>('key type to set')}
onChange={setKeyType}
options={keyTypeOptRef.current}
value={keyType}
/>
<Dropdown
isDisabled={_cryptoOptions.length === 1}
label={t<string>('crypto type to use')}
onChange={setCrypto}
options={_cryptoOptions}
value={crypto}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The key type and crypto type to use for this key. Be aware that different keys have different crypto requirements. You should be familiar with the type requirements for the different keys.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The key type and crypto type to use for this key. Be aware that different keys have different crypto requirements. You should be familiar with the type requirements for the different keys.')}>
<Dropdown
label={t<string>('key type to set')}
onChange={setKeyType}
options={keyTypeOptRef.current}
value={keyType}
/>
<Dropdown
isDisabled={_cryptoOptions.length === 1}
label={t<string>('crypto type to use')}
onChange={setCrypto}
options={_cryptoOptions}
value={crypto}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
isDisabled
label={t<string>('generated public key')}
value={publicKey}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This pubic key is what will be visible in your queued keys list. It is generated based on the seed and the crypto used.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This pubic key is what will be visible in your queued keys list. It is generated based on the seed and the crypto used.')}>
<Input
isDisabled
label={t<string>('generated public key')}
value={publicKey}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -32,38 +32,28 @@ function SetControllerAccount ({ defaultControllerId, onClose, stashId }: Props)
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
isDisabled
label={t<string>('stash account')}
value={stashId}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash account that is used. This will allow the controller to perform all non-funds related operations on behalf of the account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The stash account that is used. This will allow the controller to perform all non-funds related operations on behalf of the account.')}>
<InputAddress
isDisabled
label={t<string>('stash account')}
value={stashId}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={defaultControllerId}
help={t<string>('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
label={t<string>('controller account')}
onChange={setControllerId}
type='account'
value={controllerId}
/>
<InputValidationController
accountId={stashId}
controllerId={controllerId}
defaultController={defaultControllerId}
onError={_setError}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The selected controller tied to this stash. Once set, this account will be able to control the actions performed by the stash account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The selected controller tied to this stash. Once set, this account will be able to control the actions performed by the stash account.')}>
<InputAddress
defaultValue={defaultControllerId}
help={t<string>('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
label={t<string>('controller account')}
onChange={setControllerId}
type='account'
value={controllerId}
/>
<InputValidationController
accountId={stashId}
controllerId={controllerId}
defaultController={defaultControllerId}
onError={_setError}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -38,47 +38,37 @@ function SetRewardDestination ({ controllerId, defaultDestination, onClose, stas
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
help={t<string>('The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.')}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash and controller pair as linked. This operation will be performed via the controller.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The stash and controller pair as linked. This operation will be performed via the controller.')}>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
help={t<string>('The controller is the account that is be used to control any nominating or validating actions. I will sign this transaction.')}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
defaultValue={defaultDestination?.toString()}
help={t<string>('The destination account for any payments as either a nominator or validator')}
label={t<string>('payment destination')}
onChange={setDestination}
options={options}
value={destination}
<Modal.Columns hint={t<string>('All rewards will go towards the selected output destination when a payout is made.')}>
<Dropdown
defaultValue={defaultDestination?.toString()}
help={t<string>('The destination account for any payments as either a nominator or validator')}
label={t<string>('payment destination')}
onChange={setDestination}
options={options}
value={destination}
/>
{isAccount && (
<InputAddress
help={t('An account that is to receive the rewards')}
label={t('the payment account')}
onChange={setDestAccount}
type='account'
value={destAccount}
/>
{isAccount && (
<InputAddress
help={t('An account that is to receive the rewards')}
label={t('the payment account')}
onChange={setDestAccount}
type='account'
value={destAccount}
/>
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('All rewards will go towards the selected output destination when a payout is made.')}</p>
</Modal.Column>
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -37,55 +37,45 @@ function Unbond ({ className = '', controllerId, onClose, stakingLedger, stashId
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash and controller pair, here the controller will be used to send the transaction.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The stash and controller pair, here the controller will be used to send the transaction.')}>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
defaultValue={maxBalance}
help={t<string>('The amount of funds to unbond, this is adjusted using the bonded funds on the stash account.')}
isDisabled={withMax}
key={`unbondAmount-${withMax.toString()}`}
label={t<string>('unbond amount')}
maxValue={maxBalance}
onChange={setMaxUnbond}
withMax
<Modal.Columns hint={t<string>('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.')}>
<InputBalance
autoFocus
defaultValue={maxBalance}
help={t<string>('The amount of funds to unbond, this is adjusted using the bonded funds on the stash account.')}
isDisabled={withMax}
key={`unbondAmount-${withMax.toString()}`}
label={t<string>('unbond amount')}
maxValue={maxBalance}
onChange={setMaxUnbond}
withMax
>
<Toggle
isOverlay
label={t<string>('all bonded')}
onChange={setWithMax}
value={withMax}
/>
</InputBalance>
{bondedBlocks?.gtn(0) && (
<Static
help={t<string>('The bonding duration for any staked funds. After this period needs to be withdrawn.')}
label={t<string>('on-chain bonding duration')}
>
<Toggle
isOverlay
label={t<string>('all bonded')}
onChange={setWithMax}
value={withMax}
/>
</InputBalance>
{bondedBlocks?.gtn(0) && (
<Static
help={t<string>('The bonding duration for any staked funds. After this period needs to be withdrawn.')}
label={t<string>('on-chain bonding duration')}
>
<BlockToTime blocks={bondedBlocks} />
</Static>
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('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>
<BlockToTime blocks={bondedBlocks} />
</Static>
)}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>

View File

@ -88,9 +88,7 @@ function NewNominator ({ isInElection, targets }: Props): React.ReactElement<Pro
/>
)}
<Modal.Columns>
<Modal.Column>
<BatchWarning />
</Modal.Column>
<BatchWarning />
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={_toggle}>

View File

@ -89,9 +89,7 @@ function NewValidator ({ isInElection }: Props): React.ReactElement<Props> {
</>
)}
<Modal.Columns>
<Modal.Column>
<BatchWarning />
</Modal.Column>
<BatchWarning />
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={_toggle}>

View File

@ -93,95 +93,88 @@ function Bond ({ className = '', isNominating, minNomination, onChange }: Props)
return (
<div className={className}>
<Modal.Columns>
<Modal.Column>
<InputAddress
label={t<string>('stash account')}
onChange={setStashId}
type='account'
value={stashId}
/>
<InputAddress
help={t<string>('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
label={t<string>('controller account')}
onChange={setControllerId}
type='account'
value={controllerId}
/>
<InputValidationController
accountId={stashId}
controllerId={controllerId}
onError={_setError}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('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.')}</p>
<p>{t<string>('To ensure optimal fund security using the same stash/controller is strongly discouraged, but not forbidden.')}</p>
</Modal.Column>
</>
}>
<InputAddress
label={t<string>('stash account')}
onChange={setStashId}
type='account'
value={stashId}
/>
<InputAddress
help={t<string>('The controller is the account that will be used to control any nominating or validating actions. Should not match another stash or controller.')}
label={t<string>('controller account')}
onChange={setControllerId}
type='account'
value={controllerId}
/>
<InputValidationController
accountId={stashId}
controllerId={controllerId}
onError={_setError}
/>
</Modal.Columns>
{startBalance && (
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
defaultValue={startBalance}
help={t<string>('The total amount of the stash balance that will be at stake in any forthcoming rounds (should be less than the free amount available)')}
isError={!hasValue || !!amountError?.error}
label={t<string>('value bonded')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={stashId}
/>
}
onChange={setAmount}
/>
<InputValidateAmount
controllerId={controllerId}
isNominating={isNominating}
minNomination={minNomination}
onError={setAmountError}
stashId={stashId}
value={amount}
/>
{bondedBlocks?.gtn(0) && (
<Static
help={t<string>('The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.')}
label={t<string>('on-chain bonding duration')}
>
<BlockToTime blocks={bondedBlocks} />
</Static>
)}
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The amount placed at-stake should not be your full available available amount to allow for transaction fees.')}</p>
<p>{t<string>('Once bonded, it wil need to be unlocked/withdrawn and will be locked for at least the bonding duration.')}</p>
</Modal.Column>
</>
}>
<InputBalance
autoFocus
defaultValue={startBalance}
help={t<string>('The total amount of the stash balance that will be at stake in any forthcoming rounds (should be less than the free amount available)')}
isError={!hasValue || !!amountError?.error}
label={t<string>('value bonded')}
labelExtra={
<BalanceFree
label={<span className='label'>{t<string>('balance')}</span>}
params={stashId}
/>
}
onChange={setAmount}
/>
<InputValidateAmount
controllerId={controllerId}
isNominating={isNominating}
minNomination={minNomination}
onError={setAmountError}
stashId={stashId}
value={amount}
/>
{bondedBlocks?.gtn(0) && (
<Static
help={t<string>('The bonding duration for any staked funds. Needs to be unlocked and withdrawn to become available.')}
label={t<string>('on-chain bonding duration')}
>
<BlockToTime blocks={bondedBlocks} />
</Static>
)}
</Modal.Columns>
)}
<Modal.Columns>
<Modal.Column>
<Dropdown
defaultValue={0}
help={t<string>('The destination account for any payments as either a nominator or validator')}
label={t<string>('payment destination')}
onChange={setDestination}
options={options}
value={destination}
<Modal.Columns hint={t<string>('Rewards (once paid) can be deposited to either the stash or controller, with different effects.')}>
<Dropdown
defaultValue={0}
help={t<string>('The destination account for any payments as either a nominator or validator')}
label={t<string>('payment destination')}
onChange={setDestination}
options={options}
value={destination}
/>
{isAccount && (
<InputAddress
help={t('An account that is to receive the rewards')}
label={t('the payment account')}
onChange={setDestAccount}
type='account'
value={destAccount}
/>
{isAccount && (
<InputAddress
help={t('An account that is to receive the rewards')}
label={t('the payment account')}
onChange={setDestAccount}
type='account'
value={destAccount}
/>
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('Rewards (once paid) can be deposited to either the stash or controller, with different effects.')}</p>
</Modal.Column>
)}
</Modal.Columns>
</div>
);

View File

@ -61,23 +61,22 @@ function Nominate ({ className = '', controllerId, nominating, onChange, stashId
stashId={stashId}
/>
)}
<Modal.Columns>
<Modal.Column>
<InputAddressMulti
available={available}
availableLabel={t<string>('candidate accounts')}
defaultValue={nominating}
help={t<string>('Filter available candidates based on name, address or short account index.')}
maxCount={MAX_NOMINATIONS}
onChange={setSelected}
valueLabel={t<string>('nominated accounts')}
/>
<MarkWarning content={t<string>('You should trust your nominations to act competently and honest; basing your decision purely on their current profitability could lead to reduced profits or even loss of funds.')} />
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('Nominators can be selected manually from the list of all currently available validators.')}</p>
<p>{t<string>('Once transmitted the new selection will only take effect in 2 eras taking the new validator election cycle into account. Until then, the nominations will show as inactive.')}</p>
</Modal.Column>
</>
}>
<InputAddressMulti
available={available}
availableLabel={t<string>('candidate accounts')}
defaultValue={nominating}
help={t<string>('Filter available candidates based on name, address or short account index.')}
maxCount={MAX_NOMINATIONS}
onChange={setSelected}
valueLabel={t<string>('nominated accounts')}
/>
<MarkWarning content={t<string>('You should trust your nominations to act competently and honest; basing your decision purely on their current profitability could lead to reduced profits or even loss of funds.')} />
</Modal.Columns>
</div>
);

View File

@ -17,22 +17,20 @@ function SenderInfo ({ className = '', controllerId, stashId }: Props): React.Re
const { t } = useTranslation();
return (
<Modal.Columns className={className}>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash that is to be affected. The transaction will be sent from the associated controller account.')}</p>
</Modal.Column>
<Modal.Columns
className={className}
hint={t<string>('The stash that is to be affected. The transaction will be sent from the associated controller account.')}
>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Columns>
);
}

View File

@ -42,39 +42,29 @@ function SessionKey ({ className = '', controllerId, onChange, stashId, withSend
return (
<div className={className}>
{withSenders && (
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash and controller pair. This transaction, setting the session keys, will be sent from the controller.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The stash and controller pair. This transaction, setting the session keys, will be sent from the controller.')}>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
className='medium'
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Columns>
)}
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t<string>('Changing the key only takes effect at the start of the next session. The input here is generates from the author_rotateKeys command')}
isError={!keys}
label={t<string>('Keys from rotateKeys')}
onChange={setKeys}
placeholder='0x...'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The hex output from author_rotateKeys, as executed on the validator node. The keys will show as pending until applied at the start of a new session.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The hex output from author_rotateKeys, as executed on the validator node. The keys will show as pending until applied at the start of a new session.')}>
<Input
autoFocus
help={t<string>('Changing the key only takes effect at the start of the next session. The input here is generates from the author_rotateKeys command')}
isError={!keys}
label={t<string>('Keys from rotateKeys')}
onChange={setKeys}
placeholder='0x...'
/>
</Modal.Columns>
</div>
);

View File

@ -58,52 +58,37 @@ function Validate ({ className = '', controllerId, onChange, stashId, withSender
return (
<div className={className}>
{withSenders && (
<Modal.Columns>
<Modal.Column>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The stash and controller pair. This transaction, managing preferences, will be sent from the controller.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The stash and controller pair. This transaction, managing preferences, will be sent from the controller.')}>
<InputAddress
defaultValue={stashId}
isDisabled
label={t<string>('stash account')}
/>
<InputAddress
defaultValue={controllerId}
isDisabled
label={t<string>('controller account')}
/>
</Modal.Columns>
)}
<Modal.Columns>
<Modal.Column>
<InputNumber
help={t<string>('The percentage reward (0-100) that should be applied for the validator')}
isZeroable
label={t<string>('reward commission percentage')}
maxValue={MAX_COMM}
onChange={_setCommission}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The commission is deducted from all rewards before the remainder is split with nominators.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The commission is deducted from all rewards before the remainder is split with nominators.')}>
<InputNumber
help={t<string>('The percentage reward (0-100) that should be applied for the validator')}
isZeroable
label={t<string>('reward commission percentage')}
maxValue={MAX_COMM}
onChange={_setCommission}
/>
</Modal.Columns>
{isFunction(api.tx.staking.kick) && (
<Modal.Columns>
<Modal.Column>
<Dropdown
defaultValue={true}
help={t<string>('Does this validator allow nominations or is it blocked for all')}
label={t<string>('allows new nominations')}
onChange={setAllowNoms}
options={blockedOptions.current}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The validator can block any new nominations. By default it is set to allow all nominations.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The validator can block any new nominations. By default it is set to allow all nominations.')}>
<Dropdown
defaultValue={true}
help={t<string>('Does this validator allow nominations or is it blocked for all')}
label={t<string>('allows new nominations')}
onChange={setAllowNoms}
options={blockedOptions.current}
/>
</Modal.Columns>
)}
</div>

View File

@ -124,49 +124,43 @@ function PayButton ({ className, isAll, isDisabled, payout }: Props): React.Reac
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
label={t<string>('request payout from')}
onChange={setAccount}
type='account'
value={accountId}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Any account can request payout for stakers, this is not limited to accounts that will be rewarded.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Any account can request payout for stakers, this is not limited to accounts that will be rewarded.')}>
<InputAddress
label={t<string>('request payout from')}
onChange={setAccount}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
{Array.isArray(payout)
? (
<Static
label={t<string>('payout stakers for (multiple)')}
value={
payout.map(({ validatorId }) => (
<AddressMini
className='addressStatic'
key={validatorId}
value={validatorId}
/>
))
}
/>
)
: (
<InputAddress
defaultValue={payout.validatorId}
isDisabled
label={t<string>('payout stakers for (single)')}
/>
)
}
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('All the listed validators and all their nominators will receive their rewards.')}</p>
<p>{t<string>('The UI puts a limit of 40 payouts at a time, where each payout is a single validator for a single era.')}</p>
</Modal.Column>
</>
}>
{Array.isArray(payout)
? (
<Static
label={t<string>('payout stakers for (multiple)')}
value={
payout.map(({ validatorId }) => (
<AddressMini
className='addressStatic'
key={validatorId}
value={validatorId}
/>
))
}
/>
)
: (
<InputAddress
defaultValue={payout.validatorId}
isDisabled
label={t<string>('payout stakers for (single)')}
/>
)
}
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={togglePayout}>

View File

@ -62,44 +62,38 @@ function Nominate ({ className = '', isDisabled, ownNominators, targets }: Props
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={stashes}
help={t<string>('Your stash account. The transaction will be sent from the associated controller.')}
label={t<string>('the stash account to nominate with')}
onChange={_onChangeStash}
value={ids?.stashId}
/>
<InputAddress
isDisabled
label={t<string>('the associated controller')}
value={ids?.controllerId}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('One of your available nomination accounts, keyed by the stash. The transaction will be sent from the controller.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('One of your available nomination accounts, keyed by the stash. The transaction will be sent from the controller.')}>
<InputAddress
filter={stashes}
help={t<string>('Your stash account. The transaction will be sent from the associated controller.')}
label={t<string>('the stash account to nominate with')}
onChange={_onChangeStash}
value={ids?.stashId}
/>
<InputAddress
isDisabled
label={t<string>('the associated controller')}
value={ids?.controllerId}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Static
label={t<string>('selected validators')}
value={
targets.map((validatorId) => (
<AddressMini
className='addressStatic'
key={validatorId}
value={validatorId}
/>
))
}
/>
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The selected validators to nominate, either via the "currently best algorithm" or via a manual selection.')}</p>
<p>{t<string>('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.')}</p>
</Modal.Column>
</>
}>
<Static
label={t<string>('selected validators')}
value={
targets.map((validatorId) => (
<AddressMini
className='addressStatic'
key={validatorId}
value={validatorId}
/>
))
}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -37,30 +37,20 @@ function Close ({ hasFailed, hash, idNumber, members, proposal }: Props): React.
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted for a subsequent voting round.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The proposal that will be affected. Once closed for the current voting round, it would need to be re-submitted for a subsequent voting round.')}>
<ProposedAction
idNumber={idNumber}
proposal={proposal}
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish close the proposal with.')}
label={t<string>('sending account')}
onChange={setAccountId}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The committee account that will apply the close for the current round.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The committee account that will apply the close for the current round.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish close the proposal with.')}
label={t<string>('sending account')}
onChange={setAccountId}
type='account'
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -54,34 +54,24 @@ function Council ({ id, isDisabled, members }: Props): React.ReactElement<Props>
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the council account you wish to use to make the proposal.')}
label={t<string>('submit with council account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The council member that is proposing this, submission equates to an "aye" vote.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The council member that is proposing this, submission equates to an "aye" vote.')}>
<InputAddress
filter={members}
help={t<string>('Select the council account you wish to use to make the proposal.')}
label={t<string>('submit with council account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Dropdown
help={t<string>('The type of council proposal to submit.')}
label={t<string>('council proposal type')}
onChange={setCouncilType}
options={councilTypeOptRef.current}
value={councilType}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Proposal can either be to approve or reject this spend. Once approved, the change is applied by either removing the proposal or scheduling payout.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Proposal can either be to approve or reject this spend. Once approved, the change is applied by either removing the proposal or scheduling payout.')}>
<Dropdown
help={t<string>('The type of council proposal to submit.')}
label={t<string>('council proposal type')}
onChange={setCouncilType}
options={councilTypeOptRef.current}
value={councilType}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -37,59 +37,48 @@ function Propose ({ className }: Props): React.ReactElement<Props> | null {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select the account you wish to submit the proposal from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('This account will make the proposal and be responsible for the bond.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('This account will make the proposal and be responsible for the bond.')}>
<InputAddress
help={t<string>('Select the account you wish to submit the proposal from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The account to which the proposed balance will be transferred if approved')}
label={t<string>('beneficiary')}
onChange={setBeneficiary}
type='allPlus'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The beneficiary will receive the full amount if the proposal passes.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The beneficiary will receive the full amount if the proposal passes.')}>
<InputAddress
help={t<string>('The account to which the proposed balance will be transferred if approved')}
label={t<string>('beneficiary')}
onChange={setBeneficiary}
type='allPlus'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
help={t<string>('The amount that will be allocated from the treasury pot')}
isError={!hasValue}
label={t<string>('value')}
onChange={setValue}
/>
<Static
help={t<string>('The on-chain percentage for the treasury')}
label={t<string>('proposal bond')}
>
{bondPercentage}
</Static>
<InputBalance
defaultValue={api.consts.treasury.proposalBondMinimum.toString()}
help={t<string>('The minimum amount that will be bonded')}
isDisabled
label={t<string>('minimum bond')}
/>
<MarkWarning content={t<string>('Be aware that once submitted the proposal will be put to a council vote. If the proposal is rejected due to a lack of info, invalid requirements or non-benefit to the network as a whole, the full bond posted (as describe above) will be lost.')} />
</Modal.Column>
<Modal.Column>
<Modal.Columns hint={
<>
<p>{t<string>('The value is the amount that is being asked for and that will be allocated to the beneficiary if the proposal is approved.')}</p>
<p>{t<string>('Of the beneficiary amount, at least {{bondPercentage}} would need to be put up as collateral. The maximum of this and the minimum bond will be used to secure the proposal, refundable if it passes.', { replace: { bondPercentage } })}</p>
</Modal.Column>
</>
}>
<InputBalance
help={t<string>('The amount that will be allocated from the treasury pot')}
isError={!hasValue}
label={t<string>('value')}
onChange={setValue}
/>
<Static
help={t<string>('The on-chain percentage for the treasury')}
label={t<string>('proposal bond')}
>
{bondPercentage}
</Static>
<InputBalance
defaultValue={api.consts.treasury.proposalBondMinimum.toString()}
help={t<string>('The minimum amount that will be bonded')}
isDisabled
label={t<string>('minimum bond')}
/>
<MarkWarning content={t<string>('Be aware that once submitted the proposal will be put to a council vote. If the proposal is rejected due to a lack of info, invalid requirements or non-benefit to the network as a whole, the full bond posted (as describe above) will be lost.')} />
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -46,60 +46,40 @@ function TipCreate ({ members, refresh }: Props): React.ReactElement<Props> {
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('Select the account you wish to submit the tip from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Use this account to request the tip from. This can be a normal or council account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Use this account to request the tip from. This can be a normal or council account.')}>
<InputAddress
help={t<string>('Select the account you wish to submit the tip from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputAddress
help={t<string>('The account to which the tip will be transferred if approved')}
label={t<string>('beneficiary')}
onChange={setBeneficiary}
type='allPlus'
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('The beneficiary will received the tip as approved by council members.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('The beneficiary will received the tip as approved by council members.')}>
<InputAddress
help={t<string>('The account to which the tip will be transferred if approved')}
label={t<string>('beneficiary')}
onChange={setBeneficiary}
type='allPlus'
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<Input
autoFocus
help={t<string>('The reason why this tip should be paid.')}
isError={!hasReason}
label={t<string>('tip reason')}
onChange={setReason}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('A reason (to be stored-on-chain) as to why the recipient deserves a tip payout.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('A reason (to be stored-on-chain) as to why the recipient deserves a tip payout.')}>
<Input
autoFocus
help={t<string>('The reason why this tip should be paid.')}
isError={!hasReason}
label={t<string>('tip reason')}
onChange={setReason}
/>
</Modal.Columns>
{isMember && (
<Modal.Columns>
<Modal.Column>
<InputBalance
help={t<string>('The suggested value for this tip')}
isError={!hasValue}
label={t<string>('tip value')}
onChange={setValue}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('As a council member, you can suggest an initial value for the tip, each other council member can suggest their own.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('As a council member, you can suggest an initial value for the tip, each other council member can suggest their own.')}>
<InputBalance
help={t<string>('The suggested value for this tip')}
isError={!hasValue}
label={t<string>('tip value')}
onChange={setValue}
/>
</Modal.Columns>
)}
</Modal.Content>

View File

@ -49,35 +49,25 @@ function TipEndorse ({ defaultId, hash, isMember, isTipped, median, members }: P
size='large'
>
<Modal.Content>
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to submit the tip from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Your endorsement will be applied for this account.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Your endorsement will be applied for this account.')}>
<InputAddress
filter={members}
help={t<string>('Select the account you wish to submit the tip from.')}
label={t<string>('submit with account')}
onChange={setAccountId}
type='account'
withLabel
/>
</Modal.Columns>
<Modal.Columns>
<Modal.Column>
<InputBalance
autoFocus
defaultValue={median}
help={t<string>('The tip amount that should be allocated')}
isZeroable
label={t<string>('value')}
onChange={setValue}
/>
</Modal.Column>
<Modal.Column>
<p>{t<string>('Allocate a suggested tip amount. With enough endorsements, the suggested values are averaged and sent to the beneficiary.')}</p>
</Modal.Column>
<Modal.Columns hint={t<string>('Allocate a suggested tip amount. With enough endorsements, the suggested values are averaged and sent to the beneficiary.')}>
<InputBalance
autoFocus
defaultValue={median}
help={t<string>('The tip amount that should be allocated')}
isZeroable
label={t<string>('value')}
onChange={setValue}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={toggleOpen}>

View File

@ -1,46 +0,0 @@
// Copyright 2017-2021 @polkadot/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ColumnProps } from './types';
import React from 'react';
import styled from 'styled-components';
function Column ({ children, className = '' }: ColumnProps): React.ReactElement<ColumnProps> {
return (
<div className={`ui--Modal-Column ${className}`}>
{children}
</div>
);
}
export default React.memo(styled(Column)`
padding: 0.25em 0;
&:nth-child(1) {
flex: 100%;
max-width: 100%;
}
&:nth-child(2) {
display: none;
flex: 0%;
}
@media only screen and (min-width: 1024px) {
&:nth-child(1),
&:only-child {
flex: 0 65%;
max-width: 65%;
}
&:nth-child(2) {
box-sizing: border-box;
display: block;
flex: 0 34%;
font-size: 0.95rem;
opacity: 0.75;
padding: 0.25em 0.5rem;
}
}
`);

View File

@ -1,18 +1,17 @@
// Copyright 2017-2021 @polkadot/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ColumnProps } from './types';
import type { ColumnsProps } from './types';
import React from 'react';
import styled from 'styled-components';
import Column from './Column';
function Columns ({ children, className = '', hint }: ColumnProps): React.ReactElement<ColumnProps> {
function Columns ({ children, className = '', hint }: ColumnsProps): React.ReactElement<ColumnsProps> {
return (
<div className={`ui--Modal-Columns ${className}`}>
{children}{hint && (
<Column>{hint}</Column>
<div>{children}</div>
{hint && (
<div>{hint}</div>
)}
</div>
);
@ -26,4 +25,35 @@ export default React.memo(styled(Columns)`
&+& {
margin-top: 0.25rem;
}
> div {
padding: 0.25em 0;
&:nth-child(1) {
flex: 100%;
max-width: 100%;
}
&:nth-child(2) {
display: none;
flex: 0%;
}
@media only screen and (min-width: 1024px) {
&:nth-child(1),
&:only-child {
flex: 0 65%;
max-width: 65%;
}
&:nth-child(2) {
box-sizing: border-box;
display: block;
flex: 0 34%;
font-size: 0.95rem;
opacity: 0.75;
padding: 0.25em 0.5rem;
}
}
}
`);

View File

@ -2,20 +2,18 @@
// SPDX-License-Identifier: Apache-2.0
import type { ThemeDef } from '@polkadot/react-components/types';
import type { ActionsProps, ColumnProps, ModalProps } from './types';
import type { ActionsProps, ColumnsProps, ModalProps } from './types';
import React, { useContext } from 'react';
import { Modal as SUIModal } from 'semantic-ui-react';
import { ThemeContext } from 'styled-components';
import Actions from './Actions';
import Column from './Column';
import Columns from './Columns';
type ModalType = React.FC<ModalProps> & {
Actions: React.FC<ActionsProps>;
Column: React.FC<ColumnProps>;
Columns: React.FC<ColumnProps>;
Columns: React.FC<ColumnsProps>;
Content: typeof SUIModal.Content;
Header: typeof SUIModal.Header;
Description: typeof SUIModal.Description;
@ -43,7 +41,6 @@ function ModalBase (props: ModalProps): React.ReactElement<ModalProps> {
const Modal = React.memo(ModalBase) as unknown as ModalType;
Modal.Actions = Actions;
Modal.Column = Column;
Modal.Columns = Columns;
Modal.Content = SUIModal.Content;
Modal.Header = SUIModal.Header;

View File

@ -3,7 +3,7 @@
import React from 'react';
export interface ColumnProps {
export interface ColumnsProps {
children: React.ReactNode;
className?: string;
hint?: React.ReactNode;

View File

@ -216,51 +216,36 @@ function Address ({ currentItem, onChange, onEnter, passwordError, requestAddres
return (
<>
<Modal.Columns>
<Modal.Column>
<InputAddress
className='full'
defaultValue={requestAddress}
isDisabled
isInput
label={t('sending from my account')}
withLabel
/>
</Modal.Column>
<Modal.Column>
<p>{t('The sending account that will be used to send this transaction. Any applicable fees will be paid by this account.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The sending account that will be used to send this transaction. Any applicable fees will be paid by this account.')}>
<InputAddress
className='full'
defaultValue={requestAddress}
isDisabled
isInput
label={t('sending from my account')}
withLabel
/>
</Modal.Columns>
{proxyInfo && isProxyActive && (
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={proxyInfo.proxiesFilter}
help={t('The proxy to be used for this transaction.')}
label={t('proxy account')}
onChange={setProxyAddress}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t('The proxy is one of the allowed proxies on the account, as set and filtered by the transaction type.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The proxy is one of the allowed proxies on the account, as set and filtered by the transaction type.')}>
<InputAddress
filter={proxyInfo.proxiesFilter}
help={t('The proxy to be used for this transaction.')}
label={t('proxy account')}
onChange={setProxyAddress}
type='account'
/>
</Modal.Columns>
)}
{multiInfo && (
<Modal.Columns>
<Modal.Column>
<InputAddress
filter={multiInfo.whoFilter}
help={t('The multisig signatory for this transaction.')}
label={t('multisig signatory')}
onChange={setMultiAddress}
type='account'
/>
</Modal.Column>
<Modal.Column>
<p>{t('The signatory is one of the allowed accounts on the multisig, making a recorded approval for the transaction.')}</p>
</Modal.Column>
<Modal.Columns hint={t('The signatory is one of the allowed accounts on the multisig, making a recorded approval for the transaction.')}>
<InputAddress
filter={multiInfo.whoFilter}
help={t('The multisig signatory for this transaction.')}
label={t('multisig signatory')}
onChange={setMultiAddress}
type='account'
/>
</Modal.Columns>
)}
{signAddress && !currentItem.isUnsigned && flags.isUnlockable && (
@ -273,48 +258,36 @@ function Address ({ currentItem, onChange, onEnter, passwordError, requestAddres
)}
{passwordError && (
<Modal.Columns>
<Modal.Column>
<MarkError content={passwordError} />
</Modal.Column>
<MarkError content={passwordError} />
</Modal.Columns>
)}
{proxyInfo && (
<Modal.Columns>
<Modal.Column>
<Toggle
className='tipToggle'
isDisabled={proxyInfo.isProxied}
label={
isProxyActive
? t<string>('Use a proxy for this call')
: t<string>("Don't use a proxy for this call")
}
onChange={setIsProxyActive}
value={isProxyActive}
/>
</Modal.Column>
<Modal.Column>
<p>{t('This could either be an approval for the hash or with full call details. The call as last approval triggers execution.')}</p>
</Modal.Column>
<Modal.Columns hint={t('This could either be an approval for the hash or with full call details. The call as last approval triggers execution.')}>
<Toggle
className='tipToggle'
isDisabled={proxyInfo.isProxied}
label={
isProxyActive
? t<string>('Use a proxy for this call')
: t<string>("Don't use a proxy for this call")
}
onChange={setIsProxyActive}
value={isProxyActive}
/>
</Modal.Columns>
)}
{multiInfo && (
<Modal.Columns>
<Modal.Column>
<Toggle
className='tipToggle'
label={
isMultiCall
? t<string>('Multisig message with call (for final approval)')
: t<string>('Multisig approval with hash (non-final approval)')
}
onChange={setIsMultiCall}
value={isMultiCall}
/>
</Modal.Column>
<Modal.Column>
<p>{t('This could either be an approval for the hash or with full call details. The call as last approval triggers execution.')}</p>
</Modal.Column>
<Modal.Columns hint={t('This could either be an approval for the hash or with full call details. The call as last approval triggers execution.')}>
<Toggle
className='tipToggle'
label={
isMultiCall
? t<string>('Multisig message with call (for final approval)')
: t<string>('Multisig approval with hash (non-final approval)')
}
onChange={setIsMultiCall}
value={isMultiCall}
/>
</Modal.Columns>
)}
</>

View File

@ -49,28 +49,26 @@ function Unlock ({ address, className, error, onChange, onEnter, tabIndex }: Pro
}
return (
<Modal.Columns className={className}>
<Modal.Column>
<Password
autoFocus
isError={!!error}
label={t<string>('unlock account with password')}
onChange={setPassword}
onEnter={onEnter}
tabIndex={tabIndex}
value={password}
>
<Toggle
isOverlay
label={t<string>('unlock for {{expiry}} min', { replace: { expiry: UNLOCK_MINS } })}
onChange={setIsUnlockCached}
value={isUnlockCached}
/>
</Password>
</Modal.Column>
<Modal.Column>
<p>{t('Unlock the sending account to allow signing of this transaction.')}</p>
</Modal.Column>
<Modal.Columns
className={className}
hint={t('Unlock the sending account to allow signing of this transaction.')}
>
<Password
autoFocus
isError={!!error}
label={t<string>('unlock account with password')}
onChange={setPassword}
onEnter={onEnter}
tabIndex={tabIndex}
value={password}
>
<Toggle
isOverlay
label={t<string>('unlock for {{expiry}} min', { replace: { expiry: UNLOCK_MINS } })}
onChange={setIsUnlockCached}
value={isUnlockCached}
/>
</Password>
</Modal.Columns>
);
}

View File

@ -48,43 +48,33 @@ function SignFields ({ address, onChange, signedTx }: Props): React.ReactElement
return (
<>
<Modal.Columns>
<Modal.Column>
<InputNumber
isDisabled={!!signedTx}
isZeroable
label={t<string>('Nonce')}
labelExtra={t<string>('Current account nonce: {{accountNonce}}', { replace: { accountNonce: nonce } })}
onChange={_setNonce}
value={nonce}
/>
<InputNumber
isDisabled={!!signedTx}
isZeroable
label={t<string>('Lifetime (# of blocks)')}
labelExtra={t<string>('Set to 0 to make transaction immortal')}
onChange={_setBlocks}
value={blocks}
/>
</Modal.Column>
<Modal.Column>
<p>{t('Override any applicable values for the specific signed output. These will be used to construct and display the signed transaction.')}</p>
</Modal.Column>
<Modal.Columns hint={t('Override any applicable values for the specific signed output. These will be used to construct and display the signed transaction.')}>
<InputNumber
isDisabled={!!signedTx}
isZeroable
label={t<string>('Nonce')}
labelExtra={t<string>('Current account nonce: {{accountNonce}}', { replace: { accountNonce: nonce } })}
onChange={_setNonce}
value={nonce}
/>
<InputNumber
isDisabled={!!signedTx}
isZeroable
label={t<string>('Lifetime (# of blocks)')}
labelExtra={t<string>('Set to 0 to make transaction immortal')}
onChange={_setBlocks}
value={blocks}
/>
</Modal.Columns>
{!!signedTx && (
<Modal.Columns>
<Modal.Column>
<Output
isFull
isTrimmed
label={t<string>('Signed transaction')}
value={signedTx}
withCopy
/>
</Modal.Column>
<Modal.Column>
{t('The actual fully constructed signed output. This can be used for submission via other channels.')}
</Modal.Column>
<Modal.Columns hint={t('The actual fully constructed signed output. This can be used for submission via other channels.')}>
<Output
isFull
isTrimmed
label={t<string>('Signed transaction')}
value={signedTx}
withCopy
/>
</Modal.Columns>
)}
</>

View File

@ -24,30 +24,28 @@ function Tip ({ className, onChange }: Props): React.ReactElement<Props> | null
}, [onChange, showTip, tip]);
return (
<Modal.Columns className={className}>
<Modal.Column>
<Toggle
className='tipToggle'
label={
showTip
? t<string>('Include an optional tip for faster processing')
: t<string>('Do not include a tip for the block author')
}
onChange={setShowTip}
value={showTip}
<Modal.Columns
className={className}
hint={t<string>('Adding an optional tip to the transaction could allow for higher priority, especially when the chain is busy.')}
>
<Toggle
className='tipToggle'
label={
showTip
? t<string>('Include an optional tip for faster processing')
: t<string>('Do not include a tip for the block author')
}
onChange={setShowTip}
value={showTip}
/>
{showTip && (
<InputBalance
help={t<string>('Add a tip to this extrinsic, paying the block author for greater priority')}
isZeroable
label={t<string>('Tip (optional)')}
onChange={setTip}
/>
{showTip && (
<InputBalance
help={t<string>('Add a tip to this extrinsic, paying the block author for greater priority')}
isZeroable
label={t<string>('Tip (optional)')}
onChange={setTip}
/>
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('Adding an optional tip to the transaction could allow for higher priority, especially when the chain is busy.')}</p>
</Modal.Column>
)}
</Modal.Columns>
);
}

View File

@ -31,32 +31,30 @@ function Transaction ({ className, currentItem: { accountId, extrinsic, isUnsign
const args = meta?.args.map(({ name }) => name).join(', ') || '';
return (
<Modal.Columns className={className}>
<Modal.Column>
<Expander
<Modal.Columns
className={className}
hint={t<string>('The details of the transaction including the type, the description (as available from the chain metadata) as well as any parameters and fee estimations (as available) for the specific type of call.')}
>
<Expander
className='tx-details'
summary={<>{t<string>('Sending transaction')} <span className='highlight'>{section}.{method}({args})</span></>}
summaryMeta={meta}
>
<Call
onError={onError}
value={extrinsic}
withBorder={false}
/>
</Expander>
{!isUnsigned && !payload && (
<PaymentInfo
accountId={accountId}
className='tx-details'
summary={<>{t<string>('Sending transaction')} <span className='highlight'>{section}.{method}({args})</span></>}
summaryMeta={meta}
>
<Call
onError={onError}
value={extrinsic}
withBorder={false}
/>
</Expander>
{!isUnsigned && !payload && (
<PaymentInfo
accountId={accountId}
className='tx-details'
extrinsic={extrinsic}
isSendable={isSendable}
tip={tip}
/>
)}
</Modal.Column>
<Modal.Column>
<p>{t<string>('The details of the transaction including the type, the description (as available from the chain metadata) as well as any parameters and fee estimations (as available) for the specific type of call.')}</p>
</Modal.Column>
extrinsic={extrinsic}
isSendable={isSendable}
tip={tip}
/>
)}
</Modal.Columns>
);
}

View File

@ -368,19 +368,14 @@ function TxSigned ({ className, currentItem, requestAddress }: Props): React.Rea
/>
)}
{isSubmit && !senderInfo.isMultiCall && multiCall && (
<Modal.Columns>
<Modal.Column>
<Output
isFull
isTrimmed
label={t<string>('multisig call data')}
value={multiCall}
withCopy
/>
</Modal.Column>
<Modal.Column>
{t('The call data that can be supplied to a final call to multi approvals')}
</Modal.Column>
<Modal.Columns hint={t('The call data that can be supplied to a final call to multi approvals')}>
<Output
isFull
isTrimmed
label={t<string>('multisig call data')}
value={multiCall}
withCopy
/>
</Modal.Columns>
)}
</>