Swap referendum pass/fail to Tag (#2448)
This commit is contained in:
parent
51852e7834
commit
f309743b2f
@ -7,9 +7,8 @@ import { ActionStatus } from '@polkadot/react-components/Status/types';
|
||||
import { RecoveryConfig } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useCallback, useState, useEffect } from 'react';
|
||||
import { Label } from 'semantic-ui-react';
|
||||
import styled from 'styled-components';
|
||||
import { AddressInfo, AddressSmall, Badge, Button, ChainLock, Forget, Icon, IdentityIcon, InputTags, LinkExternal, Menu, Popup, Input } from '@polkadot/react-components';
|
||||
import { AddressInfo, AddressSmall, Badge, Button, ChainLock, Forget, Icon, IdentityIcon, Input, InputTags, LinkExternal, Menu, Popup, Tag } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
import { Option } from '@polkadot/types';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
@ -309,7 +308,7 @@ function Account ({ address, className, filter, isFavorite, toggleFavorite }: Pr
|
||||
<div className='tags--toggle' onClick={toggleEditTags}>
|
||||
{tags.length
|
||||
? tags.map((tag): React.ReactNode => (
|
||||
<Label key={tag} size='tiny' color='grey'>{tag}</Label>
|
||||
<Tag key={tag} label={tag} />
|
||||
))
|
||||
: <label>{t('no tags')}</label>
|
||||
}
|
||||
|
||||
@ -7,9 +7,8 @@ import { KeyringAddress } from '@polkadot/ui-keyring/types';
|
||||
import { ActionStatus } from '@polkadot/react-components/Status/types';
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Label } from 'semantic-ui-react';
|
||||
import styled from 'styled-components';
|
||||
import { AddressSmall, AddressInfo, Button, ChainLock, Icon, InputTags, Input, LinkExternal, Forget, Menu, Popup } from '@polkadot/react-components';
|
||||
import { AddressSmall, AddressInfo, Button, ChainLock, Icon, InputTags, Input, LinkExternal, Forget, Menu, Popup, Tag } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import keyring from '@polkadot/ui-keyring';
|
||||
import Transfer from '@polkadot/app-accounts/modals/Transfer';
|
||||
@ -222,7 +221,7 @@ function Address ({ address, className, filter, isFavorite, toggleFavorite }: Pr
|
||||
<div className='tags--toggle' onClick={_toggleEditTags}>
|
||||
{tags.length
|
||||
? tags.map((tag): React.ReactNode => (
|
||||
<Label key={tag} size='tiny' color='grey'>{tag}</Label>
|
||||
<Tag key={tag} label={tag} />
|
||||
))
|
||||
: <label>{t('no tags')}</label>
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import { BlockNumber } from '@polkadot/types/interfaces';
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { AddressMini, Badge, Button, Expander, Icon, LinkExternal } from '@polkadot/react-components';
|
||||
import { AddressMini, Button, Expander, LinkExternal, Tag } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { FormatBalance, BlockToTime } from '@polkadot/react-query';
|
||||
import { formatNumber, isBoolean } from '@polkadot/util';
|
||||
@ -84,12 +84,10 @@ function Referendum ({ className, value }: Props): React.ReactElement<Props> | n
|
||||
</td>
|
||||
<td className='padtop top'>
|
||||
{isBoolean(isPassing) && (
|
||||
<Badge
|
||||
<Tag
|
||||
color={isPassing ? 'green' : 'red'}
|
||||
hover={isPassing ? t('{{threshold}}, passing', { replace: { threshold } }) : t('{{threshold}}, not passing', { replace: { threshold } })}
|
||||
info={<Icon name={isPassing ? 'check' : 'cancel'} />}
|
||||
isInline
|
||||
isTooltip
|
||||
type={isPassing ? 'green' : 'brown'}
|
||||
label={isPassing ? t('passing') : t('failing')}
|
||||
/>
|
||||
)}
|
||||
</td>
|
||||
|
||||
@ -46,17 +46,11 @@ function newtonIteration (n: BN, x0: BN): BN {
|
||||
return newtonIteration(n, x1);
|
||||
}
|
||||
|
||||
// https://golb.hplar.ch/2018/09/javascript-bigint.html
|
||||
function sqrt (value: BN): BN {
|
||||
if (value.ltn(0)) {
|
||||
throw new Error('square root of negative numbers is not supported');
|
||||
}
|
||||
|
||||
if (value.ltn(2)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return newtonIteration(value, new BN(1));
|
||||
// TODO Replace with bnSqrt from @polkadot/util once that hits 2.7
|
||||
function bnSqrt (value: BN): BN {
|
||||
return value.ltn(2)
|
||||
? value
|
||||
: newtonIteration(value, new BN(1));
|
||||
}
|
||||
|
||||
export default function useIsPassing (referendum: DerivedReferendum): boolean | undefined {
|
||||
@ -65,26 +59,22 @@ export default function useIsPassing (referendum: DerivedReferendum): boolean |
|
||||
const [isPassing, setIsPassing] = useState<boolean | undefined>(undefined);
|
||||
|
||||
useEffect((): void => {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
const { tally, threshold } = (referendum.status as ReferendumStatus);
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
const { tally, threshold } = (referendum.status as ReferendumStatus);
|
||||
|
||||
if (totalIssuance && tally) {
|
||||
const sqrtVoters = sqrt(tally.turnout);
|
||||
const sqrtElectorate = sqrt(totalIssuance);
|
||||
if (totalIssuance && tally) {
|
||||
const sqrtVoters = bnSqrt(tally.turnout);
|
||||
const sqrtElectorate = bnSqrt(totalIssuance);
|
||||
|
||||
setIsPassing(
|
||||
sqrtVoters.isZero()
|
||||
? false
|
||||
: threshold.isSimplemajority
|
||||
? tally.ayes.gt(tally.nays)
|
||||
: threshold.isSupermajorityapproval
|
||||
? compareRationals(tally.nays, sqrtVoters, tally.ayes, sqrtElectorate)
|
||||
: compareRationals(tally.nays, sqrtElectorate, tally.ayes, sqrtVoters)
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setIsPassing(
|
||||
sqrtVoters.isZero()
|
||||
? false
|
||||
: threshold.isSimplemajority
|
||||
? tally.ayes.gt(tally.nays)
|
||||
: threshold.isSupermajorityapproval
|
||||
? compareRationals(tally.nays, sqrtVoters, tally.ayes, sqrtElectorate)
|
||||
: compareRationals(tally.nays, sqrtElectorate, tally.ayes, sqrtVoters)
|
||||
);
|
||||
}
|
||||
}, [referendum, totalIssuance]);
|
||||
|
||||
|
||||
@ -22,12 +22,12 @@ interface Props {
|
||||
let badgeId = 0;
|
||||
|
||||
function Badge ({ className, hover, info, isGray, isInline, isSmall, isTooltip, onClick, type }: Props): React.ReactElement<Props> | null {
|
||||
const [key] = useState(`${Date.now()}-${badgeId++}`);
|
||||
const [trigger] = useState(`badge-hover-${Date.now()}-${badgeId++}`);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ui--Badge ${isGray && 'isGray'} ${isInline && 'isInline'} ${isTooltip && 'isTooltip'} ${isSmall && 'isSmall'} ${onClick && 'isClickable'} ${type} ${className}`}
|
||||
data-for={`badge-status-${key}`}
|
||||
data-for={trigger}
|
||||
data-tip={true}
|
||||
data-tip-disable={!isTooltip}
|
||||
onClick={onClick}
|
||||
@ -40,7 +40,7 @@ function Badge ({ className, hover, info, isGray, isInline, isSmall, isTooltip,
|
||||
</div>
|
||||
{hover && (
|
||||
<Tooltip
|
||||
trigger={`badge-status-${key}`}
|
||||
trigger={trigger}
|
||||
text={hover}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
import { DeriveAccountInfo } from '@polkadot/api-derive/types';
|
||||
import { KeyringItemType } from '@polkadot/ui-keyring/types';
|
||||
|
||||
import { Label } from 'semantic-ui-react';
|
||||
import React from 'react';
|
||||
|
||||
import Button from './Button';
|
||||
@ -13,6 +12,7 @@ import { classes, toShortAddress } from './util';
|
||||
import CopyButton from './CopyButton';
|
||||
import Input from './Input';
|
||||
import InputTags from './InputTags';
|
||||
import Tag from './Tag';
|
||||
|
||||
export const styles = `
|
||||
text-align: left;
|
||||
@ -354,7 +354,7 @@ export default class Row<P extends RowProps, S extends RowState> extends React.P
|
||||
!tags.length
|
||||
? (isEditable ? <span className='addTags'>add tags</span> : undefined)
|
||||
: tags.map((tag): React.ReactNode => (
|
||||
<Label key={tag} size='tiny' color='grey'>{tag}</Label>
|
||||
<Tag key={tag} label={tag} />
|
||||
))
|
||||
}
|
||||
{isEditable && this.renderEditIcon()}
|
||||
|
||||
42
packages/react-components/src/Tag.tsx
Normal file
42
packages/react-components/src/Tag.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2017-2020 @polkadot/react-components 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, { useState } from 'react';
|
||||
import { Label } from 'semantic-ui-react';
|
||||
|
||||
import Tooltip from './Tooltip';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
color?: 'green' | 'grey' | 'red';
|
||||
hover?: React.ReactNode;
|
||||
label: React.ReactNode;
|
||||
}
|
||||
|
||||
let tagId = 0;
|
||||
|
||||
function Tag ({ className, color, hover, label }: Props): React.ReactElement<Props> {
|
||||
const [trigger] = useState(`tag-hover-${Date.now()}-${tagId++}`);
|
||||
|
||||
return (
|
||||
<Label
|
||||
className={className}
|
||||
color={color || 'grey'}
|
||||
data-for={trigger}
|
||||
data-tip={true}
|
||||
size='small'
|
||||
tag
|
||||
>
|
||||
{label}
|
||||
{hover && (
|
||||
<Tooltip
|
||||
trigger={trigger}
|
||||
text={hover}
|
||||
/>
|
||||
)}
|
||||
</Label>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Tag);
|
||||
@ -77,6 +77,7 @@ export { default as Status, StatusContext } from './Status';
|
||||
export { default as SummaryBox } from './SummaryBox';
|
||||
export { default as Table } from './Table';
|
||||
export { default as Tabs } from './Tabs';
|
||||
export { default as Tag } from './Tag';
|
||||
export { default as Toggle } from './Toggle';
|
||||
export { default as Tooltip } from './Tooltip';
|
||||
export { default as TxButton } from './TxButton';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user