Skip to content

Commit

Permalink
Merge pull request #2373 from IntersectMBO/feat/1597-rendering-motion…
Browse files Browse the repository at this point in the history
…-of-no-confidence-governance-action

feat: add support for the rest of the Governance Actions
  • Loading branch information
MSzalowski authored Nov 15, 2024
2 parents 628b78a + 44c2d9d commit d113332
Show file tree
Hide file tree
Showing 27 changed files with 918 additions and 179 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ changes.
### Added

- Handle displaying votes based on bootstrap phase, full governance and security groups [Issue 2316](https://github.com/IntersectMBO/govtool/issues/2316)
- Add support for displaying Motion of No Confidence Governance Action [Issue 1597](https://github.com/IntersectMBO/govtool/issues/1597)
- Add support for displaying Update committee/threshold Governance Action [Issue 1598](https://github.com/IntersectMBO/govtool/issues/1598)
- Add support for displaying New Constitution and/or Guardrails Script Governance Action [Issue 1599](https://github.com/IntersectMBO/govtool/issues/1598)

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions govtool/backend/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ startApp vvaConfig = do
settings =
setPort vvaPort
$ setHost vvaHost
$ setTimeout 60 -- 60 seconds timeout
$ setTimeout 120 -- 120 seconds timeout
$ setBeforeMainLoop
( Text.hPutStrLn stderr $
Text.pack
Expand Down Expand Up @@ -117,7 +117,7 @@ startApp vvaConfig = do
, dRepListCache
, networkMetricsCache
}
connectionPool <- createPool (connectPostgreSQL (encodeUtf8 (dbSyncConnectionString $ getter vvaConfig))) close 1 1 60
connectionPool <- createPool (connectPostgreSQL (encodeUtf8 (dbSyncConnectionString $ getter vvaConfig))) close 10 10 120
let appEnv = AppEnv {vvaConfig=vvaConfig, vvaCache=cacheEnv, vvaConnectionPool=connectionPool }
server' <- mkVVAServer appEnv
runSettings settings server'
Expand Down
24 changes: 12 additions & 12 deletions govtool/backend/example-config.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"dbsyncconfig" : {
"host" : "localhost",
"dbname" : "cexplorer",
"user" : "postgres",
"password" : "postgres",
"port" : 5432
},
"port" : 9999,
"host" : "localhost",
"cachedurationseconds": 20,
"sentrydsn": "https://username:password@senty.host/id",
"sentryenv": "dev"
"dbsyncconfig" : {
"host" : "localhost",
"dbname" : "cexplorer",
"user" : "postgres",
"password" : "postgres",
"port" : 5432
},
"port" : 9999,
"host" : "localhost",
"cachedurationseconds": 20,
"sentrydsn": "https://username:password@senty.host/id",
"sentryenv": "dev"
}
99 changes: 98 additions & 1 deletion govtool/backend/sql/list-proposals.sql
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,74 @@ always_abstain_voting_power AS (
LEFT JOIN drep_distr ON drep_hash.id = drep_distr.hash_id
WHERE
drep_hash.view = 'drep_always_abstain' ORDER BY epoch_no DESC LIMIT 1), 0) AS amount
),
committee_data AS (
SELECT DISTINCT ON (ch.raw)
encode(ch.raw, 'hex') AS hash,
cm.expiration_epoch,
ch.has_script
FROM
committee_member cm
JOIN
committee_hash ch ON cm.committee_hash_id = ch.id
ORDER BY ch.raw, cm.expiration_epoch DESC
),
parsed_description AS (
SELECT
gov_action_proposal.id,
description->'tag' AS tag,
description->'contents'->1 AS members_to_be_removed,
description->'contents'->2 AS members,
description->'contents'->3 AS threshold
FROM
gov_action_proposal
WHERE
gov_action_proposal.type = 'NewCommittee'
),
members_to_be_removed AS (
SELECT
id,
json_agg(value->>'keyHash') AS members_to_be_removed
FROM
parsed_description,
json_array_elements(members_to_be_removed::json) AS value
GROUP BY
id
),
processed_current_members AS (
SELECT
pd.id,
json_agg(
json_build_object(
'hash', regexp_replace(kv.key, '^keyHash-', ''),
'newExpirationEpoch', kv.value::int
)
) AS current_members
FROM
parsed_description pd,
jsonb_each_text(pd.members) AS kv(key, value)
GROUP BY
pd.id
),
enriched_current_members AS (
SELECT
pcm.id,
json_agg(
json_build_object(
'hash', cm.hash,
'expirationEpoch', cm.expiration_epoch,
'hasScript', cm.has_script,
'newExpirationEpoch', (member->>'newExpirationEpoch')::int
)
) AS enriched_members
FROM
processed_current_members pcm
LEFT JOIN
json_array_elements(pcm.current_members) AS member ON true
LEFT JOIN
committee_data cm ON cm.hash = encode(decode(member->>'hash', 'hex'), 'hex')
GROUP BY
pcm.id
)
SELECT
gov_action_proposal.id,
Expand All @@ -42,13 +110,42 @@ SELECT
json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)

