Add ability to second proposals (#1150)

This commit is contained in:
Jaco Greeff 2019-05-14 07:37:55 +02:00 committed by GitHub
parent 539e0fded5
commit bc15fa8d79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 138 additions and 105 deletions

View File

@ -7,55 +7,61 @@ import { I18nProps } from '@polkadot/ui-app/types';
import BN from 'bn.js';
import React from 'react';
import { AccountId, Balance, Option, Proposal, Tuple, Vector } from '@polkadot/types';
import { AddressMini, Labelled, Static } from '@polkadot/ui-app';
import { InputAddress, Labelled, Static } from '@polkadot/ui-app';
import { withCalls, withMulti } from '@polkadot/ui-api';
import { formatBalance } from '@polkadot/util';
import Item from './Item';
import translate from '../translate';
import Item from './Item';
import Seconding from './Seconding';
type Props = I18nProps & {
democracy_depositOf?: Option<Tuple>,
democracy_depositOf?: [Balance, Vector<AccountId>] | null,
idNumber: BN,
value: Tuple
value: Proposal
};
class ProposalDisplay extends React.PureComponent<Props> {
render () {
const { idNumber, value } = this.props;
const { democracy_depositOf, idNumber, value } = this.props;
const depositors = democracy_depositOf
? democracy_depositOf[1]
: [];
return (
<Item
idNumber={idNumber}
proposal={value[1] as Proposal}
proposal={value}
proposalExtra={this.renderExtra()}
/>
>
<Seconding
depositors={depositors}
proposalId={idNumber}
/>
</Item>
);
}
private renderExtra () {
const { democracy_depositOf, t } = this.props;
if (!democracy_depositOf || democracy_depositOf.isNone) {
if (!democracy_depositOf) {
return null;
}
const value = democracy_depositOf.unwrap();
const balance = value[0] as Balance;
const addresses = value[1] as Vector<AccountId>;
const [balance, addresses] = democracy_depositOf;
return (
<div className='democracy--Proposal-info'>
<Labelled label={t('depositors')}>
<div>
{addresses.map((address, index) => (
<AddressMini
isPadded={false}
key={`${index}:${address}`}
value={address}
/>
))}
</div>
{addresses.map((address, index) => (
<InputAddress
isDisabled
key={`${index}:${address}`}
value={address}
withLabel={false}
/>
))}
</Labelled>
<Static label={t('balance')}>
{formatBalance(balance)}
@ -69,6 +75,10 @@ export default withMulti(
ProposalDisplay,
translate,
withCalls<Props>(
['query.democracy.depositOf', { paramName: 'idNumber' }]
['query.democracy.depositOf', {
paramName: 'idNumber',
transform: (value: Option<Tuple>) =>
value.unwrapOr(null)
}]
)
);

View File

@ -4,15 +4,16 @@
import { I18nProps } from '@polkadot/ui-app/types';
import BN from 'bn.js';
import React from 'react';
import { Tuple } from '@polkadot/types';
import { Proposal } from '@polkadot/types';
import { withCalls, withMulti } from '@polkadot/ui-api';
import Proposal from './Proposal';
import ProposalDisplay from './Proposal';
import translate from '../translate';
type Props = I18nProps & {
democracy_publicProps?: Array<Tuple>
democracy_publicProps?: Array<[BN, Proposal]>
};
type State = {
@ -48,10 +49,10 @@ class Proposals extends React.PureComponent<Props> {
);
}
return democracy_publicProps.map((proposal) => (
<Proposal
idNumber={proposal[0]}
key={proposal[0].toString()}
return democracy_publicProps.map(([idNumber, proposal]) => (
<ProposalDisplay
idNumber={idNumber}
key={idNumber.toString()}
value={proposal}
/>
));

View File

@ -0,0 +1,73 @@
// Copyright 2017-2019 @polkadot/app-democracy authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import BN from 'bn.js';
import React from 'react';
import { AccountId } from '@polkadot/types';
import { Button, InputAddress, TxButton } from '@polkadot/ui-app';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import { withMulti, withObservable } from '@polkadot/ui-api';
import translate from '../translate';
type Props = I18nProps & {
allAccounts?: SubjectInfo,
depositors: Array<AccountId>,
proposalId: BN | number
};
type State = {
accountId?: string
};
class Seconding extends React.PureComponent<Props, State> {
state: State = {};
render () {
const { allAccounts, depositors, proposalId, t } = this.props;
const { accountId } = this.state;
const hasAccounts = allAccounts && Object.keys(allAccounts).length !== 0;
if (!hasAccounts) {
return null;
}
const isDepositor = !!depositors.find((depositor) => depositor.eq(accountId));
return (
<div className='democarcy--Proposal-second'>
<InputAddress
help={t('Select the account you wish to second with. This will lock your funds until the proposal is either approved or rejected')}
label={t('using my account')}
onChange={this.onChangeAccount}
type='account'
withLabel
/>
<Button.Group>
<TxButton
accountId={accountId}
isDisabled={!accountId || isDepositor}
isPrimary
label={t('Second')}
params={[proposalId]}
tx='democracy.second'
/>
</Button.Group>
</div>
);
}
private onChangeAccount = (accountId?: string) => {
this.setState({ accountId });
}
}
export default withMulti(
Seconding,
translate,
withObservable(accountObservable.subject, { propName: 'allAccounts' })
);

View File

@ -7,11 +7,10 @@ import { SubjectInfo } from '@polkadot/ui-keyring/observable/types';
import BN from 'bn.js';
import React from 'react';
import { InputAddress } from '@polkadot/ui-app';
import { Button, InputAddress, TxButton } from '@polkadot/ui-app';
import accountObservable from '@polkadot/ui-keyring/observable/accounts';
import { withMulti, withObservable } from '@polkadot/ui-api';
import VotingButtons from './VotingButtons';
import translate from '../translate';
type Props = I18nProps & {
@ -23,11 +22,15 @@ type State = {
accountId?: string
};
const VOTE_NAY = 0;
const VOTE_YAY = -1; // Yes, this is weird, but voting works on i8 with the high bit set
class Voting extends React.PureComponent<Props, State> {
state: State = {};
render () {
const { allAccounts, t } = this.props;
const { allAccounts, referendumId, t } = this.props;
const { accountId } = this.state;
const hasAccounts = allAccounts && Object.keys(allAccounts).length !== 0;
if (!hasAccounts) {
@ -38,33 +41,34 @@ class Voting extends React.PureComponent<Props, State> {
<div className='democracy--Referendum-vote'>
<InputAddress
help={t('Select the account you wish to vote with. You can approve "yay" or deny "nay" the proposal.')}
label={t('vote using my account')}
label={t('using my account')}
onChange={this.onChangeAccount}
placeholder='0x...'
type='account'
withLabel
/>
{this.renderButtons()}
<Button.Group>
<TxButton
accountId={accountId}
isDisabled={!accountId}
isNegative
label={t('Nay')}
params={[referendumId, VOTE_NAY]}
tx='democracy.vote'
/>
<Button.Or />
<TxButton
accountId={accountId}
isDisabled={!accountId}
isPositive
label={t('Aye')}
params={[referendumId, VOTE_YAY]}
tx='democracy.vote'
/>
</Button.Group>
</div>
);
}
private renderButtons () {
const { referendumId } = this.props;
const { accountId } = this.state;
if (!accountId) {
return null;
}
return (
<VotingButtons
accountId={accountId}
referendumId={referendumId}
/>
);
}
private onChangeAccount = (accountId?: string) => {
this.setState({ accountId });
}

View File

@ -1,55 +0,0 @@
// Copyright 2017-2019 @polkadot/app-democracy authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { I18nProps } from '@polkadot/ui-app/types';
import { ApiProps } from '@polkadot/ui-api/types';
import BN from 'bn.js';
import React from 'react';
import { Button, TxButton } from '@polkadot/ui-app';
import { withApi, withMulti } from '@polkadot/ui-api';
import translate from '../translate';
type Props = ApiProps & I18nProps & {
accountId?: string,
referendumId: BN
};
const NAY = 0;
const YAY = -1; // Yes, this is weird, but works on i8 with the high bit set
class VotingButton extends React.PureComponent<Props> {
render () {
const { accountId, referendumId, t } = this.props;
return (
<Button.Group>
<TxButton
accountId={accountId}
isDisabled={!accountId}
isNegative
label={t('Nay')}
params={[referendumId, NAY]}
tx='democracy.vote'
/>
<Button.Or />
<TxButton
accountId={accountId}
isDisabled={!accountId}
isPositive
label={t('Aye')}
params={[referendumId, YAY]}
tx='democracy.vote'
/>
</Button.Group>
);
}
}
export default withMulti(
VotingButton,
translate,
withApi
);