Skip to content

Commit

Permalink
feat(#1703): make voting on governance actions dependent on protocol …
Browse files Browse the repository at this point in the history
…version
  • Loading branch information
MSzalowski committed Aug 9, 2024
1 parent 960e7c0 commit 542f381
Show file tree
Hide file tree
Showing 25 changed files with 1,245 additions and 5,721 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ changes.

- Unsancho GovTool [Issue 1637](https://github.com/IntersectMBO/govtool/issues/1637)
- Add network metrics model to frontend service
- Make voting on governance actions enabled based on protocol version [Issue 1703](https://github.com/IntersectMBO/govtool/issues/1703)

### Fixed

Expand All @@ -25,7 +26,7 @@ changes.

### Changed

- Changed stake key registration to use the newer Conway type of certificate
- Changed stake key registration to use the newer Conway type of certificate

## [sancho-v1.0.12](https://github.com/IntersectMBO/govtool/releases/tag/sancho-v1.0.12) 2024-08-01

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Box } from "@mui/material";

import { useScreenDimension } from "@hooks";
import { VoteActionForm, VotesSubmitted } from "@molecules";
import { useFeatureFlag } from "@/context";
import { GovernanceActionType } from "@/types/governanceAction";

type GovernanceActionCardVotesProps = {
setIsVoteSubmitted: Dispatch<SetStateAction<boolean>>;
Expand All @@ -19,6 +21,7 @@ type GovernanceActionCardVotesProps = {
voteEpochNoFromEP?: number;
isDashboard?: boolean;
isInProgress?: boolean;
type: GovernanceActionType;
};

export const GovernanceActionDetailsCardVotes = ({
Expand All @@ -36,7 +39,9 @@ export const GovernanceActionDetailsCardVotes = ({
voteEpochNoFromEP,
isDashboard,
isInProgress,
type,
}: GovernanceActionCardVotesProps) => {
const { isVotingOnGovernanceActionEnabled } = useFeatureFlag();
const { screenWidth } = useScreenDimension();

const isModifiedPadding =
Expand All @@ -50,7 +55,7 @@ export const GovernanceActionDetailsCardVotes = ({
p: `40px ${isModifiedPadding ? "24px" : "80px"}`,
}}
>
{isVoter ? (
{isVoter && isVotingOnGovernanceActionEnabled(type) ? (
<VoteActionForm
setIsVoteSubmitted={setIsVoteSubmitted}
expiryDate={expiryDate}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ export const AutomatedVotingOptions = ({
txHash,
}: AutomatedVotingOptionsProps) => {
const { t } = useTranslation();
// TODO: Get network metrics from useAppContext
const { networkMetrics, fetchNetworkMetrics } = useGetNetworkMetrics();

const [isOpen, setIsOpen] = useState<boolean>(false);

const { networkMetrics } = useGetNetworkMetrics();

const isDelegatedToAbstain =
currentDelegation ===
AutomatedVotingOptionCurrentDelegation.drep_always_abstain;
Expand All @@ -55,6 +55,10 @@ export const AutomatedVotingOptions = ({
const isDelegationToNoConfidenceInProgress =
delegationInProgress === AutomatedVotingOptionDelegationId.no_confidence;

useEffect(() => {
fetchNetworkMetrics();
}, []);

useEffect(() => {
const shouldBeSetOpen =
isDelegatedToAbstain ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dispatch, SetStateAction } from "react";
import { ActionRadio, Spacer, Typography } from "@atoms";
import { GovernanceActionTootlip } from "@consts";
import { GovernanceActionTooltip } from "@consts";
import {
useCreateGovernanceActionForm,
useScreenDimension,
Expand Down Expand Up @@ -49,7 +49,9 @@ export const ChooseGovernanceActionType = ({
value={type}
tooltipTitle={type}
tooltipText={
GovernanceActionTootlip[type as GovernanceActionType]
GovernanceActionTooltip[
type as keyof typeof GovernanceActionTooltip
]
}
/>
{index + 1 < governanceActionTypes.length ? <Spacer y={2} /> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import { GOVERNANCE_ACTION_FIELDS, Placeholders } from "@consts";
import { useCreateGovernanceActionForm, useTranslation } from "@hooks";
import { Field } from "@molecules";
import { URL_REGEX, testIdFromLabel } from "@/utils";
import { GovernanceActionField } from "@/types/governanceAction";
import {
GovernanceActionField,
GovernanceActionType,
} from "@/types/governanceAction";

import { BgCard } from "../BgCard";
import { ControlledField } from "../ControlledField";
Expand Down Expand Up @@ -40,7 +43,13 @@ export const CreateGovernanceActionForm = ({
const isContinueButtonDisabled =
// TODO: Provide better typing for GOVERNANCE_ACTION_FIELDS
// to get rid of explicit type assertion
Object.keys(GOVERNANCE_ACTION_FIELDS[type!]).some(
Object.keys(
GOVERNANCE_ACTION_FIELDS[
type! as
| GovernanceActionType.InfoAction
| GovernanceActionType.TreasuryWithdrawals
],
).some(
(field) => !watch(field as unknown as Parameters<typeof watch>[0]),
) || isError;

Expand All @@ -54,7 +63,13 @@ export const CreateGovernanceActionForm = ({
};

const renderGovernanceActionField = () =>
Object.entries(GOVERNANCE_ACTION_FIELDS[type!]).map(([key, field]) => {
Object.entries(
GOVERNANCE_ACTION_FIELDS[
type! as
| GovernanceActionType.InfoAction
| GovernanceActionType.TreasuryWithdrawals
],
).map(([key, field]) => {
const fieldProps = {
helpfulText: field.tipI18nKey ? t(field.tipI18nKey) : undefined,
key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { getShortenedGovActionId, getProposalTypeLabel } from "@utils";
import { GovernanceActionDetailsCard } from "@organisms";
import { Breadcrumbs } from "@molecules";

// TODO: Refactor: GovernanceActionDetals and DashboardGovernanceActionDetails are almost identical
// and should be unified
export const DashboardGovernanceActionDetails = () => {
const { voter } = useGetVoterInfo();
const { pendingTransaction, isEnableLoading } = useCardano();
Expand All @@ -33,7 +35,13 @@ export const DashboardGovernanceActionDetails = () => {
state ? state.txHash : data?.proposal.txHash ?? "",
state ? state.index : data?.proposal.index ?? "",
);

// TODO: Refactor me
const title = state ? state?.title : data?.proposal?.title;
const label = state
? getProposalTypeLabel(state.type)
: getProposalTypeLabel(data.proposal.type);
const type = state ? state.type : data.proposal.type;

return (
<Box
Expand Down Expand Up @@ -115,14 +123,11 @@ export const DashboardGovernanceActionDetails = () => {
voter?.isRegisteredAsDRep || voter?.isRegisteredAsSoleVoter
}
noVotes={state ? state.noVotes : data.proposal.noVotes}
type={
state
? getProposalTypeLabel(state.type)
: getProposalTypeLabel(data.proposal.type)
}
type={type}
label={label}
title={title}
details={state ? state.details : data.proposal.details}
url={state ? state.url : data.proposal.url}
title={title}
links={state ? state?.references : data.proposal?.references}
abstract={state ? state?.abstract : data.proposal?.abstract}
motivation={state ? state?.motivation : data.proposal?.motivation}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@molecules";
import { GovernanceActionDetailsCardData } from "@organisms";
import { MetadataValidationStatus } from "@models";
import { GovernanceActionType } from "@/types/governanceAction";

type GovernanceActionDetailsCardProps = {
abstainVotes: number;
Expand All @@ -16,7 +17,8 @@ type GovernanceActionDetailsCardProps = {
expiryDate: string;
expiryEpochNo: number;
noVotes: number;
type: string;
type: GovernanceActionType;
label: string;
details?: ActionDetailsType;
url: string;
title?: string;
Expand All @@ -43,9 +45,10 @@ export const GovernanceActionDetailsCard = ({
expiryDate,
expiryEpochNo,
noVotes,
type,
details,
url,
type,
label,
title,
links,
abstract,
Expand Down Expand Up @@ -109,7 +112,7 @@ export const GovernanceActionDetailsCard = ({
motivation={motivation}
rationale={rationale}
title={title}
type={type}
label={label}
url={url}
/>
<GovernanceActionDetailsCardVotes
Expand All @@ -127,6 +130,7 @@ export const GovernanceActionDetailsCard = ({
isDashboard={isDashboard}
isOneColumn={isOneColumn}
isInProgress={isInProgress}
type={type}
/>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type GovernanceActionDetailsCardDataProps = {
motivation?: string;
rationale?: string;
title?: string;
type: string;
label: string;
url: string;
};

Expand All @@ -51,7 +51,7 @@ export const GovernanceActionDetailsCardData = ({
motivation,
rationale,
title,
type,
label,
url,
}: GovernanceActionDetailsCardDataProps) => {
const { t } = useTranslation();
Expand Down Expand Up @@ -89,9 +89,9 @@ export const GovernanceActionDetailsCardData = ({
/>
<GovernanceActionCardElement
label={t("govActions.governanceActionType")}
text={type}
text={label}
textVariant="pill"
dataTestId={`${getProposalTypeNoEmptySpaces(type)}-type`}
dataTestId={`${getProposalTypeNoEmptySpaces(label)}-type`}
/>
<GovernanceActionsDatesBox
createdDate={createdDate}
Expand Down Expand Up @@ -134,12 +134,12 @@ export const GovernanceActionDetailsCardData = ({
/>
{details &&
Object.keys(details).length !== 0 &&
Object.entries(details).map(([label, content]) => (
Object.entries(details).map(([detailLabel, content]) => (
<GovernanceActionCardElement
isCopyButton={label.toLowerCase().includes("address")}
label={label}
isCopyButton={detailLabel.toLowerCase().includes("address")}
label={detailLabel}
text={content}
dataTestId={testIdFromLabel(label)}
dataTestId={testIdFromLabel(detailLabel)}
/>
))}
<GovernanceActionDetailsCardLinks links={links} />
Expand Down
10 changes: 5 additions & 5 deletions govtool/frontend/src/consts/governanceAction/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
SharedGovernanceActionFieldSchema,
} from "@/types/governanceAction";

export const GovernanceActionTootlip = {
Info: I18n.t("govActions.tooltips.info"),
Treasury: I18n.t("govActions.tooltips.treasury"),
export const GovernanceActionTooltip = {
InfoAction: I18n.t("govActions.tooltips.info"),
TreasuryWithdrawals: I18n.t("govActions.tooltips.treasury"),
};

export const CIP_100 =
Expand Down Expand Up @@ -96,8 +96,8 @@ export const sharedGovernanceActionFields: SharedGovernanceActionFieldSchema = {
};

export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = {
[GovernanceActionType.Info]: sharedGovernanceActionFields,
[GovernanceActionType.Treasury]: {
[GovernanceActionType.InfoAction]: sharedGovernanceActionFields,
[GovernanceActionType.TreasuryWithdrawals]: {
...sharedGovernanceActionFields,
receivingAddress: {
component: GovernanceActionField.Input,
Expand Down
5 changes: 3 additions & 2 deletions govtool/frontend/src/consts/queryKeys.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
export const QUERY_KEYS = {
getAdaHolderCurrentDelegationKey: "getAdaHolderCurrentDelegationKey",
getAdaHolderVotingPowerKey: "getAdaHolderVotingPowerKey",
useGetDRepInfoKey: "useGetDRepInfoKey",
useGetDRepListInfiniteKey: "useGetDRepListInfiniteKey",
useGetDRepVotesKey: "useGetDRepVotesKey",
useGetDRepVotingPowerKey: "useGetDRepVotingPowerKey",
useGetEpochParamsKey: "useGetEpochParamsKey",
useGetNetworkMetricsKey: "useGetNetworkMetricsKey",
useGetProposalKey: "useGetProposalKey",
useGetProposalsKey: "useGetProposalsKey",
useGetProposalsInfiniteKey: "useGetProposalsInfiniteKey",
useGetDRepInfoKey: "useGetDRepInfoKey",
useGetProposalsKey: "useGetProposalsKey",
useGetVoteContextFromFile: "useGetVoteContextFromFile",
};

Expand Down
43 changes: 40 additions & 3 deletions govtool/frontend/src/context/appContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,26 @@ import {
useContext,
useEffect,
useMemo,
useState,
} from "react";
import * as Sentry from "@sentry/react";

import { NETWORK_NAMES, CEXPLORER_BASE_URLS } from "@/consts";
import { useGetNetworkMetrics } from "@/hooks";
import { useGetNetworkMetrics, useGetEpochParams } from "@/hooks";
import {
NETWORK_METRICS_KEY,
PROTOCOL_PARAMS_KEY,
setItemToLocalStorage,
} from "@/utils";
import { EpochParams, NetworkMetrics } from "@/models";

type AppContextType = {
isAppInitializing: boolean;
networkName: string;
network: string;
cExplorerBaseUrl: string;
epochParams?: EpochParams;
networkMetrics?: NetworkMetrics;
};

const AppContext = createContext<AppContextType | null>(null);
Expand All @@ -27,11 +37,36 @@ const AppContextProvider = ({ children }: PropsWithChildren) => {
useEffect(() => {
Sentry.setTag("component_name", "AppContextProvider");
}, []);
const { fetchEpochParams, epochParams } = useGetEpochParams();
const { fetchNetworkMetrics, networkMetrics } = useGetNetworkMetrics();

const [isAppInitializing, setIsAppInitializing] = useState(true);

useEffect(() => {
const init = async () => {
try {
const { data: epochParamsData } = await fetchEpochParams();
if (epochParamsData) {
setItemToLocalStorage(PROTOCOL_PARAMS_KEY, epochParamsData);
}

const { networkMetrics } = useGetNetworkMetrics();
const { data: networkMetricsData } = await fetchNetworkMetrics();
if (networkMetricsData) {
setItemToLocalStorage(NETWORK_METRICS_KEY, networkMetricsData);
}

setIsAppInitializing(false);
} catch (error) {
Sentry.captureException(error);
}
};

init();
}, []);

const value = useMemo(
() => ({
isAppInitializing,
networkName:
NETWORK_NAMES[
(networkMetrics?.networkName as keyof typeof NETWORK_NAMES) ||
Expand All @@ -43,8 +78,10 @@ const AppContextProvider = ({ children }: PropsWithChildren) => {
(networkMetrics?.networkName as keyof typeof NETWORK_NAMES) ||
"preview"
],
epochParams,
networkMetrics,
}),
[networkMetrics],
[isAppInitializing],
);

return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
Expand Down
Loading

0 comments on commit 542f381

Please sign in to comment.