diff --git a/.github/scripts/set_commit_status.sh b/.github/scripts/set_commit_status.sh
index 01a822304..73b460812 100644
--- a/.github/scripts/set_commit_status.sh
+++ b/.github/scripts/set_commit_status.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# Ensure required environment variables are set
-if [ -z "$GITHUB_REPOSITORY" ] || [ -z "$GITHUB_SHA" ] || [ -z "$GITHUB_TOKEN" ] || [ -z "$GITHUB_RUN_ID" ]; then
+if [ -z "$GITHUB_REPOSITORY" ] || [ -z "$COMMIT_SHA" ] || [ -z "$GITHUB_TOKEN" ] || [ -z "$GITHUB_RUN_ID" ]; then
echo "Missing required environment variables!"
exit 1
fi
@@ -69,7 +69,7 @@ fi
# Send commit status update to GitHub
curl -X POST -H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
- https://api.github.com/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA} \
+ https://api.github.com/repos/${GITHUB_REPOSITORY}/statuses/${COMMIT_SHA} \
-d "{\"state\": \"${TEST_STATUS}\", \"context\": \"${CONTEXT}\", \"description\": \"${DESCRIPTION}\", \"target_url\": \"${TARGET_URL}\"}"
echo "Commit status updated successfully!"
diff --git a/.github/workflows/test_backend.yml b/.github/workflows/test_backend.yml
index 59488d061..28c7b1599 100644
--- a/.github/workflows/test_backend.yml
+++ b/.github/workflows/test_backend.yml
@@ -46,6 +46,8 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v4
+ with:
+ ref: ${{ env.COMMIT_SHA }}
- name: Set pending commit status
id: set-pending-status
@@ -53,7 +55,7 @@ jobs:
echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
curl -X POST -H "Authorization: Bearer ${{ github.token }}" \
-H "Accept: application/vnd.github+json" \
- https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
+ https://api.github.com/repos/${{ github.repository }}/statuses/${{ env.COMMIT_SHA }} \
-d "{\"state\": \"pending\", \"context\": \"Backend Tests : ${{env.BASE_URL}}\", \"target_url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}"
@@ -184,3 +186,4 @@ env:
BASE_URL: https://${{inputs.deployment || 'govtool.cardanoapi.io/api' }}
REPORT_NAME: govtool-backend
GH_PAGES: ${{vars.GH_PAGES}}
+ COMMIT_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
diff --git a/.github/workflows/test_integration_playwright.yml b/.github/workflows/test_integration_playwright.yml
index b3c1591db..cf5e0ed63 100644
--- a/.github/workflows/test_integration_playwright.yml
+++ b/.github/workflows/test_integration_playwright.yml
@@ -48,13 +48,15 @@ jobs:
working-directory: tests/govtool-frontend/playwright
steps:
- uses: actions/checkout@v4
+ with:
+ ref: ${{ env.COMMIT_SHA }}
- name: Set pending commit status
id: set-pending-status
run: |
echo "timestamp=$(date +%s)" >> $GITHUB_OUTPUT
curl -X POST -H "Authorization: Bearer ${{ github.token }}" \
-H "Accept: application/vnd.github+json" \
- https://api.github.com/repos/${{ github.repository }}/statuses/${{ github.sha }} \
+ https://api.github.com/repos/${{ github.repository }}/statuses/${{ env.COMMIT_SHA }} \
-d "{\"state\": \"pending\", \"context\": \"Playwright Tests : ${{env.HOST_URL}}\", \"target_url\": \"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}\"}"
- uses: actions/setup-node@v4
@@ -223,3 +225,4 @@ env:
HOST_URL: https://${{inputs.deployment || 'govtool.cardanoapi.io' }}
REPORT_NAME: govtool-frontend
GH_PAGES: ${{vars.GH_PAGES}}
+ COMMIT_SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
diff --git a/.github/workflows/update-intersect-package.yml b/.github/workflows/update-intersect-package.yml
index e2fb1d680..f93759b13 100644
--- a/.github/workflows/update-intersect-package.yml
+++ b/.github/workflows/update-intersect-package.yml
@@ -58,6 +58,7 @@ jobs:
token: ${{ secrets.GITHUB_TOKEN }}
branch: "chore/${{ github.event.inputs.package_name }}-${{ github.event.inputs.new_version }}"
title: "Update ${{ github.event.inputs.package_name }} to ${{ github.event.inputs.new_version }}"
+ commit-message: "chore: update ${{ github.event.inputs.package_name }} to ${{ github.event.inputs.new_version }}"
body: |
This PR updates `${{ github.event.inputs.package_name }}` to version `${{ github.event.inputs.new_version }}`.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f802f639f..8be337c51 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ changes.
- Add CC votes percentages, not voted and Ratification threshold
- Add support for submitting all 7 governance action types [Issue 2258](https://github.com/IntersectMBO/govtool/issues/2258)
- Add workflow to automatically update any of the @intersect.mbo package [Issue 2968](https://github.com/IntersectMBO/govtool/issues/2968)
+- Add Propose Governance Action button in governance actions dashboard [Issue 1188](https://github.com/IntersectMBO/govtool/issues/1188)
### Fixed
diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql
index 0a6d92d1e..2c3b87aa5 100644
--- a/govtool/backend/sql/list-dreps.sql
+++ b/govtool/backend/sql/list-dreps.sql
@@ -1,10 +1,7 @@
WITH DRepDistr AS (
- SELECT
- drep_distr.*,
- ROW_NUMBER() OVER (PARTITION BY drep_hash.id ORDER BY drep_distr.epoch_no DESC) AS rn
- FROM
- drep_distr
- JOIN drep_hash ON drep_hash.id = drep_distr.hash_id
+ SELECT DISTINCT ON (drep_distr.hash_id) drep_distr.*
+ FROM drep_distr
+ ORDER BY drep_distr.hash_id, drep_distr.epoch_no DESC
),
DRepActivity AS (
SELECT
@@ -19,11 +16,12 @@ DRepActivity AS (
LIMIT 1
),
LatestVotingProcedure AS (
- SELECT
- vp.*,
- ROW_NUMBER() OVER (PARTITION BY drep_voter ORDER BY tx_id DESC) AS rn
+ SELECT DISTINCT ON (vp.drep_voter)
+ vp.*
FROM
voting_procedure vp
+ ORDER BY
+ vp.drep_voter, vp.tx_id DESC
),
LatestVoteEpoch AS (
SELECT
@@ -33,20 +31,19 @@ LatestVoteEpoch AS (
LatestVotingProcedure lvp
JOIN tx ON tx.id = lvp.tx_id
JOIN block ON block.id = tx.block_id
- WHERE
- lvp.rn = 1
),
RankedDRepRegistration AS (
- SELECT
+ SELECT DISTINCT ON (dr.drep_hash_id)
dr.id,
dr.drep_hash_id,
dr.deposit,
dr.voting_anchor_id,
- ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn,
encode(tx.hash, 'hex') AS tx_hash
- FROM
+ FROM
drep_registration dr
JOIN tx ON tx.id = dr.tx_id
+ ORDER BY
+ dr.drep_hash_id, dr.tx_id DESC
),
FetchError AS (
SELECT
@@ -132,29 +129,31 @@ DRepData AS (
off_chain_vote_drep_data.image_hash
FROM
drep_hash dh
- JOIN RankedDRepRegistration ON RankedDRepRegistration.drep_hash_id = dh.id AND RankedDRepRegistration.rn = 1
+ JOIN RankedDRepRegistration ON RankedDRepRegistration.drep_hash_id = dh.id
JOIN (
- SELECT
+ SELECT DISTINCT ON (dr.drep_hash_id)
dr.id,
dr.drep_hash_id,
- dr.deposit,
- ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn
+ dr.deposit
FROM
drep_registration dr
WHERE
dr.deposit IS NOT NULL
- ) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id AND dr_deposit.rn = 1
+ ORDER BY
+ dr.drep_hash_id, dr.tx_id DESC
+ ) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id
LEFT JOIN (
- SELECT
+ SELECT DISTINCT ON (dr.drep_hash_id)
dr.id,
dr.drep_hash_id,
- dr.deposit,
- ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn
+ dr.deposit
FROM
drep_registration dr
- ) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id AND latestDeposit.rn = 1
+ ORDER BY
+ dr.drep_hash_id, dr.tx_id DESC
+ ) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id
LEFT JOIN LatestExistingVotingAnchor leva ON leva.drep_hash_id = dh.id
- LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id AND DRepDistr.rn = 1
+ LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id
LEFT JOIN FetchError fetch_error ON fetch_error.voting_anchor_id = leva.voting_anchor_id
LEFT JOIN HasNonDeregisterVotingAnchor hndva ON hndva.drep_hash_id = dh.id
LEFT JOIN off_chain_vote_data ocvd ON ocvd.voting_anchor_id = leva.voting_anchor_id
@@ -163,26 +162,28 @@ DRepData AS (
LEFT JOIN tx voting_procedure_transaction ON voting_procedure_transaction.id = voting_procedure.tx_id
LEFT JOIN block voting_procedure_block ON voting_procedure_block.id = voting_procedure_transaction.block_id
LEFT JOIN (
- SELECT
+ SELECT DISTINCT ON (dr.drep_hash_id)
block.epoch_no,
block.time,
- dr.drep_hash_id,
- ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn
+ dr.drep_hash_id
FROM
- drep_registration dr
+ drep_registration dr
JOIN tx ON tx.id = dr.tx_id
JOIN block ON block.id = tx.block_id
WHERE
COALESCE(dr.deposit, 0) >= 0
- ) AS newestRegister ON newestRegister.drep_hash_id = dh.id AND newestRegister.rn = 1
- LEFT JOIN (
- SELECT
+ ORDER BY
+ dr.drep_hash_id, dr.tx_id DESC
+ ) AS newestRegister ON newestRegister.drep_hash_id = dh.id
+ LEFT JOIN (
+ SELECT DISTINCT ON (dr.drep_hash_id)
dr.tx_id,
- dr.drep_hash_id,
- ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id ASC) AS rn
+ dr.drep_hash_id
FROM
drep_registration dr
- ) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id AND dr_first_register.rn = 1
+ ORDER BY
+ dr.drep_hash_id, dr.tx_id ASC
+ ) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id
LEFT JOIN tx AS tx_first_register ON tx_first_register.id = dr_first_register.tx_id
LEFT JOIN block AS block_first_register ON block_first_register.id = tx_first_register.block_id
LEFT JOIN LatestVoteEpoch lve ON lve.drep_id = dh.id
diff --git a/govtool/backend/sql/list-proposals.sql b/govtool/backend/sql/list-proposals.sql
index cedc4e86d..2c0de7f10 100644
--- a/govtool/backend/sql/list-proposals.sql
+++ b/govtool/backend/sql/list-proposals.sql
@@ -85,10 +85,13 @@ EnrichedCurrentMembers AS (
) AS enriched_members
FROM
ProcessedCurrentMembers pcm
- LEFT JOIN
- json_array_elements(pcm.current_members) AS member ON true
- LEFT JOIN
- CommitteeData cm ON cm.hash = encode(decode(member->>'hash', 'hex'), 'hex')
+ LEFT JOIN json_array_elements(pcm.current_members) AS member ON true
+ LEFT JOIN CommitteeData cm
+ ON (CASE
+ WHEN (member->>'hash') ~ '^[0-9a-fA-F]+$'
+ THEN encode(decode(member->>'hash', 'hex'), 'hex')
+ ELSE NULL
+ END) = cm.hash
GROUP BY
pcm.id
),
@@ -199,7 +202,13 @@ SELECT
'tag', pd.tag,
'members', em.enriched_members,
'membersToBeRemoved', mtr.members_to_be_removed,
- 'threshold', pd.threshold::float
+ 'threshold',
+ CASE
+ WHEN (pd.threshold->>'numerator') IS NOT NULL
+ AND (pd.threshold->>'denominator') IS NOT NULL
+ THEN (pd.threshold->>'numerator')::float / (pd.threshold->>'denominator')::float
+ ELSE NULL
+ END
)
FROM
ParsedDescription pd
diff --git a/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx b/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx
index 3bcf8bb90..2efc90aa6 100644
--- a/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx
+++ b/govtool/frontend/src/components/organisms/DashboardGovernanceActions.tsx
@@ -1,12 +1,14 @@
-import { useState, useEffect } from "react";
+import { useState, useEffect, useCallback } from "react";
import { Box, CircularProgress, Tab, Tabs, styled } from "@mui/material";
-import { useLocation } from "react-router-dom";
+import { useLocation, useNavigate } from "react-router-dom";
import {
GOVERNANCE_ACTIONS_FILTERS,
GOVERNANCE_ACTIONS_SORTING,
+ PATHS,
+ PDF_PATHS,
} from "@consts";
-import { useCardano, useDataActionsBar } from "@context";
+import { useCardano, useDataActionsBar, useFeatureFlag } from "@context";
import {
useGetProposalsQuery,
useGetVoterInfo,
@@ -18,6 +20,7 @@ import {
GovernanceActionsToVote,
DashboardGovernanceActionsVotedOn,
} from "@organisms";
+import { Button } from "@atoms";
type TabPanelProps = {
children?: React.ReactNode;
@@ -74,6 +77,8 @@ export const DashboardGovernanceActions = () => {
const { isMobile } = useScreenDimension();
const { t } = useTranslation();
const { isEnableLoading } = useCardano();
+ const { isProposalDiscussionForumEnabled } = useFeatureFlag();
+ const navigate = useNavigate();
const queryFilters =
chosenFilters.length > 0 ? chosenFilters : defaultCategories;
@@ -94,6 +99,14 @@ export const DashboardGovernanceActions = () => {
setContent(newValue);
};
+ const onClickPropose = useCallback(() => {
+ navigate(
+ isProposalDiscussionForumEnabled
+ ? PDF_PATHS.proposalDiscussionPropose
+ : PATHS.createGovernanceAction,
+ );
+ }, [isProposalDiscussionForumEnabled]);
+
useEffect(() => {
window.history.replaceState({}, document.title);
}, []);
@@ -126,36 +139,49 @@ export const DashboardGovernanceActions = () => {
) : (
<>
{(voter?.isRegisteredAsDRep || voter?.isRegisteredAsSoleVoter) && (
-
-
+
-
+
+
+
+
-
+ >
+ {t("govActions.propose")}
+
+
)}
+
{
filtersTitle={t("govActions.filterTitle")}
sortOptions={GOVERNANCE_ACTIONS_SORTING}
/>
-
{!proposals || isProposalsLoading ? (