From 9e2474d39a626ed43a1ac7a89fbd5c8c78fa5961 Mon Sep 17 00:00:00 2001 From: Sam Keen Date: Fri, 19 May 2023 14:30:08 +0100 Subject: [PATCH] feat(governance): proposals-sort-order (#3848) --- apps/governance/src/routes/home/index.tsx | 21 ++-- .../proposals-list/proposals-list.spec.tsx | 8 +- .../proposals-list/proposals-list.tsx | 98 +++++++++++++------ .../proposals/proposal/proposal-container.tsx | 3 +- .../proposals/proposals-container.tsx | 31 +----- .../rejected/rejected-proposals-container.tsx | 5 +- 6 files changed, 95 insertions(+), 71 deletions(-) diff --git a/apps/governance/src/routes/home/index.tsx b/apps/governance/src/routes/home/index.tsx index b5b2a485c..19fe4621e 100644 --- a/apps/governance/src/routes/home/index.tsx +++ b/apps/governance/src/routes/home/index.tsx @@ -27,6 +27,10 @@ import type { ProposalFieldsFragment } from '../proposals/proposals/__generated_ import type { NodesFragmentFragment } from '../staking/home/__generated__/Nodes'; import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals'; import { useProtocolUpgradeProposalsQuery } from '@vegaprotocol/proposals'; +import { + orderByDate, + orderByUpgradeBlockHeight, +} from '../proposals/components/proposals-list/proposals-list'; const nodesToShow = 6; @@ -200,17 +204,17 @@ const GovernanceHome = ({ name }: RouteChildProps) => { const proposals = useMemo( () => proposalsData - ? getNotRejectedProposals( - proposalsData.proposalsConnection - ) + ? getNotRejectedProposals(proposalsData.proposalsConnection) : [], [proposalsData] ); + const sortedProposals = useMemo(() => orderByDate(proposals), [proposals]); + const protocolUpgradeProposals = useMemo( () => protocolUpgradesData - ? getNotRejectedProtocolUpgradeProposals( + ? getNotRejectedProtocolUpgradeProposals( protocolUpgradesData.protocolUpgradeProposals ).filter( (p) => @@ -221,15 +225,20 @@ const GovernanceHome = ({ name }: RouteChildProps) => { [protocolUpgradesData] ); + const sortedProtocolUpgradeProposals = useMemo( + () => orderByUpgradeBlockHeight(protocolUpgradeProposals), + [protocolUpgradeProposals] + ); + const totalProposalsDesired = 4; - const protocolUpgradeProposalsToShow = protocolUpgradeProposals.slice( + const protocolUpgradeProposalsToShow = sortedProtocolUpgradeProposals.slice( 0, totalProposalsDesired ); const proposalsToShow = protocolUpgradeProposalsToShow.length === totalProposalsDesired ? [] - : proposals.slice( + : sortedProposals.slice( 0, totalProposalsDesired - protocolUpgradeProposalsToShow.length ); diff --git a/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.spec.tsx b/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.spec.tsx index 2016f0633..f11e557ae 100644 --- a/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.spec.tsx +++ b/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.spec.tsx @@ -132,10 +132,10 @@ describe('Proposals list', () => { const closedProposalsItems = closedProposals.getAllByTestId( 'proposals-list-item' ); - expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal1'); - expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal2'); - expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal4'); - expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal3'); + expect(openProposalsItems[0]).toHaveAttribute('id', 'proposal2'); + expect(openProposalsItems[1]).toHaveAttribute('id', 'proposal1'); + expect(closedProposalsItems[0]).toHaveAttribute('id', 'proposal3'); + expect(closedProposalsItems[1]).toHaveAttribute('id', 'proposal4'); }); it('Displays info on no proposals', () => { diff --git a/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.tsx b/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.tsx index db1490391..59d821261 100644 --- a/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.tsx +++ b/apps/governance/src/routes/proposals/components/proposals-list/proposals-list.tsx @@ -1,5 +1,6 @@ +import orderBy from 'lodash/orderBy'; import { isFuture } from 'date-fns'; -import { useState } from 'react'; +import { useState, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { Heading, SubHeading } from '../../../../components/heading'; import { ProposalsListItem } from '../proposals-list-item'; @@ -30,6 +31,25 @@ interface SortedProtocolUpgradeProposalsProps { 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 = ({ proposals, protocolUpgradeProposals, @@ -37,35 +57,57 @@ export const ProposalsList = ({ }: ProposalsListProps) => { const { t } = useTranslation(); 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( - (acc: SortedProtocolUpgradeProposalsProps, proposal) => { - if (Number(proposal?.upgradeBlockHeight) > Number(lastBlockHeight)) { - acc.open.push(proposal); - } else { - acc.closed.push(proposal); + const sortedProposals: SortedProposalsProps = useMemo(() => { + const initialSorting = 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: [], } - return acc; - }, - { - open: [], - closed: [], - } - ); + ); + return { + open: + initialSorting.open.length > 0 + ? 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 = ( p: ProposalFieldsFragment | ProposalQuery['proposal'] diff --git a/apps/governance/src/routes/proposals/proposal/proposal-container.tsx b/apps/governance/src/routes/proposals/proposal/proposal-container.tsx index f47f3d681..f087eb34c 100644 --- a/apps/governance/src/routes/proposals/proposal/proposal-container.tsx +++ b/apps/governance/src/routes/proposals/proposal/proposal-container.tsx @@ -11,9 +11,8 @@ import { ENV } from '../../../config'; export const ProposalContainer = () => { const params = useParams<{ proposalId: string }>(); const { - state: { loading: restLoading, error: restError, data: restData }, + state: { data: restData }, } = useFetch(`${ENV.rest}governance?proposalId=${params.proposalId}`); - console.log(restLoading, restError, restData); const { data, loading, error, refetch } = useProposalQuery({ fetchPolicy: 'network-only', errorPolicy: 'ignore', diff --git a/apps/governance/src/routes/proposals/proposals/proposals-container.tsx b/apps/governance/src/routes/proposals/proposals/proposals-container.tsx index 29b289d27..16790f082 100644 --- a/apps/governance/src/routes/proposals/proposals/proposals-container.tsx +++ b/apps/governance/src/routes/proposals/proposals/proposals-container.tsx @@ -1,3 +1,4 @@ +import flow from 'lodash/flow'; import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -6,36 +7,15 @@ import { SplashLoader } from '../../../components/splash-loader'; import { ProposalsList } from '../components/proposals-list'; import { useProposalsQuery } from './__generated__/Proposals'; import { getNodes } from '@vegaprotocol/utils'; -import flow from 'lodash/flow'; import { ProposalState, ProtocolUpgradeProposalStatus, } from '@vegaprotocol/types'; import type { NodeConnection, NodeEdge } from '@vegaprotocol/utils'; import type { ProposalFieldsFragment } from './__generated__/Proposals'; -import orderBy from 'lodash/orderBy'; import type { ProtocolUpgradeProposalFieldsFragment } 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( data?: NodeConnection> | null ): T[] { @@ -44,7 +24,6 @@ export function getNotRejectedProposals( getNodes(data, (p) => p ? p.state !== ProposalState.STATE_REJECTED : false ), - orderByDate, ])(data); } @@ -59,7 +38,6 @@ export function getNotRejectedProtocolUpgradeProposals< ProtocolUpgradeProposalStatus.PROTOCOL_UPGRADE_PROPOSAL_STATUS_REJECTED : false ), - orderByUpgradeBlockHeight, ])(data); } @@ -82,17 +60,14 @@ export const ProposalsContainer = () => { }); const proposals = useMemo( - () => - getNotRejectedProposals( - data?.proposalsConnection - ), + () => getNotRejectedProposals(data?.proposalsConnection), [data] ); const protocolUpgradeProposals = useMemo( () => protocolUpgradesData - ? getNotRejectedProtocolUpgradeProposals( + ? getNotRejectedProtocolUpgradeProposals( protocolUpgradesData.protocolUpgradeProposals ) : [], diff --git a/apps/governance/src/routes/proposals/rejected/rejected-proposals-container.tsx b/apps/governance/src/routes/proposals/rejected/rejected-proposals-container.tsx index b65e239b9..bf20b4ee7 100644 --- a/apps/governance/src/routes/proposals/rejected/rejected-proposals-container.tsx +++ b/apps/governance/src/routes/proposals/rejected/rejected-proposals-container.tsx @@ -16,11 +16,10 @@ const orderByDate = (arr: ProposalFieldsFragment[]) => orderBy( 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).getTime(), + (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) => p.id, ], - ['desc', 'desc', 'desc'] + ['desc', 'desc'] ); export function getRejectedProposals(