Majority propose shortcut (council) (#2423)

This commit is contained in:
Jaco Greeff 2020-03-20 08:09:17 +01:00 committed by GitHub
parent c25b08e014
commit 042e8a0a16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 103 additions and 4 deletions

View File

@ -0,0 +1,90 @@
// Copyright 2017-2020 @polkadot/ui-staking authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { SubmittableExtrinsic } from '@polkadot/api/types';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Input, InputAddress, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useToggle } from '@polkadot/react-hooks';
import { isHex } from '@polkadot/util';
import { useTranslation } from '../translate';
interface Props {
className?: string;
isMember: boolean;
members: string[];
}
function ProposeExternal ({ className, isMember, members }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [isVisible, toggleVisible] = useToggle();
const [accountId, setAcountId] = useState<string | null>(null);
const [proposal, setProposal] = useState<SubmittableExtrinsic<'promise'> | null>(null);
const [{ isHashValid, hash }, setHash] = useState<{ isHashValid: boolean; hash?: string }>({ isHashValid: false, hash: '' });
const threshold = Math.ceil((members.length || 0) * 0.5);
const _onChangeHash = useCallback(
(hash?: string): void => setHash({ isHashValid: isHex(hash, 256), hash }),
[]
);
useEffect((): void => {
if (isHashValid && hash) {
setProposal(() => api.tx.democracy.externalProposeMajority(hash));
} else {
setProposal(null);
}
}, [hash, isHashValid]);
return (
<>
<Button
icon='add'
isDisabled={!isMember}
label={t('Propose external')}
onClick={toggleVisible}
/>
{isVisible && (
<Modal
className={className}
header={t('Propose external (majority)')}
>
<Modal.Content>
<InputAddress
filter={members}
help={t('Select the account you wish to make the proposal with.')}
label={t('propose from account')}
onChange={setAcountId}
type='account'
withLabel
/>
<Input
autoFocus
help={t('The preimage hash of the proposal')}
label={t('preimage hash')}
onChange={_onChangeHash}
value={hash}
/>
</Modal.Content>
<Modal.Actions onCancel={toggleVisible}>
<TxButton
accountId={accountId}
icon='plus'
isDisabled={!threshold || !members.includes(accountId || '') || !proposal}
isPrimary
label={t('Propose')}
onStart={toggleVisible}
params={[threshold, proposal]}
tx='council.propose'
/>
</Modal.Actions>
</Modal>
)}
</>
);
}
export default React.memo(ProposeExternal);

View File

@ -22,7 +22,7 @@ interface Option {
value: number;
}
export default function Slashing ({ className, isMember, members }: Props): React.ReactElement<Props> {
function Slashing ({ className, isMember, members }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const slashes = useAvailableSlashes();
@ -65,7 +65,7 @@ export default function Slashing ({ className, isMember, members }: Props): Reac
<>
<Button
icon='cancel'
isDisabled={!isMember || !members.length || !slashes.length}
isDisabled={!isMember || !slashes.length}
label={t('Cancel slashes')}
onClick={toggleVisible}
/>
@ -119,3 +119,5 @@ export default function Slashing ({ className, isMember, members }: Props): Reac
</>
);
}
export default React.memo(Slashing);

View File

@ -11,7 +11,8 @@ import { Button, Table } from '@polkadot/react-components';
import { useTranslation } from '../translate';
import useCouncilMembers from '../useCouncilMembers';
import Motion from './Motion';
import Propose from './Propose';
import ProposeMotion from './ProposeMotion';
import ProposeExternal from './ProposeExternal';
import Slashing from './Slashing';
interface Props {
@ -27,12 +28,17 @@ function Proposals ({ className, motions, prime }: Props): React.ReactElement<Pr
return (
<div className={className}>
<Button.Group>
<Propose
<ProposeMotion
filter={members}
isMember={isMember}
members={members}
/>
<Button.Or />
<ProposeExternal
isMember={isMember}
members={members}
/>
<Button.Or />
<Slashing
isMember={isMember}
members={members}

View File

@ -32,6 +32,7 @@ function SetSessionKey ({ controllerId, onClose }: Props): React.ReactElement<Pr
label={t('controller account')}
/>
<Input
autoFocus
className='medium'
help={t('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}