Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,22 @@ changes.

### Removed

## [v2.0.17](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.17) 2025-03-18
## [v2.0.18](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.18) 2025-03-20


### Added

- Add redirection to outcomes when proposal is not found [Issue 3230](https://github.com/IntersectMBO/govtool/issues/3230)

### Fixed

- Fix post-vote navigation to governance action list [Issue 3242](https://github.com/IntersectMBO/govtool/issues/3242)

### Changed

### Removed

## [v2.0.17](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.17) 2025-03-18

### Added

Expand Down
2 changes: 1 addition & 1 deletion govtool/backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.17/x/vva-be/build/vva-be/vva-be /usr/local/bin
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.18/x/vva-be/build/vva-be/vva-be /usr/local/bin
2 changes: 1 addition & 1 deletion govtool/backend/Dockerfile.qovery
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal build
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.17/x/vva-be/build/vva-be/vva-be /usr/local/bin
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.18/x/vva-be/build/vva-be/vva-be /usr/local/bin

# Expose the necessary port
EXPOSE 9876
Expand Down
16 changes: 9 additions & 7 deletions govtool/backend/src/VVA/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -283,18 +283,20 @@ getVotes (unHexText -> dRepId) selectedTypes sortMode mSearch = do
CacheEnv {dRepGetVotesCache} <- asks vvaCache
(votes, proposals) <- cacheRequest dRepGetVotesCache dRepId $ DRep.getVotes dRepId []

let voteMap = Map.fromList $ map (\vote@Types.Vote {..} -> (voteProposalId, vote)) votes

processedProposals <- filter (isProposalSearchedFor mSearch) <$> mapSortAndFilterProposals selectedTypes sortMode proposals

let voteMapByTxHash = Map.fromList $
map (\vote -> (pack $ Prelude.takeWhile (/= '#') (unpack $ Types.voteGovActionId vote), vote)) votes

processedProposals <- filter (isProposalSearchedFor mSearch) <$>
mapSortAndFilterProposals selectedTypes sortMode proposals

return $
[ VoteResponse
{ voteResponseVote = voteToResponse vote
, voteResponseProposal = proposalResponse
}
| proposalResponse@ProposalResponse{proposalResponseId} <- processedProposals
, let proposalIdInt = read (unpack proposalResponseId) :: Int
, Just vote <- [Map.lookup (toInteger proposalIdInt) voteMap]
| proposalResponse <- processedProposals
, let txHash = unHexText (proposalResponseTxHash proposalResponse)
, Just vote <- [Map.lookup txHash voteMapByTxHash]
]

drepInfo :: App m => HexText -> m DRepInfoResponse
Expand Down
6 changes: 2 additions & 4 deletions govtool/backend/src/VVA/DRep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,22 @@ getVotes ::
m ([Vote], [Proposal])
getVotes drepId selectedProposals = withPool $ \conn -> do
results <- liftIO $ SQL.query conn getVotesSql (SQL.Only drepId)

if null results
then return ([], [])
else do
let proposalsToSelect = if null selectedProposals
then [ govActionId | (_, govActionId, _, _, _, _, _, _, _) <- results]
else selectedProposals

allProposals <- mapM (Proposal.getProposals . Just . (:[])) proposalsToSelect

let proposals = concat allProposals

let proposalMap = M.fromList $ map (\x -> (proposalId x, x)) proposals

timeZone <- liftIO getCurrentTimeZone

let votes =
[ Vote proposalId' drepId' vote' url' docHash' epochNo' (localTimeToUTC timeZone date') voteTxHash'
[ Vote proposalId' govActionId' drepId' vote' url' docHash' epochNo' (localTimeToUTC timeZone date') voteTxHash'
| (proposalId', govActionId', drepId', vote', url', docHash', epochNo', date', voteTxHash') <- results
, govActionId' `elem` proposalsToSelect
]
Expand Down
17 changes: 9 additions & 8 deletions govtool/backend/src/VVA/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ instance Exception AppError

data Vote
= Vote
{ voteProposalId :: Integer
, voteDrepId :: Text
, voteVote :: Text
, voteUrl :: Maybe Text
, voteDocHash :: Maybe Text
, voteEpochNo :: Integer
, voteDate :: UTCTime
, voteTxHash :: Text
{ voteProposalId :: Integer
, voteGovActionId :: Text
, voteDrepId :: Text
, voteVote :: Text
, voteUrl :: Maybe Text
, voteDocHash :: Maybe Text
, voteEpochNo :: Integer
, voteDate :: UTCTime
, voteTxHash :: Text
}

data DRepInfo
Expand Down
2 changes: 1 addition & 1 deletion govtool/backend/vva-be.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 3.6
name: vva-be
version: 2.0.17
version: 2.0.18

-- A short (one-line) description of the package.
-- synopsis:
Expand Down
4 changes: 2 additions & 2 deletions govtool/frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion govtool/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@govtool/frontend",
"private": true,
"version": "2.0.17",
"version": "2.0.18",
"type": "module",
"scripts": {
"build": "vite build",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useEffect } from "react";
import {
useNavigate,
useLocation,
useParams,
generatePath,
} from "react-router-dom";
import { Box, CircularProgress, Link, Typography } from "@mui/material";
import { AxiosError } from "axios";

import { ICONS, PATHS } from "@consts";
import { ICONS, OUTCOMES_PATHS, PATHS } from "@consts";
import { useCardano } from "@context";
import {
useGetProposalQuery,
Expand Down Expand Up @@ -42,13 +44,24 @@ export const DashboardGovernanceActionDetails = () => {
const shortenedGovActionId =
txHash && getShortenedGovActionId(txHash, +index);

const { data, isLoading } = useGetProposalQuery(
const { data, isLoading, error } = useGetProposalQuery(
fullProposalId ?? "",
!state?.proposal || !state?.vote,
);
const proposal = (data ?? state)?.proposal;
const vote = (data ?? state)?.vote;

useEffect(() => {
const isProposalNotFound =
(error as AxiosError)?.response?.data ===
`Proposal with id: ${fullProposalId} not found`;
if (isProposalNotFound && fullProposalId) {
navigate(
OUTCOMES_PATHS.governanceActionOutcomes.replace(":id", fullProposalId),
);
}
}, [error]);

return (
<Box
px={isMobile ? 2 : 4}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@consts";
import { useCardano, useDataActionsBar, useFeatureFlag } from "@context";
import {
useGetDRepVotesQuery,
useGetProposalsQuery,
useGetVoterInfo,
useScreenDimension,
Expand Down Expand Up @@ -89,6 +90,31 @@ export const DashboardGovernanceActions = () => {
searchPhrase: debouncedSearchText,
enabled: !isAdjusting,
});
const { data: votes, areDRepVotesLoading } = useGetDRepVotesQuery(
queryFilters,
chosenSorting,
debouncedSearchText,
);

// TODO: Black magic - that filtering should be done on the backend
const filteredProposals = proposals
?.map((proposalCategory) => {
const filteredActions = proposalCategory.actions.filter((action) => {
const hasVote = votes?.some((voteCategory) =>
voteCategory.actions.some(
(voteAction) => voteAction.proposal.txHash === action.txHash,
),
);

return !hasVote;
});

return {
...proposalCategory,
actions: filteredActions,
};
})
.filter((category) => category.actions.length > 0);

const { state } = useLocation();
const [content, setContent] = useState<number>(
Expand Down Expand Up @@ -189,14 +215,14 @@ export const DashboardGovernanceActions = () => {
onDashboard
searchPhrase={debouncedSearchText}
sorting={chosenSorting}
proposals={proposals}
proposals={filteredProposals}
/>
</CustomTabPanel>
<CustomTabPanel value={content} index={1}>
<DashboardGovernanceActionsVotedOn
filters={chosenFilters}
searchPhrase={debouncedSearchText}
sorting={chosenSorting}
votes={votes}
areDRepVotesLoading={areDRepVotesLoading}
/>
</CustomTabPanel>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,34 @@ import { useMemo } from "react";
import { Box, Typography, CircularProgress } from "@mui/material";

import { useCardano } from "@context";
import {
useGetDRepVotesQuery,
useScreenDimension,
useTranslation,
} from "@hooks";
import { useScreenDimension, useTranslation } from "@hooks";
import { GovernanceVotedOnCard } from "@molecules";
import { Slider } from "@organisms";
import { getFullGovActionId, getProposalTypeLabel } from "@utils";
import { VotedProposal } from "@/models";

type DashboardGovernanceActionsVotedOnProps = {
filters: string[];
searchPhrase?: string;
sorting: string;
votes: {
title: string;
actions: VotedProposal[];
}[];
areDRepVotesLoading: boolean;
};

export const DashboardGovernanceActionsVotedOn = ({
filters,
searchPhrase,
sorting,
votes,
areDRepVotesLoading,
}: DashboardGovernanceActionsVotedOnProps) => {
const { data, areDRepVotesLoading } = useGetDRepVotesQuery(
filters,
sorting,
searchPhrase,
);
const { isMobile } = useScreenDimension();
const { pendingTransaction } = useCardano();
const { t } = useTranslation();

// TODO: Filtering here is some kind of craziness. It should be done on the backend.
const filteredData = useMemo(() => {
if (data.length && searchPhrase) {
return data
if (votes.length && searchPhrase) {
return votes
.map((entry) => ({
...entry,
actions: entry.actions.filter((action) =>
Expand All @@ -44,16 +40,16 @@ export const DashboardGovernanceActionsVotedOn = ({
}))
.filter((entry) => entry.actions?.length > 0);
}
return data;
}, [data, searchPhrase, pendingTransaction.vote]);
return votes;
}, [votes, searchPhrase, pendingTransaction.vote]);

return areDRepVotesLoading ? (
<Box py={4} display="flex" justifyContent="center">
<CircularProgress />
</Box>
) : (
<>
{!data.length ? (
{!votes.length ? (
<Typography py={4} fontWeight="300">
{t("govActions.youHaventVotedYet")}
</Typography>
Expand Down
2 changes: 2 additions & 0 deletions govtool/frontend/src/hooks/queries/useGetDRepVotesQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const useGetDRepVotesQuery = (
},
}),
enabled: !!dRepID,
refetchOnWindowFocus: true,
keepPreviousData: true,
});

const groupedByType = data?.reduce((groups, item) => {
Expand Down
3 changes: 2 additions & 1 deletion govtool/frontend/src/hooks/queries/useGetProposalQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getProposal } from "@services";
export const useGetProposalQuery = (proposalId: string, enabled?: boolean) => {
const { dRepID } = useCardano();

const { data, isLoading, refetch, isRefetching } = useQuery(
const { data, isLoading, refetch, isRefetching, error } = useQuery(
[QUERY_KEYS.useGetProposalKey, dRepID, proposalId],
() => getProposal(proposalId, dRepID),
{
Expand All @@ -21,5 +21,6 @@ export const useGetProposalQuery = (proposalId: string, enabled?: boolean) => {
isLoading,
refetch,
isFetching: isRefetching,
error,
};
};
13 changes: 4 additions & 9 deletions govtool/frontend/src/hooks/queries/useGetProposalsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const useGetProposalsQuery = ({
sorting,
enabled,
}: GetProposalsArguments) => {
const { dRepID, pendingTransaction } = useCardano();
const { dRepID } = useCardano();
const { voter } = useGetVoterInfo();

const fetchProposals = async (): Promise<ProposalData[]> => {
Expand All @@ -34,17 +34,12 @@ export const useGetProposalsQuery = ({
};

const { data, isLoading } = useQuery(
[
QUERY_KEYS.useGetProposalsKey,
filters,
searchPhrase,
sorting,
dRepID,
pendingTransaction.vote?.transactionHash,
],
[QUERY_KEYS.useGetProposalsKey, filters, searchPhrase, sorting, dRepID],
fetchProposals,
{
enabled,
refetchOnWindowFocus: true,
keepPreviousData: true,
},
);

Expand Down
3 changes: 2 additions & 1 deletion govtool/frontend/src/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ declare global {

type ActionTypeFromAPI = {
id: string;
txHash: string;
type: string;
details: string;
expiryDate: string;
Expand All @@ -36,7 +37,7 @@ declare global {

type ToVoteDataType = {
title: string;
actions: ActionTypeToDsiplay[];
actions: ProposalData[];
}[];

type NestedKeys<T> = T extends Record<string, unknown>
Expand Down
Loading