From 4ecb68d1cb77567f9f676744919c4411c1e190f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Mutisya Date: Sat, 22 Feb 2025 01:19:39 +0300 Subject: [PATCH] prevent duplicates and fix action list filters --- .../governance-actions.controller.ts | 5 +- backend/src/queries/governanceActions.ts | 62 ++++++++++++------- .../Molecules/GovernanceActionsList.tsx | 4 +- ui/src/hooks/useGetGovernanceActionsQuery.ts | 3 +- .../services/requests/getGovernanceActions.ts | 8 +-- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/backend/src/governance-actions/governance-actions.controller.ts b/backend/src/governance-actions/governance-actions.controller.ts index f3e9539..9eddfed 100644 --- a/backend/src/governance-actions/governance-actions.controller.ts +++ b/backend/src/governance-actions/governance-actions.controller.ts @@ -10,14 +10,15 @@ export class GovernanceActionsController { @Get() findAll( @Query("search") search: string, - @Query("filters") filters: string[], + @Query("filters") filters: string, @Query("sort") sort: string, @Query("page") page: number, @Query("limit") limit: number ) { + const filtersArray = filters ? filters.split(",") : []; return this.governanceActionsService.findAll( search, - filters, + filtersArray, sort, page, limit diff --git a/backend/src/queries/governanceActions.ts b/backend/src/queries/governanceActions.ts index fd4e2db..8a93b98 100644 --- a/backend/src/queries/governanceActions.ts +++ b/backend/src/queries/governanceActions.ts @@ -102,15 +102,36 @@ VoteCounts AS ( FROM voting_procedure WHERE invalid IS NULL GROUP BY gov_action_proposal_id +), +RankedProposals AS ( + SELECT + gov_action_proposal.id, + encode(creator_tx.hash, 'hex') AS tx_hash, + gov_action_proposal.index, + gov_action_proposal.type::text, + COALESCE(vc.yes_votes, 0) as yes_votes, + COALESCE(vc.no_votes, 0) as no_votes, + COALESCE(vc.abstain_votes, 0) as abstain_votes, + creator_block.time, + creator_block.epoch_no, + ROW_NUMBER() OVER ( + PARTITION BY gov_action_proposal.id + ORDER BY creator_block.epoch_no DESC, creator_block.time DESC + ) as rn + FROM + gov_action_proposal + LEFT JOIN tx AS creator_tx ON creator_tx.id = gov_action_proposal.tx_id + LEFT JOIN block AS creator_block ON creator_block.id = creator_tx.block_id + LEFT JOIN VoteCounts vc ON vc.gov_action_proposal_id = gov_action_proposal.id ) -SELECT - gov_action_proposal.id, - encode(creator_tx.hash, 'hex') AS tx_hash, - gov_action_proposal.index, - gov_action_proposal.type::text, - COALESCE(vc.yes_votes, 0) as yes_votes, - COALESCE(vc.no_votes, 0) as no_votes, - COALESCE(vc.abstain_votes, 0) as abstain_votes, +SELECT + rp.id, + rp.tx_hash, + rp.index, + rp.type, + rp.yes_votes, + rp.no_votes, + rp.abstain_votes, COALESCE( CASE WHEN gov_action_proposal.type = 'TreasuryWithdrawals' THEN @@ -167,8 +188,8 @@ SELECT latest_epoch.start_time + (gov_action_proposal.expiration - latest_epoch.no)::bigint * INTERVAL '1 day' END AS expiry_date, gov_action_proposal.expiration, - creator_block.time, - creator_block.epoch_no, + rp.time, + rp.epoch_no, voting_anchor.url, encode(voting_anchor.data_hash, 'hex') AS data_hash, jsonb_set( @@ -196,11 +217,10 @@ SELECT 'expired_time', expired_block.block_time ) AS status_times FROM - gov_action_proposal + RankedProposals rp + JOIN gov_action_proposal ON gov_action_proposal.id = rp.id CROSS JOIN LatestEpoch AS latest_epoch CROSS JOIN meta - LEFT JOIN tx AS creator_tx ON creator_tx.id = gov_action_proposal.tx_id - LEFT JOIN block AS creator_block ON creator_block.id = creator_tx.block_id LEFT JOIN voting_anchor ON voting_anchor.id = gov_action_proposal.voting_anchor_id LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = voting_anchor.id LEFT JOIN off_chain_vote_gov_action_data ON off_chain_vote_gov_action_data.off_chain_vote_data_id = off_chain_vote_data.id @@ -210,12 +230,12 @@ FROM LEFT JOIN EpochBlocks enacted_block ON enacted_block.epoch_no = gov_action_proposal.enacted_epoch LEFT JOIN EpochBlocks dropped_block ON dropped_block.epoch_no = gov_action_proposal.dropped_epoch LEFT JOIN EpochBlocks expired_block ON expired_block.epoch_no = gov_action_proposal.expired_epoch - LEFT JOIN VoteCounts vc ON vc.gov_action_proposal_id = gov_action_proposal.id WHERE - (COALESCE($1, '') = '' OR + rp.rn = 1 + AND (COALESCE($1, '') = '' OR off_chain_vote_gov_action_data.title ILIKE '%' || $1 || '%' OR off_chain_vote_gov_action_data.abstract ILIKE '%' || $1 || '%' OR - concat(encode(creator_tx.hash, 'hex'), '#', gov_action_proposal.index) ILIKE '%' || $1 || '%') + concat(rp.tx_hash, '#', rp.index) ILIKE '%' || $1 || '%') AND ( CASE WHEN ARRAY_LENGTH($2::text[], 1) > 0 THEN @@ -292,16 +312,16 @@ AND ( ) ORDER BY CASE WHEN $3 = 'oldestFirst' THEN - creator_block.epoch_no + rp.epoch_no END ASC, CASE WHEN $3 = 'highestYesVotes' THEN - COALESCE(vc.yes_votes, 0) + rp.yes_votes END DESC, CASE WHEN $3 = 'newestFirst' OR $3 IS NULL THEN - creator_block.epoch_no + rp.epoch_no END DESC, - creator_block.time DESC, - gov_action_proposal.id DESC + rp.time DESC, + rp.id DESC OFFSET $4 LIMIT $5`; diff --git a/ui/src/Components/Molecules/GovernanceActionsList.tsx b/ui/src/Components/Molecules/GovernanceActionsList.tsx index 3a1c8bc..b789693 100644 --- a/ui/src/Components/Molecules/GovernanceActionsList.tsx +++ b/ui/src/Components/Molecules/GovernanceActionsList.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "react-router-dom"; import { Button } from "../Atoms/Button"; import GovernanceActionCard from "./GovernanceActionCard"; import { ActionsEmptyState } from "./ActionsEmptyState"; -import { useGetGovernanceActions } from "../../hooks/useGetGovernanceActionsQuery"; +import { useGetGovernanceActionsQuery } from "../../hooks/useGetGovernanceActionsQuery"; const ITEMS_PER_PAGE = 12; @@ -22,7 +22,7 @@ const GovernanceActionsList = () => { fetchNextPage, hasNextPage, isFetchingNextPage, - } = useGetGovernanceActions(search, filters, sort, ITEMS_PER_PAGE); + } = useGetGovernanceActionsQuery(search, filters, sort, ITEMS_PER_PAGE); const displayedActions = govActions?.pages?.flat() || []; diff --git a/ui/src/hooks/useGetGovernanceActionsQuery.ts b/ui/src/hooks/useGetGovernanceActionsQuery.ts index 00be35d..66fa872 100644 --- a/ui/src/hooks/useGetGovernanceActionsQuery.ts +++ b/ui/src/hooks/useGetGovernanceActionsQuery.ts @@ -2,9 +2,8 @@ import { useInfiniteQuery } from "react-query"; import { queryKeys } from "../consts/queryKeys"; import { getGovernanceActions } from "../services/requests/getGovernanceActions"; import { decodeCIP129Identifier, getFullGovActionId } from "../lib/utils"; -import { GovernanceAction } from "../types/api"; -export const useGetGovernanceActions = ( +export const useGetGovernanceActionsQuery = ( search: string, filters: string[], sort: string, diff --git a/ui/src/services/requests/getGovernanceActions.ts b/ui/src/services/requests/getGovernanceActions.ts index 90ab114..209f2bf 100644 --- a/ui/src/services/requests/getGovernanceActions.ts +++ b/ui/src/services/requests/getGovernanceActions.ts @@ -8,12 +8,12 @@ export const getGovernanceActions = async ( limit: number ) => { const response = await axiosInstance.get("/governance-actions", { - params: { - search, - filters, + params: { + search, + filters: filters.join(","), sort, page, - limit + limit, }, }); return response.data;