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:
parent
b20773e47b
commit
a86bc3284a
@ -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}>
|
||||
|
||||
@ -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 && (
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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
|
||||
}}
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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]
|
||||
);
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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()}
|
||||
/>
|
||||
|
||||
@ -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>
|
||||
|
||||
10
packages/page-parachains/src/Overview/types.ts
Normal file
10
packages/page-parachains/src/Overview/types.ts
Normal 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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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}>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
`);
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export interface ColumnProps {
|
||||
export interface ColumnsProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
hint?: React.ReactNode;
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
</>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
</>
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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>
|
||||
)}
|
||||
</>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user