when gov_action_proposal.type::text = 'InfoAction' then
json_build_object()
json_build_object('data', gov_action_proposal.description)

when gov_action_proposal.type::text = 'HardForkInitiation' then
json_build_object(
'major', (gov_action_proposal.description->'contents'->1->>'major')::int,
'minor', (gov_action_proposal.description->'contents'->1->>'minor')::int
)

when gov_action_proposal.type::text = 'NoConfidence' then
json_build_object('data', gov_action_proposal.description->'contents')

when gov_action_proposal.type::text = 'ParameterChange' then
json_build_object('data', gov_action_proposal.description->'contents')

when gov_action_proposal.type::text = 'NewConstitution' then
json_build_object(
'anchor', gov_action_proposal.description->'contents'->1->'anchor'
)
when gov_action_proposal.type::text = 'NewCommittee' then
(
SELECT
json_build_object(
'tag', pd.tag,
'members', em.enriched_members,
'membersToBeRemoved', mtr.members_to_be_removed,
'threshold', pd.threshold::float
)
FROM
parsed_description pd
JOIN
members_to_be_removed mtr ON pd.id = mtr.id
JOIN
enriched_current_members em ON pd.id = em.id
WHERE
pd.id = gov_action_proposal.id
)
else
null
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import { Box, SxProps } from "@mui/material";

import { Typography } from "@atoms";
import { Share } from "@molecules";
import { MetadataValidationStatus } from "@models";
import { getMetadataDataMissingStatusTranslation } from "@/utils";

type DataMissingHeaderProps = {
isDataMissing: MetadataValidationStatus | null;
shareLink?: string;
title?: string;
titleStyle?: SxProps;
};

export const DataMissingHeader = ({
title,
isDataMissing,
shareLink,
titleStyle,
}: DataMissingHeaderProps) => (
<Box
Expand Down Expand Up @@ -50,6 +47,5 @@ export const DataMissingHeader = ({
title}
</Typography>
</Box>
{shareLink && <Share link={shareLink} />}
</Box>
);
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ export const GovernanceActionCard: FC<ActionTypeProps> = ({ ...props }) => {
const { t } = useTranslation();

const govActionId = getFullGovActionId(txHash, index);
const cip129GovernanceActionId = encodeCIP129Identifier(
txHash,
index.toString(16).padStart(2, "0"),
"gov_action",
);
const cip129GovernanceActionId = encodeCIP129Identifier({
txID: txHash,
index: index.toString(16).padStart(2, "0"),
bech32Prefix: "gov_action",
});

return (
<Box
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Typography } from "@atoms";
import { ICONS } from "@consts";
import { useModal } from "@context";
import { useScreenDimension, useTranslation } from "@hooks";
import { LinkWithIcon } from "@molecules";

export const GovernanceActionDetailsCardLinks = ({
links,
Expand Down Expand Up @@ -42,29 +41,56 @@ export const GovernanceActionDetailsCardLinks = ({
}}
>
{links.map(({ uri, label }) => (
<Box flexDirection="column">
<Box flexDirection={isMobile ? "column" : "row"} display="flex">
{label && (
<Typography
data-testid={`${label}-${uri}-label`}
sx={{ fontWeight: "500" }}
sx={{
fontWeight: 400,
flex: 1,
fontSize: 16,
lineHeight: "24px",
mr: 8,
overflow: "hidden",
width: "auto",
whiteSpace: "nowrap",
}}
>
{label}
</Typography>
)}
<LinkWithIcon
key={uri}
label={uri}
onClick={() => {
openModal({
type: "externalLink",
state: {
externalLink: uri,
},
});
<Typography
sx={{
fontSize: 16,
fontWeight: 400,
maxWidth: "283px",
lineHeight: "24px",
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
color: "primaryBlue",
}}
icon={<img alt="link" src={ICONS.link} />}
cutWithEllipsis
/>
>
{uri}
</Typography>
{label && (
<Box ml={1}>
<img
data-testid="link-button"
alt="link"
src={ICONS.externalLinkIcon}
style={{ cursor: "pointer" }}
onClick={() => {
openModal({
type: "externalLink",
state: {
externalLink: uri,
},
});
}}
/>
</Box>
)}
</Box>
))}
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ReactNode } from "react";
import { Box } from "@mui/material";

import { Typography } from "@atoms";
Expand Down Expand Up @@ -65,7 +66,7 @@ export const GovernanceActionDetailsCardOnChainData = ({
ml: 0.5,
}}
>
{content}
{content as ReactNode}
</Typography>
</Box>
))}
Expand Down
Loading

0 comments on commit d113332

Please sign in to comment.