Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"packages/*"
],
"resolutions": {
"@polkadot/api": "^1.0.0-beta.33",
"@polkadot/api-contract": "^1.0.0-beta.33",
"@polkadot/api": "^1.0.0-beta.35",
"@polkadot/api-contract": "^1.0.0-beta.35",
"@polkadot/keyring": "^2.0.0-beta.9",
"@polkadot/types": "^1.0.0-beta.33",
"@polkadot/types": "^1.0.0-beta.35",
"@polkadot/util": "^2.0.0-beta.9",
"@polkadot/util-crypto": "^2.0.0-beta.9",
"babel-core": "^7.0.0-bridge.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/app-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.8.3",
"@polkadot/api-contract": "^1.0.0-beta.33"
"@polkadot/api-contract": "^1.0.0-beta.35"
}
}
71 changes: 5 additions & 66 deletions packages/app-society/src/Overview/Candidate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@

import { DeriveSocietyCandidate } from '@polkadot/api-derive/types';
import { AccountId, SocietyVote } from '@polkadot/types/interfaces';
import { VoteType } from '../types';

import React, { useEffect, useState } from 'react';
import { AddressMini, AddressSmall } from '@polkadot/react-components';
import React from 'react';
import { AddressSmall } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { FormatBalance } from '@polkadot/react-query';
import { Option } from '@polkadot/types';

import { useTranslation } from '../translate';
import CandidateVoting from './CandidateVoting';
import VoteDisplay from './VoteDisplay';

