diff --git a/packages/apps/public/locales/en/app-bounties.json b/packages/apps/public/locales/en/app-bounties.json
index 04070171b2..f32febc7ed 100644
--- a/packages/apps/public/locales/en/app-bounties.json
+++ b/packages/apps/public/locales/en/app-bounties.json
@@ -101,6 +101,7 @@
"Title too long": "Title too long",
"Unassign curator": "Unassign curator",
"Unassign curator under voting": "Unassign curator under voting",
+ "Update overdue": "Update overdue",
"Voting": "Voting",
"Voting results": "Voting results",
"Waiting for Bounty Funding": "Waiting for Bounty Funding",
diff --git a/packages/page-bounties/src/Bounties.spec.ts b/packages/page-bounties/src/Bounties.spec.ts
index c6a064793d..46135d4841 100644
--- a/packages/page-bounties/src/Bounties.spec.ts
+++ b/packages/page-bounties/src/Bounties.spec.ts
@@ -21,7 +21,7 @@ import { keyring } from '@polkadot/ui-keyring';
import { defaultBountyUpdatePeriod, mockBountyHooks } from '../test/hooks/defaults';
import { BountiesPage } from '../test/pages/bountiesPage';
-import { BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING } from './BountyInfos';
+import { BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING } from './BountyNextActionInfo/BountyActionMessage';
jest.mock('@polkadot/react-hooks/useTreasury', () => ({
useTreasury: () => mockHooks.treasury
@@ -100,7 +100,7 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty, proposals);
- await bountiesPage.expectText('Curator proposal under voting');
+ await bountiesPage.expectVotingDescription('Curator proposal under voting');
});
it('when voting on bounty approval', async () => {
@@ -109,7 +109,7 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty, proposals);
- await bountiesPage.expectText('Bounty approval under voting');
+ await bountiesPage.expectVotingDescription('Bounty approval under voting');
});
it('when simultaneous close and approve motions exist, show approved', async () => {
@@ -121,7 +121,7 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty, proposals);
- await bountiesPage.expectText('Bounty approval under voting');
+ await bountiesPage.expectVotingDescription('Bounty approval under voting');
});
it('when voting on close bounty', async () => {
@@ -130,7 +130,7 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty, proposals);
- await bountiesPage.expectText('Bounty rejection under voting');
+ await bountiesPage.expectVotingDescription('Bounty rejection under voting');
});
it('when voting on unassign curator', async () => {
@@ -139,7 +139,7 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty, proposals);
- await bountiesPage.expectText('Curator slash under voting');
+ await bountiesPage.expectVotingDescription('Curator slash under voting');
});
it('when a motion exists that would fail on execution, show nothing', async () => {
@@ -148,14 +148,7 @@ describe('Bounties', () => {
const { findByTestId } = bountiesPage.renderOne(bounty, proposals);
- await expect(findByTestId('extendedVotingStatus')).rejects.toThrow();
- });
-
- it('when bounty is claimable', async () => {
- const bounty = bountyWith({ status: 'PendingPayout' });
- const { findByTestId } = bountiesPage.renderOne(bounty);
-
- expect((await findByTestId('extendedActionStatus')).textContent).toEqual('Claimable');
+ await expect(findByTestId('voting-description')).rejects.toThrow();
});
});
@@ -215,7 +208,7 @@ describe('Bounties', () => {
const { findByTestId } = bountiesPage.renderOne(bounty, proposals);
- expect((await findByTestId('voting-summary')).textContent).toEqual('Aye 2/4Nay 0/0Voting results');
+ expect((await findByTestId('voting-summary')).textContent).toEqual('Aye 2/4Nay 0/0Voting');
});
it('is not displayed when not voting', async () => {
@@ -457,16 +450,28 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty);
- await bountiesPage.expectText('Warning');
await bountiesPage.expectText('Close deadline');
});
+ it('warning when update time is overdue', async () => {
+ const bounty = aBounty({ status: bountyStatusWith(
+ {
+ curator: alice,
+ status: 'Active',
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ updateDue: mockBountyHooks.bountyApi.bestNumber!.toNumber()
+ }) });
+
+ bountiesPage.renderOne(bounty);
+
+ await bountiesPage.expectText('Update overdue');
+ });
+
it('info when waiting for bounty funding', async () => {
const bounty = bountyWith({ status: 'Approved' });
bountiesPage.renderOne(bounty);
- await bountiesPage.expectText('Info');
await bountiesPage.expectText('Waiting for Bounty Funding');
});
@@ -475,10 +480,17 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty);
- await bountiesPage.expectText('Info');
await bountiesPage.expectText('Waiting for Curator\'s acceptance');
});
+ it('info when bounty is claimable', async () => {
+ const bounty = bountyWith({ status: 'PendingPayout' });
+
+ bountiesPage.renderOne(bounty);
+
+ await bountiesPage.expectText('Waiting for implementer to claim');
+ });
+
it('no warning or info when requirements are not met', async () => {
const bounty = aBounty({ status: bountyStatusWith({
curator: alice,
@@ -489,11 +501,11 @@ describe('Bounties', () => {
bountiesPage.renderOne(bounty);
await bountiesPage.rendered();
- bountiesPage.expectTextAbsent('Warning');
bountiesPage.expectTextAbsent('Close deadline');
- bountiesPage.expectTextAbsent('Info');
+ bountiesPage.expectTextAbsent('Update overdue');
bountiesPage.expectTextAbsent('Waiting for Bounty Funding');
bountiesPage.expectTextAbsent("Waiting for Curator's acceptance");
+ bountiesPage.expectTextAbsent('Waiting for implementer to claim');
});
});
});
diff --git a/packages/page-bounties/src/Bounty.tsx b/packages/page-bounties/src/Bounty.tsx
index 11eed43361..0385a65bdc 100644
--- a/packages/page-bounties/src/Bounty.tsx
+++ b/packages/page-bounties/src/Bounty.tsx
@@ -13,8 +13,8 @@ import { ThemeProps } from '@polkadot/react-components/types';
import { BlockToTime, FormatBalance } from '@polkadot/react-query';
import { formatNumber } from '@polkadot/util';
+import BountyActionMessage from './BountyNextActionInfo/BountyActionMessage';
import { getProposalToDisplay } from './helpers/extendedStatuses';
-import VotersColumn from './Voting/VotersColumn';
import { BountyActions } from './BountyActions';
import BountyExtraActions from './BountyExtraActions';
import BountyInfos from './BountyInfos';
@@ -23,6 +23,7 @@ import Curator from './Curator';
import { useBountyStatus } from './hooks';
import { bountyBorderColor, bountyLabelColor } from './theme';
import { useTranslation } from './translate';
+import VotersColumn from './VotersColumn';
interface Props {
bestNumber: BlockNumber;
@@ -71,12 +72,7 @@ function Bounty ({ bestNumber, bounty, className = '', description, index, propo
<>
|
-
+
|
|
: ''}
+
-
+ |
@@ -240,7 +240,10 @@ export default React.memo(styled(Bounty)(({ theme }: ThemeProps) => `
display: inline-flex;
}
- & .fast-actions {
+ & td.fast-actions {
+ padding-left: 0.2rem;
+ width: 1%;
+
.fast-actions-row {
display: flex;
align-items: center;
@@ -296,17 +299,24 @@ export default React.memo(styled(Bounty)(({ theme }: ThemeProps) => `
padding: 0 0 1.3rem;
}
+ & .td-info-action-row {
+ padding-right: 0;
+ }
+
.td-row {
display: flex;
justify-content: space-between;
align-items: center;
+
+ & :only-child {
+ margin-left: auto;
+ }
}
.bounty-action-row {
display: flex;
justify-content: flex-end;
align-items: center;
- margin-left: auto;
& > * + * {
margin-left: 0.6rem;
@@ -314,9 +324,8 @@ export default React.memo(styled(Bounty)(({ theme }: ThemeProps) => `
}
.block-to-time {
- margin-top: 0.28rem;
font-size: 0.7rem;
- line-height: 0.85rem;
+ line-height: 1.5rem;
color: ${bountyLabelColor[theme.theme]};
}
diff --git a/packages/page-bounties/src/Voting/ExtendedStatus.tsx b/packages/page-bounties/src/BountyInfos/VotingDescriptionInfo.tsx
similarity index 53%
rename from packages/page-bounties/src/Voting/ExtendedStatus.tsx
rename to packages/page-bounties/src/BountyInfos/VotingDescriptionInfo.tsx
index e4bb1fb9c5..971078a0e8 100644
--- a/packages/page-bounties/src/Voting/ExtendedStatus.tsx
+++ b/packages/page-bounties/src/BountyInfos/VotingDescriptionInfo.tsx
@@ -4,24 +4,22 @@
import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
import type { BountyStatus } from '@polkadot/types/interfaces';
-import BN from 'bn.js';
import React, { useRef } from 'react';
+import styled from 'styled-components';
-import { BN_ZERO } from '@polkadot/util';
+import { LabelHelp } from '@polkadot/react-components';
-import Description from '../Description';
import { proposalNameToDisplay } from '../helpers/extendedStatuses';
import { useTranslation } from '../translate';
interface Props {
- blocksUntilPayout?: BN ;
className?: string;
- proposals?: DeriveCollectiveProposal[];
+ proposal: DeriveCollectiveProposal;
status: BountyStatus;
}
-function ExtendedStatus ({ blocksUntilPayout, className = '', proposals, status }: Props): React.ReactElement {
- const bestProposalName = proposals ? proposalNameToDisplay(proposals, status) : null;
+function VotingDescriptionInfo ({ className, proposal, status }: Props): React.ReactElement {
+ const bestProposalName = proposalNameToDisplay(proposal, status);
const { t } = useTranslation();
const votingDescriptions = useRef>({
approveBounty: t('Bounty approval under voting'),
@@ -32,23 +30,17 @@ function ExtendedStatus ({ blocksUntilPayout, className = '', proposals, status
});
return (
- <>
+
{bestProposalName && votingDescriptions.current[bestProposalName] &&
-
+
}
- {blocksUntilPayout?.lt(BN_ZERO) &&
- ('Claimable')}
- />
- }
- >
+
);
}
-export default React.memo(ExtendedStatus);
+export default React.memo(styled(VotingDescriptionInfo)`
+ margin-left: 0.2rem;
+`);
diff --git a/packages/page-bounties/src/Voting/VotingLink.tsx b/packages/page-bounties/src/BountyInfos/VotingLink.tsx
similarity index 65%
rename from packages/page-bounties/src/Voting/VotingLink.tsx
rename to packages/page-bounties/src/BountyInfos/VotingLink.tsx
index bc60d1f7ce..399c5b58d3 100644
--- a/packages/page-bounties/src/Voting/VotingLink.tsx
+++ b/packages/page-bounties/src/BountyInfos/VotingLink.tsx
@@ -4,7 +4,6 @@
import React from 'react';
import styled from 'styled-components';
-import Description from '../Description';
import { useTranslation } from '../translate';
interface Props {
@@ -15,13 +14,15 @@ function VotingLink ({ className }: Props): React.ReactElement {
const { t } = useTranslation();
return (
-
+
+ {t('Voting')}
+
);
}
export default React.memo(styled(VotingLink)`
- margin: 0 1rem 0 0
+ line-height: 0.85rem;
+ font-size: 0.7rem;
+ text-decoration: underline;
`);
diff --git a/packages/page-bounties/src/BountyInfos/VotingSummary.tsx b/packages/page-bounties/src/BountyInfos/VotingSummary.tsx
index 1c13bfd69d..9e1a7a3bf7 100644
--- a/packages/page-bounties/src/BountyInfos/VotingSummary.tsx
+++ b/packages/page-bounties/src/BountyInfos/VotingSummary.tsx
@@ -2,23 +2,26 @@
// SPDX-License-Identifier: Apache-2.0
import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
+import type { BountyStatus } from '@polkadot/types/interfaces';
import React, { useMemo } from 'react';
import styled from 'styled-components';
+import VotingDescriptionInfo from '@polkadot/app-bounties/BountyInfos/VotingDescriptionInfo';
import { ThemeProps } from '@polkadot/react-components/types';
import { useMembers } from '@polkadot/react-hooks';
-import Description from '../Description';
import { bountyLabelColor } from '../theme';
import { useTranslation } from '../translate';
+import VotingLink from './VotingLink';
interface Props {
className?: string;
proposal: DeriveCollectiveProposal;
+ status: BountyStatus;
}
-function VotingSummary ({ className, proposal }: Props): JSX.Element {
+function VotingSummary ({ className, proposal, status }: Props): JSX.Element {
const { members } = useMembers();
const { t } = useTranslation();
const ayes = useMemo(() => proposal?.votes?.ayes?.length, [proposal]);
@@ -33,10 +36,14 @@ function VotingSummary ({ className, proposal }: Props): JSX.Element {
className={className}
data-testid='voting-summary'
>
-
- {t('Aye')} {ayes}/{threshold}
- {t('Nay')} {nays}/{nayThreshold}
- ('Voting results')} />
+ {t('Aye')} {ayes}/{threshold}
+ {t('Nay')} {nays}/{nayThreshold}
+
+
+
)}
@@ -45,11 +52,9 @@ function VotingSummary ({ className, proposal }: Props): JSX.Element {
}
export default React.memo(styled(VotingSummary)(({ theme }: ThemeProps) => `
- margin: 0 1rem 0 0;
-
.voting-summary-text {
font-size: 0.85rem;
- line-height: 0.5rem;
+ line-height: 1.5rem;
color: ${bountyLabelColor[theme.theme]}
span {
@@ -57,4 +62,11 @@ export default React.memo(styled(VotingSummary)(({ theme }: ThemeProps) => `
margin-right: 0.5rem;
}
}
+
+ .link-info {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ line-height: 1.5rem;
+ }
`));
diff --git a/packages/page-bounties/src/BountyInfos/index.tsx b/packages/page-bounties/src/BountyInfos/index.tsx
index 1472b8c135..8f89bbdda9 100644
--- a/packages/page-bounties/src/BountyInfos/index.tsx
+++ b/packages/page-bounties/src/BountyInfos/index.tsx
@@ -4,75 +4,42 @@
import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
import type { AccountId, BountyStatus } from '@polkadot/types/interfaces';
-import BN from 'bn.js';
import React, { useMemo } from 'react';
-import styled from 'styled-components';
import { AddressSmall } from '@polkadot/react-components';
-import { BN_HUNDRED } from '@polkadot/util';
import Description from '../Description';
import { getProposalToDisplay } from '../helpers/extendedStatuses';
-import { useBounties } from '../hooks';
import { useTranslation } from '../translate';
-import VotingLink from '../Voting/VotingLink';
-import BountyInfo from './BountyInfo';
import VotingSummary from './VotingSummary';
interface Props {
beneficiary?: AccountId;
- blocksUntilUpdate?: BN;
- className?: string;
proposals?: DeriveCollectiveProposal[];
status: BountyStatus;
}
-export const BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING = 10;
-const BLOCKS_LEFT_TO_SHOW_WARNING = new BN('10000');
-
-function BountyInfos ({ beneficiary, blocksUntilUpdate, className, proposals, status }: Props): JSX.Element {
+function BountyInfos ({ beneficiary, proposals, status }: Props): JSX.Element {
const { t } = useTranslation();
- const { bountyUpdatePeriod } = useBounties();
-
- const blocksPercentageLeftToShowWarning = bountyUpdatePeriod?.muln(BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING).div(BN_HUNDRED);
- const blocksToShowWarning = blocksPercentageLeftToShowWarning ?? BLOCKS_LEFT_TO_SHOW_WARNING;
const proposalToDisplay = useMemo(() => proposals && getProposalToDisplay(proposals, status), [proposals, status]);
return (
-
- {proposalToDisplay && }
- {proposalToDisplay && }
+ <>
+ {proposalToDisplay &&
+
+ }
{beneficiary && (
)}
- {blocksUntilUpdate?.lt(blocksToShowWarning) && (
- ('Close deadline')}
- type='warning'
- />
- )}
- {status.isApproved && (
- ('Waiting for Bounty Funding')}
- type='info'
- />
- )}
- {status.isCuratorProposed && (
- ("Waiting for Curator's acceptance")}
- type='info'
- />
- )}
-
+ >
);
}
-export default React.memo(styled(BountyInfos)`
- display: flex;
- justify-content: space-between;
- align-items: center;
-`);
+export default React.memo(BountyInfos);
diff --git a/packages/page-bounties/src/BountyNextActionInfo/BountyActionMessage.tsx b/packages/page-bounties/src/BountyNextActionInfo/BountyActionMessage.tsx
new file mode 100644
index 0000000000..575b22a58f
--- /dev/null
+++ b/packages/page-bounties/src/BountyNextActionInfo/BountyActionMessage.tsx
@@ -0,0 +1,71 @@
+// Copyright 2017-2021 @polkadot/app-bounties authors & contributors
+// SPDX-License-Identifier: Apache-2.0
+
+import type { BlockNumber, BountyStatus } from '@polkadot/types/interfaces';
+
+import BN from 'bn.js';
+import React, { useMemo } from 'react';
+
+import { useBountyStatus } from '@polkadot/app-bounties/hooks';
+import { BN_HUNDRED, BN_ZERO } from '@polkadot/util';
+
+import { useBounties } from '../hooks';
+import { useTranslation } from '../translate';
+import BountyInfo from './BountyInfo';
+
+interface Props {
+ bestNumber: BlockNumber;
+ blocksUntilUpdate?: BN;
+ status: BountyStatus;
+}
+
+export const BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING = 10;
+const BLOCKS_LEFT_TO_SHOW_WARNING = new BN('10000');
+
+function BountyActionMessage ({ bestNumber, blocksUntilUpdate, status }: Props): JSX.Element {
+ const { t } = useTranslation();
+ const { unlockAt } = useBountyStatus(status);
+ const { bountyUpdatePeriod } = useBounties();
+
+ const blocksUntilPayout = useMemo(() => unlockAt?.sub(bestNumber), [bestNumber, unlockAt]);
+
+ const blocksPercentageLeftToShowWarning = bountyUpdatePeriod?.muln(BLOCKS_PERCENTAGE_LEFT_TO_SHOW_WARNING).div(BN_HUNDRED);
+ const blocksToShowWarning = blocksPercentageLeftToShowWarning ?? BLOCKS_LEFT_TO_SHOW_WARNING;
+
+ return (
+
+ {blocksUntilUpdate?.lte(BN_ZERO) && (
+ ('Update overdue')}
+ type='warning'
+ />
+ )}
+ {blocksUntilUpdate?.lt(blocksToShowWarning) && blocksUntilUpdate?.gt(BN_ZERO) && (
+ ('Close deadline')}
+ type='warning'
+ />
+ )}
+ {status.isApproved && (
+ ('Waiting for Bounty Funding')}
+ type='info'
+ />
+ )}
+ {status.isCuratorProposed && (
+ ("Waiting for Curator's acceptance")}
+ type='info'
+ />
+ )}
+ {blocksUntilPayout?.lt(BN_ZERO) &&
+ ('Waiting for implementer to claim')}
+ type='info'
+ />
+ }
+
+ );
+}
+
+export default React.memo(BountyActionMessage);
diff --git a/packages/page-bounties/src/BountyInfos/BountyInfo.tsx b/packages/page-bounties/src/BountyNextActionInfo/BountyInfo.tsx
similarity index 77%
rename from packages/page-bounties/src/BountyInfos/BountyInfo.tsx
rename to packages/page-bounties/src/BountyNextActionInfo/BountyInfo.tsx
index 6f5427c4c8..709271a778 100644
--- a/packages/page-bounties/src/BountyInfos/BountyInfo.tsx
+++ b/packages/page-bounties/src/BountyNextActionInfo/BountyInfo.tsx
@@ -8,7 +8,6 @@ import { Icon } from '@polkadot/react-components';
import { ThemeProps } from '@polkadot/react-components/types';
import { bountyColor, bountyLabelColor, bountySvgColor } from '../theme';
-import { useTranslation } from '../translate';
interface Props {
className: '';
@@ -17,13 +16,13 @@ interface Props {
}
function BountyInfo ({ className = '', description, type = 'info' }: Props): React.ReactElement {
- const { t } = useTranslation();
-
return (
-
- { type === 'warning' && } {type === 'info' ? t('Info') : t('Warning')}
-
+ {type === 'warning' && (
+
+
+
+ )}
{description}
@@ -32,13 +31,15 @@ function BountyInfo ({ className = '', description, type = 'info' }: Props): Rea
}
export default React.memo(styled(BountyInfo)(({ theme }: ThemeProps) => `
+ display: flex;
+ align-items: center;
font-weight: 500;
font-size: 0.857rem;
- line-height: 1.714rem;
+ line-height: 1.5rem;
color: ${bountyColor[theme.theme]};
- .title{
- margin-bottom: 0.285rem;
+ .info-icon{
+ margin-right: 0.2rem;
svg {
color: ${bountySvgColor[theme.theme]};
}
@@ -49,5 +50,6 @@ export default React.memo(styled(BountyInfo)(({ theme }: ThemeProps) => `
font-size: 0.714rem;
line-height: 0.864rem;
color: ${bountyLabelColor[theme.theme]};
+ word-wrap: break-word;
}
`));
diff --git a/packages/page-bounties/src/BountyStatusView.tsx b/packages/page-bounties/src/BountyStatusView.tsx
index 603ad9a80d..adb68f624a 100644
--- a/packages/page-bounties/src/BountyStatusView.tsx
+++ b/packages/page-bounties/src/BountyStatusView.tsx
@@ -1,29 +1,21 @@
// Copyright 2017-2021 @polkadot/app-bounties authors & contributors
// SPDX-License-Identifier: Apache-2.0
-import type { DeriveCollectiveProposal } from '@polkadot/api-derive/types';
-import type { BountyStatus } from '@polkadot/types/interfaces';
-
-import BN from 'bn.js';
import React, { useRef } from 'react';
import styled from 'styled-components';
import { LabelHelp } from '@polkadot/react-components';
-import ExtendedStatus from './Voting/ExtendedStatus';
import { insertSpaceBeforeCapitalLetter } from './helpers';
import { useTranslation } from './translate';
import { HelpMessages, StatusName } from './types';
interface Props {
- blocksUntilPayout?: BN
bountyStatus: StatusName;
className?: string;
- proposals?: DeriveCollectiveProposal[];
- status: BountyStatus;
}
-function BountyStatusView ({ blocksUntilPayout, bountyStatus, className = '', proposals, status }: Props): React.ReactElement {
+function BountyStatusView ({ bountyStatus, className = '' }: Props): React.ReactElement {
const { t } = useTranslation();
const statusHelpMessages = useRef({
@@ -36,30 +28,19 @@ function BountyStatusView ({ blocksUntilPayout, bountyStatus, className = '', pr
});
return (
-
-
- {insertSpaceBeforeCapitalLetter(bountyStatus)}
-
-
- {proposals && (
-
-
-
- )}
+
+ {insertSpaceBeforeCapitalLetter(bountyStatus)}
+
);
}
export default React.memo(styled(BountyStatusView)`
- .bountyStatus {
- display: flex;
- align-items: center;
- }
+ display: flex;
+ align-items: center;
`);
diff --git a/packages/page-bounties/src/Voting/VotersColumn.tsx b/packages/page-bounties/src/VotersColumn.tsx
similarity index 93%
rename from packages/page-bounties/src/Voting/VotersColumn.tsx
rename to packages/page-bounties/src/VotersColumn.tsx
index a81ea104c1..4501f4e53a 100644
--- a/packages/page-bounties/src/Voting/VotersColumn.tsx
+++ b/packages/page-bounties/src/VotersColumn.tsx
@@ -10,9 +10,9 @@ import styled from 'styled-components';
import { AddressSmall, Icon } from '@polkadot/react-components';
import { ThemeProps } from '@polkadot/react-components/types';
-import { getProposalToDisplay } from '../helpers/extendedStatuses';
-import { bountyLabelColor } from '../theme';
-import { useTranslation } from '../translate';
+import { getProposalToDisplay } from './helpers/extendedStatuses';
+import { bountyLabelColor } from './theme';
+import { useTranslation } from './translate';
interface Props {
className?: string;
diff --git a/packages/page-bounties/src/helpers/extendedStatuses.ts b/packages/page-bounties/src/helpers/extendedStatuses.ts
index c20cd90c5d..6c8803f3d4 100644
--- a/packages/page-bounties/src/helpers/extendedStatuses.ts
+++ b/packages/page-bounties/src/helpers/extendedStatuses.ts
@@ -29,10 +29,8 @@ function bestValidProposalName (bountyProposals: DeriveCollectiveProposal[], sta
return validMethods(status).find((method) => methods.includes(method));
}
-export function proposalNameToDisplay (bountyProposals: DeriveCollectiveProposal[], status: BountyStatus): string | undefined {
- const bestProposalName = bestValidProposalName(bountyProposals, status);
-
- if (bestProposalName !== 'unassignCurator') { return bestProposalName; }
+export function proposalNameToDisplay (bountyProposal: DeriveCollectiveProposal, status: BountyStatus): string | undefined {
+ if (bountyProposal.proposal.method !== 'unassignCurator') { return bountyProposal.proposal.method; }
return status.isCuratorProposed ? 'unassignCurator' : 'slashCurator';
}
diff --git a/packages/page-bounties/test/pages/bountiesPage.tsx b/packages/page-bounties/test/pages/bountiesPage.tsx
index d6c4bb7377..f3b4df5d0b 100644
--- a/packages/page-bounties/test/pages/bountiesPage.tsx
+++ b/packages/page-bounties/test/pages/bountiesPage.tsx
@@ -114,17 +114,20 @@ export class BountiesPage {
} as QueueProps;
return render(
-
-
-
-
-
-
-
-
-
-
-
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+ >
);
}
@@ -305,4 +308,13 @@ export class BountiesPage {
fireEvent.change(beneficiaryAccountInput, { target: { value: beneficiary } });
fireEvent.keyDown(beneficiaryAccountInput, { code: 'Enter', key: 'Enter' });
}
+
+ async expectVotingDescription (description: string): Promise {
+ this.assertRendered();
+ const votingInfo = await this.findByTestId('voting-description');
+ const icon = await within(votingInfo).findByTestId('question-circle');
+
+ fireEvent.mouseEnter(icon);
+ expect(await this.findByText(description)).toBeVisible();
+ }
}
diff --git a/packages/react-components/src/Icon.tsx b/packages/react-components/src/Icon.tsx
index 849cce2063..48de0da38d 100644
--- a/packages/react-components/src/Icon.tsx
+++ b/packages/react-components/src/Icon.tsx
@@ -24,7 +24,7 @@ library.add(fas);
function Icon ({ className = '', color = 'normal', icon, isSpinning, onClick, size = '1x', tooltip }: Props): React.ReactElement {
const extraProps = tooltip
- ? { 'data-for': tooltip, 'data-tip': true }
+ ? { 'data-for': tooltip, 'data-testid': icon, 'data-tip': true }
: {};
return (
diff --git a/packages/react-components/src/Tooltip.tsx b/packages/react-components/src/Tooltip.tsx
index 98298c66d5..f4603d5352 100644
--- a/packages/react-components/src/Tooltip.tsx
+++ b/packages/react-components/src/Tooltip.tsx
@@ -6,9 +6,11 @@ import ReactDOM from 'react-dom';
import ReactTooltip from 'react-tooltip';
import styled from 'styled-components';
-const rootElement = typeof document === 'undefined'
- ? null // This hack is required for server side rendering
- : document.getElementById('tooltips');
+function rootElement () {
+ return typeof document === 'undefined'
+ ? null // This hack is required for server side rendering
+ : document.getElementById('tooltips');
+}
interface Props {
className?: string;
@@ -33,10 +35,12 @@ function Tooltip ({ className = '', effect = 'solid', offset, place = 'top', tex
);
useEffect((): () => void => {
- rootElement && rootElement.appendChild(tooltipContainer);
+ const root = rootElement();
+
+ root && root.appendChild(tooltipContainer);
return (): void => {
- rootElement && rootElement.removeChild(tooltipContainer);
+ root && root.removeChild(tooltipContainer);
};
}, [tooltipContainer]);
|