Skip to content

Commit 4f1bb07

Browse files
committed
Merge branch 'dev' into 'main'
Dev See merge request voltaire/govtool-outcomes-pillar!79
2 parents 259a48d + 4e5271a commit 4f1bb07

File tree

7 files changed

+98
-34
lines changed

7 files changed

+98
-34
lines changed

backend/src/governance-actions/governance-actions.service.ts

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable, Logger } from "@nestjs/common";
1+
import { Injectable, Logger, NotFoundException } from "@nestjs/common";
22
import { InjectDataSource } from "@nestjs/typeorm";
33
import { getGovernanceAction } from "src/queries/governanceAction";
44
import { getGovernanceActions } from "src/queries/governanceActions";
@@ -24,29 +24,55 @@ export class GovernanceActionsService {
2424
private readonly httpService: HttpService,
2525
private readonly configService: ConfigService
2626
) {}
27-
findAll(
27+
async findAll(
2828
search: string,
2929
filters: string[],
3030
sort: string,
3131
page: number = 1,
3232
limit: number = 12
3333
) {
34-
const searchTerm = search ? search.trim() : "";
35-
const filterArray = filters?.length > 0 ? filters : null;
36-
const sortOption = sort || "newestFirst";
37-
const offset = (page - 1) * limit;
38-
39-
return this.cexplorerService.manager.query(getGovernanceActions, [
40-
searchTerm,
41-
filterArray,
42-
sortOption,
43-
offset,
44-
limit,
45-
]);
34+
try {
35+
const searchTerm = search ? search.trim() : "";
36+
const filterArray = filters?.length > 0 ? filters : null;
37+
const sortOption = sort || "newestFirst";
38+
const offset = (page - 1) * limit;
39+
40+
const result = await this.cexplorerService.manager.query(
41+
getGovernanceActions,
42+
[searchTerm, filterArray, sortOption, offset, limit]
43+
);
44+
45+
if (!result) {
46+
return [];
47+
}
48+
49+
return result;
50+
} catch (error) {
51+
if (error) {
52+
throw error;
53+
}
54+
}
4655
}
4756

48-
findOne(id: string) {
49-
return this.cexplorerService.manager.query(getGovernanceAction, [id]);
57+
async findOne(id: string) {
58+
try {
59+
const result = await this.cexplorerService.manager.query(
60+
getGovernanceAction,
61+
[id]
62+
);
63+
64+
if (!result || result.length === 0) {
65+
throw new NotFoundException(
66+
`Governance action with ID '${id}' not found`
67+
);
68+
}
69+
70+
return result?.[0];
71+
} catch (error) {
72+
if (error) {
73+
throw error;
74+
}
75+
}
5076
}
5177

5278
async findProposal(hash: string): Promise<any> {

ui/src/Components/Molecules/ActionsEmptyState.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
import { Card, Typography } from "@mui/material";
22
import { useTranslation } from "../../contexts/I18nContext";
33

4-
export const ActionsEmptyState = () => {
4+
type ActionsEmptyStateProps = {
5+
title: string;
6+
description: string;
7+
};
8+
export const ActionsEmptyState = ({
9+
title,
10+
description,
11+
}: ActionsEmptyStateProps) => {
512
const { t } = useTranslation();
613
return (
714
<Card
@@ -18,11 +25,9 @@ export const ActionsEmptyState = () => {
1825
}}
1926
>
2027
<Typography fontSize={22} fontWeight={500}>
21-
{t("outcomesList.noResults.title")}
22-
</Typography>
23-
<Typography fontWeight={400}>
24-
{t("outcomesList.noResults.description")}
28+
{title}
2529
</Typography>
30+
<Typography fontWeight={400}>{description}</Typography>
2631
</Card>
2732
);
2833
};

ui/src/Components/Molecules/GovernanceActionsList.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ const GovernanceActionsList = () => {
5555

5656
{!isGovActionsLoading && !displayedActions.length ? (
5757
<Box sx={{ paddingY: 3 }}>
58-
<ActionsEmptyState />
58+
<ActionsEmptyState
59+
title={t("outcomesList.noResults.title")}
60+
description={t("outcomesList.noResults.description")}
61+
/>
5962
</Box>
6063
) : null}
6164

@@ -90,7 +93,9 @@ const GovernanceActionsList = () => {
9093
{isFetchingNextPage ? (
9194
<CircularProgress size={20} sx={{ mr: 1 }} />
9295
) : null}
93-
{isFetchingNextPage ? t("loaders.loading") : t("outcomesList.showMore")}
96+
{isFetchingNextPage
97+
? t("loaders.loading")
98+
: t("outcomesList.showMore")}
9499
</Button>
95100
</Box>
96101
)}

ui/src/Components/SingleAction/GovernanceVoting.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ type GovernanceVotingProps = {
1515
action: GovernanceAction;
1616
};
1717
const GovernanceVoting = ({ action }: GovernanceVotingProps) => {
18+
if (!action) return null;
19+
1820
const {
1921
yes_votes,
2022
no_votes,
@@ -29,6 +31,7 @@ const GovernanceVoting = ({ action }: GovernanceVotingProps) => {
2931
type,
3032
status,
3133
} = action;
34+
3235
const {
3336
networkMetrics,
3437
epochParams,
@@ -37,7 +40,9 @@ const GovernanceVoting = ({ action }: GovernanceVotingProps) => {
3740
areSPOVoteTotalsDisplayed,
3841
areCCVoteTotalsDisplayed,
3942
} = useNetworkMetrics(action);
43+
4044
const { t } = useTranslation();
45+
4146
const {
4247
palette: {
4348
textBlack,
@@ -100,13 +105,9 @@ const GovernanceVoting = ({ action }: GovernanceVotingProps) => {
100105
Number(networkMetrics?.spos_no_confidence_voting_power) ?? 0;
101106
const totalStakeControlledByDReps =
102107
Number(networkMetrics?.total_stake_controlled_by_active_dreps) ?? 0;
103-
const totalActiveStakeControlledByDReps =
104-
totalStakeControlledByDReps - totalStakeControlledByAlwaysAbstain;
105108
const totalStakeControlledBySPOs = Number(
106109
networkMetrics?.total_stake_controlled_by_stake_pools
107110
);
108-
const totalActiveStakeControlledBySPOs =
109-
totalStakeControlledBySPOs - totalStakeControlledByAlwaysAbstainForSPOs;
110111
const noOfCommitteeMembers =
111112
Number(networkMetrics?.no_of_committee_members) ?? 0;
112113
const ccThreshold = (
@@ -155,17 +156,17 @@ const GovernanceVoting = ({ action }: GovernanceVotingProps) => {
155156
);
156157

157158
// DReps vote percentages
158-
const dRepYesVotesPercentage = totalActiveStakeControlledByDReps
159-
? (dRepYesVotes / totalActiveStakeControlledByDReps) * 100
159+
const dRepYesVotesPercentage = dRepRatificationThresholdStake
160+
? (dRepYesVotes / dRepRatificationThresholdStake) * 100
160161
: undefined;
161162
const dRepNoVotesPercentage =
162163
dRepYesVotesPercentage !== undefined
163164
? Number(100 - dRepYesVotesPercentage)
164165
: undefined;
165166

166167
// SPOs vote percentages
167-
const poolYesVotesPercentage = totalActiveStakeControlledBySPOs
168-
? (poolYesVotes / totalActiveStakeControlledBySPOs) * 100
168+
const poolYesVotesPercentage = poolRatificationThresholdStake
169+
? (poolYesVotes / poolRatificationThresholdStake) * 100
169170
: undefined;
170171
const poolNoVotesPercentage =
171172
poolYesVotesPercentage !== undefined

ui/src/Pages/GovernanceAction.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { Typography } from "../Components/Atoms/Typography";
3535
import ProposalCardLoader from "../Components/Loaders/ProposalCardLoader";
3636
import { useTranslation } from "../contexts/I18nContext";
3737
import GovernanceActionAuthors from "../Components/Molecules/GovernanceActionAuthors";
38+
import { ActionsEmptyState } from "../Components/Molecules/ActionsEmptyState";
3839

3940
type GovernanceActionProps = {
4041
id: string;
@@ -70,7 +71,7 @@ const StyledTab = styled(({ isMobile, ...props }: StyledTabProps) => (
7071

7172
function GovernanceAction({ id }: GovernanceActionProps) {
7273
const { isMobile } = useScreenDimension();
73-
const { governanceAction, isGovernanceActionLoading } =
74+
const { governanceAction, isGovernanceActionLoading, governanceActionError } =
7475
useGetGovernanceActionQuery(id);
7576
const { metadata, metadataValid, isMetadataLoading } =
7677
useMetadata(governanceAction);
@@ -268,6 +269,28 @@ function GovernanceAction({ id }: GovernanceActionProps) {
268269
);
269270
}
270271

272+
if (governanceActionError || !governanceAction) {
273+
return (
274+
<Box display="flex" flex={1} flexDirection="column" width="100%">
275+
<Box
276+
data-testid={`single-action-page-circular-loader`}
277+
sx={{
278+
alignItems: "center",
279+
display: "flex",
280+
flex: 1,
281+
justifyContent: "center",
282+
minHeight: "75vh",
283+
}}
284+
>
285+
<ActionsEmptyState
286+
title={t("outcome.noResults.title")}
287+
description={t("outcome.noResults.description")}
288+
/>
289+
</Box>
290+
</Box>
291+
);
292+
}
293+
271294
const renderAllTabContent = () => {
272295
return tabDefinitions.map((tab) => (
273296
<CustomTabPanel

ui/src/i18n/translations/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@
118118
"details": "Details"
119119
},
120120
"viewDetails": "View Details",
121-
"seeDiscussion": "See discussion"
121+
"seeDiscussion": "See discussion",
122+
"noResults": {
123+
"title": "Governance action not found",
124+
"description": "The governance action you're looking for could not be found. The ID might be incorrect, or there could be a temporary issue loading the data."
125+
}
122126
},
123127
"proposalDiscussion": {
124128
"title": "Discussion forum",

ui/src/services/requests/getGovernanceAction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ export const getGovernanceAction = async (id: string) => {
66
const response = await axiosInstance.get(`/governance-actions/${hash}`, {
77
params: { index },
88
});
9-
return response.data[0];
9+
return response.data;
1010
};

0 commit comments

Comments
 (0)