feat(governance): proposals-sort-order (#3848)

This commit is contained in:
Sam Keen 2023-05-19 14:30:08 +01:00 committed by GitHub
parent 2533e5ec44
commit 9e2474d39a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 71 deletions

View File

@ -27,6 +27,10 @@ import type { ProposalFieldsFragment } from '../proposals/proposals/__generated_
import type { NodesFragmentFragment } from '../staking/home/__generated__/Nodes'; import type { NodesFragmentFragment } from '../staking/home/__generated__/Nodes';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals'; import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals'; import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals';
import {
orderByDate,
orderByUpgradeBlockHeight,
} from '../proposals/components/proposals-list/proposals-list';
const nodesToShow = 6; const nodesToShow = 6;
@ -200,17 +204,17 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
const proposals = useMemo( const proposals = useMemo(
() => () =>
proposalsData proposalsData
? getNotRejectedProposals<ProposalFieldsFragment>( ? getNotRejectedProposals(proposalsData.proposalsConnection)
proposalsData.proposalsConnection
)
: [], : [],
[proposalsData] [proposalsData]
); );
const sortedProposals = useMemo(() => orderByDate(proposals), [proposals]);
const protocolUpgradeProposals = useMemo( const protocolUpgradeProposals = useMemo(
() => () =>
protocolUpgradesData protocolUpgradesData
? getNotRejectedProtocolUpgradeProposals<ProtocolUpgradeProposalFieldsFragment>( ? getNotRejectedProtocolUpgradeProposals(
protocolUpgradesData.protocolUpgradeProposals protocolUpgradesData.protocolUpgradeProposals
).filter( ).filter(
(p) => (p) =>
@ -221,15 +225,20 @@ const GovernanceHome = ({ name }: RouteChildProps) => {
[protocolUpgradesData] [protocolUpgradesData]
); );
const sortedProtocolUpgradeProposals = useMemo(
() => orderByUpgradeBlockHeight(protocolUpgradeProposals),
[protocolUpgradeProposals]
);
const totalProposalsDesired = 4; const totalProposalsDesired = 4;
const protocolUpgradeProposalsToShow = protocolUpgradeProposals.slice( const protocolUpgradeProposalsToShow = sortedProtocolUpgradeProposals.slice(
0, 0,
totalProposalsDesired totalProposalsDesired
); );
const proposalsToShow = const proposalsToShow =
protocolUpgradeProposalsToShow.length === totalProposalsDesired protocolUpgradeProposalsToShow.length === totalProposalsDesired
? [] ? []
: proposals.slice( : sortedProposals.slice(
0, 0,
totalProposalsDesired - protocolUpgradeProposalsToShow.length totalProposalsDesired - protocolUpgradeProposalsToShow.length
); );

View File

@ -132,10 +132,10 @@ describe('Proposals list', () => {
const closedProposalsItems = closedProposals.getAllByTestId( const closedProposalsItems = closedProposals.getAllByTestId(
'proposals-list-item' 'proposals-list-item'
); );
expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal1'); expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal2');
expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal2'); expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal1');
expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal4'); expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal3');
expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal3'); expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal4');
}); });
it('Displays info on no proposals', () => { it('Displays info on no proposals', () => {

View File

@ -1,5 +1,6 @@
import orderBy from 'lodash/orderBy';
import { isFuture } from 'date-fns'; import { isFuture } from 'date-fns';
import { useState } from 'react'; import { useState, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Heading, SubHeading } from '../../../../components/heading'; import { Heading, SubHeading } from '../../../../components/heading';
import { ProposalsListItem } from '../proposals-list-item'; import { ProposalsListItem } from '../proposals-list-item';
@ -30,6 +31,25 @@ interface SortedProtocolUpgradeProposalsProps {
closed: ProtocolUpgradeProposalFieldsFragment[]; closed: ProtocolUpgradeProposalFieldsFragment[];
} }
export const orderByDate = (arr: ProposalFieldsFragment[]) =>
orderBy(
arr,
[
(p) => new Date(p?.terms?.closingDatetime).getTime(),
(p) => new Date(p?.datetime).getTime(),
],
['asc', 'asc']
);
export const orderByUpgradeBlockHeight = (
arr: ProtocolUpgradeProposalFieldsFragment[]
) =>
orderBy(
arr,
[(p) => p?.upgradeBlockHeight, (p) => p.vegaReleaseTag],
['desc', 'desc']
);
export const ProposalsList = ({ export const ProposalsList = ({
proposals, proposals,
protocolUpgradeProposals, protocolUpgradeProposals,
@ -37,35 +57,57 @@ export const ProposalsList = ({
}: ProposalsListProps) => { }: ProposalsListProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [filterString, setFilterString] = useState(''); const [filterString, setFilterString] = useState('');
const sortedProposals = proposals.reduce(
(acc: SortedProposalsProps, proposal) => {
if (isFuture(new Date(proposal?.terms.closingDatetime))) {
acc.open.push(proposal);
} else {
acc.closed.push(proposal);
}
return acc;
},
{
open: [],
closed: [],
}
);
const sortedProtocolUpgradeProposals = protocolUpgradeProposals.reduce( const sortedProposals: SortedProposalsProps = useMemo(() => {
(acc: SortedProtocolUpgradeProposalsProps, proposal) => { const initialSorting = proposals.reduce(
if (Number(proposal?.upgradeBlockHeight) > Number(lastBlockHeight)) { (acc: SortedProposalsProps, proposal) => {
acc.open.push(proposal); if (isFuture(new Date(proposal?.terms.closingDatetime))) {
} else { acc.open.push(proposal);
acc.closed.push(proposal); } else {
acc.closed.push(proposal);
}
return acc;
},
{
open: [],
closed: [],
} }
return acc; );
}, return {
{ open:
open: [], initialSorting.open.length > 0
closed: [], ? orderByDate(initialSorting.open as ProposalFieldsFragment[])
} : [],
); closed:
initialSorting.closed.length > 0
? orderByDate(
initialSorting.closed as ProposalFieldsFragment[]
).reverse()
: [],
};
}, [proposals]);
const sortedProtocolUpgradeProposals: SortedProtocolUpgradeProposalsProps =
useMemo(() => {
const initialSorting = protocolUpgradeProposals.reduce(
(acc: SortedProtocolUpgradeProposalsProps, proposal) => {
if (Number(proposal?.upgradeBlockHeight) > Number(lastBlockHeight)) {
acc.open.push(proposal);
} else {
acc.closed.push(proposal);
}
return acc;
},
{
open: [],
closed: [],
}
);
return {
open: orderByUpgradeBlockHeight(initialSorting.open),
closed: orderByUpgradeBlockHeight(initialSorting.closed).reverse(),
};
}, [protocolUpgradeProposals, lastBlockHeight]);
const filterPredicate = ( const filterPredicate = (
p: ProposalFieldsFragment | ProposalQuery['proposal'] p: ProposalFieldsFragment | ProposalQuery['proposal']

View File

@ -11,9 +11,8 @@ import { ENV } from '../../../config';
export const ProposalContainer = () => { export const ProposalContainer = () => {
const params = useParams<{ proposalId: string }>(); const params = useParams<{ proposalId: string }>();
const { const {
state: { loading: restLoading, error: restError, data: restData }, state: { data: restData },
} = useFetch(`${ENV.rest}governance?proposalId=${params.proposalId}`); } = useFetch(`${ENV.rest}governance?proposalId=${params.proposalId}`);
console.log(restLoading, restError, restData);
const { data, loading, error, refetch } = useProposalQuery({ const { data, loading, error, refetch } = useProposalQuery({
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
errorPolicy: 'ignore', errorPolicy: 'ignore',

View File

@ -1,3 +1,4 @@
import flow from 'lodash/flow';
import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit'; import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -6,36 +7,15 @@ import { SplashLoader } from '../../../components/splash-loader';
import { ProposalsList } from '../components/proposals-list'; import { ProposalsList } from '../components/proposals-list';
import { useProposalsQuery } from './__generated__/Proposals'; import { useProposalsQuery } from './__generated__/Proposals';
import { getNodes } from '@vegaprotocol/utils'; import { getNodes } from '@vegaprotocol/utils';
import flow from 'lodash/flow';
import { import {
ProposalState, ProposalState,
ProtocolUpgradeProposalStatus, ProtocolUpgradeProposalStatus,
} from '@vegaprotocol/types'; } from '@vegaprotocol/types';
import type { NodeConnection, NodeEdge } from '@vegaprotocol/utils'; import type { NodeConnection, NodeEdge } from '@vegaprotocol/utils';
import type { ProposalFieldsFragment } from './__generated__/Proposals'; import type { ProposalFieldsFragment } from './__generated__/Proposals';
import orderBy from 'lodash/orderBy';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals'; import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals'; import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals';
const orderByDate = (arr: ProposalFieldsFragment[]) =>
orderBy(
arr,
[
(p) => new Date(p?.terms?.closingDatetime).getTime(),
(p) => new Date(p?.datetime).getTime(),
],
['asc', 'asc']
);
const orderByUpgradeBlockHeight = (
arr: ProtocolUpgradeProposalFieldsFragment[]
) =>
orderBy(
arr,
[(p) => p?.upgradeBlockHeight, (p) => p.vegaReleaseTag],
['desc', 'desc']
);
export function getNotRejectedProposals<T extends ProposalFieldsFragment>( export function getNotRejectedProposals<T extends ProposalFieldsFragment>(
data?: NodeConnection<NodeEdge<T>> | null data?: NodeConnection<NodeEdge<T>> | null
): T[] { ): T[] {
@ -44,7 +24,6 @@ export function getNotRejectedProposals<T extends ProposalFieldsFragment>(
getNodes<ProposalFieldsFragment>(data, (p) => getNodes<ProposalFieldsFragment>(data, (p) =>
p ? p.state !== ProposalState.STATE_REJECTED : false p ? p.state !== ProposalState.STATE_REJECTED : false
), ),
orderByDate,
])(data); ])(data);
} }
@ -59,7 +38,6 @@ export function getNotRejectedProtocolUpgradeProposals<
ProtocolUpgradeProposalStatus.PROTOCOL_UPGRADE_PROPOSAL_STATUS_REJECTED ProtocolUpgradeProposalStatus.PROTOCOL_UPGRADE_PROPOSAL_STATUS_REJECTED
: false : false
), ),
orderByUpgradeBlockHeight,
])(data); ])(data);
} }
@ -82,17 +60,14 @@ export const ProposalsContainer = () => {
}); });
const proposals = useMemo( const proposals = useMemo(
() => () => getNotRejectedProposals(data?.proposalsConnection),
getNotRejectedProposals<ProposalFieldsFragment>(
data?.proposalsConnection
),
[data] [data]
); );
const protocolUpgradeProposals = useMemo( const protocolUpgradeProposals = useMemo(
() => () =>
protocolUpgradesData protocolUpgradesData
? getNotRejectedProtocolUpgradeProposals<ProtocolUpgradeProposalFieldsFragment>( ? getNotRejectedProtocolUpgradeProposals(
protocolUpgradesData.protocolUpgradeProposals protocolUpgradesData.protocolUpgradeProposals
) )
: [], : [],

View File

@ -16,11 +16,10 @@ const orderByDate = (arr: ProposalFieldsFragment[]) =>
orderBy( orderBy(
arr, arr,
[ [
(p) => new Date(p?.terms?.enactmentDatetime || 0).getTime(), // has to be defaulted to 0 because new Date(null).getTime() -> NaN which is first when ordered. (p) => new Date(p?.terms?.closingDatetime || 0).getTime(), // has to be defaulted to 0 because new Date(null).getTime() -> NaN which is first when ordered
(p) => new Date(p?.terms?.closingDatetime).getTime(),
(p) => p.id, (p) => p.id,
], ],
['desc', 'desc', 'desc'] ['desc', 'desc']
); );
export function getRejectedProposals<T extends ProposalFieldsFragment>( export function getRejectedProposals<T extends ProposalFieldsFragment>(