interface Props {
allMembers: string[];
Expand All @@ -21,18 +23,9 @@ interface Props {
value: DeriveSocietyCandidate;
}

type VoteType = [string, SocietyVote];

interface VoteSplit {
allAye: VoteType[];
allNay: VoteType[];
allSkeptic: VoteType[];
}

export default function Candidate ({ allMembers, isMember, ownMembers, value: { accountId, kind, value } }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [{ allAye, allNay, allSkeptic }, setVoteSplit] = useState<VoteSplit>({ allAye: [], allNay: [], allSkeptic: [] });
const votes = useCall<VoteType[]>(api.query.society.votes.multi as any, [allMembers.map((memberId): [AccountId, string] => [accountId, memberId])] as any, {
transform: (voteOpts: Option<SocietyVote>[]): VoteType[] =>
voteOpts
Expand All @@ -41,16 +34,6 @@ export default function Candidate ({ allMembers, isMember, ownMembers, value: {
.map(([accountId, voteOpt]): VoteType => [accountId, voteOpt.unwrap()])
});

useEffect((): void => {
if (votes) {
setVoteSplit({
allAye: votes.filter(([, vote]): boolean => vote.isApprove),
allNay: votes.filter(([, vote]): boolean => vote.isReject),
allSkeptic: votes.filter(([, vote]): boolean => vote.isSkeptic)
});
}
}, [votes]);

return (
<tr>
<td className='top'>
Expand All @@ -66,51 +49,7 @@ export default function Candidate ({ allMembers, isMember, ownMembers, value: {
value={value}
/>
</td>
<td className='top padtop'>
{allSkeptic.length !== 0 && (
<details>
<summary>
{t('Skeptics ({{count}})', { replace: { count: allSkeptic.length } })}
</summary>
{allSkeptic.map(([who]): React.ReactNode =>
<AddressMini
key={who.toString()}
value={who}
/>
)}
</details>
)}
</td>
<td className='top padtop'>
{allAye.length !== 0 && (
<details>
<summary>
{t('Approvals ({{count}})', { replace: { count: allAye.length } })}
</summary>
{allAye.map(([who]): React.ReactNode =>
<AddressMini
key={who.toString()}
value={who}
/>
)}
</details>
)}
</td>
<td className='top padtop'>
{allNay.length !== 0 && (
<details>
<summary>
{t('Rejections ({{count}})', { replace: { count: allNay.length } })}
</summary>
{allNay.map(([who]): React.ReactNode =>
<AddressMini
key={who.toString()}
value={who}
/>
)}
</details>
)}
</td>
<VoteDisplay votes={votes} />
<td className='number together top'>
<CandidateVoting
candidateId={accountId.toString()}
Expand Down
7 changes: 3 additions & 4 deletions packages/app-society/src/Overview/Candidates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
// of the Apache-2.0 license. See the LICENSE file for details.

import { DeriveSocietyCandidate } from '@polkadot/api-derive/types';
import { OwnMembers } from '../types';

import React from 'react';
import { Table } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';

import { useTranslation } from '../translate';
import useMembers from '../useMembers';
import Candidate from './Candidate';

interface Props {
interface Props extends OwnMembers {
className?: string;
}

export default function Candidates ({ className }: Props): React.ReactElement<Props> {
export default function Candidates ({ allMembers, className, isMember, ownMembers }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const candidates = useCall<DeriveSocietyCandidate[]>(api.derive.society.candidates, []);
const { allMembers, isMember, ownMembers } = useMembers();

return (
<div className={`overviewSection ${className}`}>
Expand Down
57 changes: 57 additions & 0 deletions packages/app-society/src/Overview/Defender.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2017-2020 @polkadot/app-society 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 { DeriveSociety, DeriveSocietyMember } from '@polkadot/api-derive/types';
import { SocietyVote } from '@polkadot/types/interfaces';
import { OwnMembers, VoteType } from '../types';

import React from 'react';
import { AddressSmall, Table } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';

import { useTranslation } from '../translate';
import DefenderVoting from './DefenderVoting';
import VoteDisplay from './VoteDisplay';

interface Props extends OwnMembers {
className?: string;
info?: DeriveSociety;
}

export default function Defender ({ className, info, isMember, ownMembers }: Props): React.ReactElement<Props> | null {
const { t } = useTranslation();
const { api } = useApi();
const votes = useCall<VoteType[]>(api.derive.society.members, [], {
transform: (members: DeriveSocietyMember[]): VoteType[] =>
members
.filter(({ vote }): boolean => !!vote)
.map(({ accountId, vote }): VoteType => [accountId.toString(), vote as SocietyVote])
});

if (!info || !info.hasDefender || !info.defender) {
return null;
}

return (
<div className={`overviewSection ${className}`}>
<h1>{t('defender')}</h1>
<Table>
<Table.Body>
<tr>
<td className='top'>
<AddressSmall value={info.defender} />
</td>
<VoteDisplay votes={votes} />
<td className='top together number'>
<DefenderVoting
isMember={isMember}
ownMembers={ownMembers}
/>
</td>
</tr>
</Table.Body>
</Table>
</div>
);
}
66 changes: 66 additions & 0 deletions packages/app-society/src/Overview/DefenderVoting.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2017-2020 @polkadot/app-society 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 React, { useMemo, useState } from 'react';
import { useToggle } from '@polkadot/react-hooks';

import { useTranslation } from '../translate';
import { Button, Dropdown, InputAddress, Modal, TxButton } from '@polkadot/react-components';

interface Props {
isMember: boolean;
ownMembers: string[];
}

export default function DefenderVoting ({ isMember, ownMembers }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [isVisible, toggleVisible] = useToggle();
const [vote, setVote] = useState(true);
const [accountId, setAccountId] = useState<string | null>(null);
const voteOpts = useMemo(() => [
{ text: t('Aye, I approve'), value: true },
{ text: t('Nay, I do not approve'), value: false }
], [t]);

return (
<>
{isVisible && (
<Modal header={t('Vote for defender')}>
<Modal.Content>
<InputAddress
filter={ownMembers}
help={t('The address to vote from (must be a member)')}
label={t('vote from account')}
onChange={setAccountId}
/>
<Dropdown
help={t('Approve or reject this defneder.')}
label={t('vote for defender')}
onChange={setVote}
options={voteOpts}
value={vote}
/>
</Modal.Content>
<Modal.Actions onCancel={toggleVisible}>
<TxButton
accountId={accountId}
icon='check'
label={t('Vote')}
onStart={toggleVisible}
params={[vote]}
tx='society.defenderVote'
/>
</Modal.Actions>
</Modal>
)}
<Button
icon='check'
isDisabled={!isMember}
isPrimary
label={t('Vote')}
onClick={toggleVisible}
/>
</>
);
}
18 changes: 13 additions & 5 deletions packages/app-society/src/Overview/Members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.

import { DeriveSocietyMember } from '@polkadot/api-derive/types';
import { DeriveSociety, DeriveSocietyMember } from '@polkadot/api-derive/types';

import React from 'react';
import React, { useEffect, useState } from 'react';
import { Table } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';

Expand All @@ -13,21 +13,29 @@ import Member from './Member';

interface Props {
className?: string;
info?: DeriveSociety;
}

export default function Members ({ className }: Props): React.ReactElement<Props> {
export default function Members ({ className, info }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const members = useCall<DeriveSocietyMember[]>(api.derive.society.members, []);
const [filtered, setFiltered] = useState<DeriveSocietyMember[]>([]);

useEffect((): void => {
members && setFiltered(
members.filter((member): boolean => !info || !info.hasDefender || !member.accountId.eq(info.defender))
);
}, [info, members]);

return (
<div className={`overviewSection ${className}`}>
<h1>{t('members')}</h1>
{members?.length
{filtered.length
? (
<Table>
<Table.Body>
{members.map((member): React.ReactNode => (
{filtered.map((member): React.ReactNode => (
<Member
key={member.accountId.toString()}
value={member}
Expand Down
4 changes: 2 additions & 2 deletions packages/app-society/src/Overview/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useTranslation } from '../translate';

interface Props {
className?: string;
info?: DeriveSociety;
}

interface NameProps {
Expand All @@ -40,10 +41,9 @@ function Name ({ label, value }: NameProps): React.ReactElement<NameProps> | nul
);
}

function Summary ({ className }: Props): React.ReactElement<Props> {
function Summary ({ className, info }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const info = useCall<DeriveSociety>(api.derive.society.info, []);
const members = useCall<any[]>(api.derive.society.members, []);
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);

Expand Down
Loading