From 51f0c107564c96e52de8c8379999bdf0a92f0010 Mon Sep 17 00:00:00 2001 From: Daniel Chew Date: Sat, 11 Mar 2023 03:32:47 +0900 Subject: [PATCH] [xc-admin] fix xc-admin-frontend bugs (#681) * allow proposing without connecting wallet * show voted icon on proposals --- .../components/tabs/General.tsx | 19 ++-- .../components/tabs/Proposals.tsx | 89 +++++++++++++++++-- .../images/icons/voted.inline.svg | 23 +++++ 3 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 governance/xc_admin/packages/xc_admin_frontend/images/icons/voted.inline.svg diff --git a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/General.tsx b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/General.tsx index 65f8d2b8..d73f709a 100644 --- a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/General.tsx +++ b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/General.tsx @@ -2,7 +2,6 @@ import { AnchorProvider, Program } from '@coral-xyz/anchor' import { AccountType, getPythProgramKeyForCluster } from '@pythnetwork/client' import { PythOracle, pythOracleProgram } from '@pythnetwork/client/lib/anchor' import { useWallet } from '@solana/wallet-adapter-react' -import { WalletModalButton } from '@solana/wallet-adapter-react-ui' import { Cluster, PublicKey, TransactionInstruction } from '@solana/web3.js' import { useCallback, useContext, useEffect, useState } from 'react' import toast from 'react-hot-toast' @@ -697,18 +696,12 @@ const General = () => {

No proposed changes.

)} {Object.keys(changes).length > 0 ? ( - !connected ? ( -
- -
- ) : ( - - ) + ) : null} ) diff --git a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx index 09b75ac1..21f0c72a 100644 --- a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx +++ b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx @@ -1,4 +1,5 @@ import * as Tooltip from '@radix-ui/react-tooltip' +import { useWallet } from '@solana/wallet-adapter-react' import { AccountMeta, PublicKey } from '@solana/web3.js' import { MultisigAccount, TransactionAccount } from '@sqds/mesh/lib/types' import { useRouter } from 'next/router' @@ -28,6 +29,7 @@ import { usePythContext } from '../../contexts/PythContext' import { StatusFilterContext } from '../../contexts/StatusFilterContext' import { PRICE_FEED_MULTISIG } from '../../hooks/useMultisig' import VerifiedIcon from '../../images/icons/verified.inline.svg' +import VotedIcon from '../../images/icons/voted.inline.svg' import { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter' import ClusterSwitch from '../ClusterSwitch' import CopyPubkey from '../common/CopyPubkey' @@ -56,11 +58,13 @@ const getMappingCluster = (cluster: string) => { const ProposalRow = ({ proposal, verified, + voted, setCurrentProposalPubkey, multisig, }: { proposal: TransactionAccount verified: boolean + voted: boolean setCurrentProposalPubkey: Dispatch> multisig: MultisigAccount | undefined }) => { @@ -100,7 +104,10 @@ const ProposalRow = ({ '...' + proposal.publicKey.toBase58().slice(-6)} {' '} - {verified ? : null} +
+ {verified ? : null} +
+ {voted ? : null}
@@ -167,6 +174,25 @@ const VerifiedIconWithTooltip = () => { ) } +const VotedIconWithTooltip = () => { + return ( +
+ + + + + + + + You have voted on this proposal. + + + + +
+ ) +} + const ParsedAccountPubkeyRow = ({ mapping, title, @@ -187,7 +213,7 @@ const ParsedAccountPubkeyRow = ({ } const getProposalStatus = ( - proposal: TransactionAccount | undefined, + proposal: TransactionAccount | ClientProposal | undefined, multisig: MultisigAccount | undefined ): string => { if (multisig && proposal) { @@ -1054,6 +1080,8 @@ const Proposal = ({ ) } +type ClientProposal = TransactionAccount & { verified: boolean; voted: boolean } + const Proposals = ({ publisherKeyToNameMapping, multisigSignerKeyToNameMapping, @@ -1062,11 +1090,13 @@ const Proposals = ({ multisigSignerKeyToNameMapping: Record }) => { const router = useRouter() + const { connected, publicKey: signerPublicKey } = useWallet() const [currentProposal, setCurrentProposal] = useState() const [currentProposalIndex, setCurrentProposalIndex] = useState() const [allProposalsVerifiedArr, setAllProposalsVerifiedArr] = useState< boolean[] >([]) + const [proposalsVotedArr, setProposalsVotedArr] = useState([]) const [currentProposalPubkey, setCurrentProposalPubkey] = useState() const { cluster } = useContext(ClusterContext) const { statusFilter } = useContext(StatusFilterContext) @@ -1076,9 +1106,9 @@ const Proposals = ({ allProposalsIxsParsed, isLoading: isMultisigLoading, } = useMultisigContext() - const [filteredProposals, setFilteredProposals] = useState< - TransactionAccount[] - >(priceFeedMultisigProposals) + const [filteredProposals, setFilteredProposals] = useState( + [] + ) useEffect(() => { if (!isMultisigLoading) { @@ -1160,19 +1190,59 @@ const Proposals = ({ ]) useEffect(() => { + const allClientProposals = priceFeedMultisigProposals.map( + (proposal, idx) => ({ + ...proposal, + verified: allProposalsVerifiedArr[idx], + voted: proposalsVotedArr[idx], + }) + ) // filter price feed multisig proposals by status if (statusFilter === 'all') { - setFilteredProposals(priceFeedMultisigProposals) + // pass priceFeedMultisigProposals and add verified and voted props + setFilteredProposals(allClientProposals) } else { setFilteredProposals( - priceFeedMultisigProposals.filter( + allClientProposals.filter( (proposal) => getProposalStatus(proposal, priceFeedMultisigAccount) === statusFilter ) ) } - }, [statusFilter, priceFeedMultisigAccount, priceFeedMultisigProposals]) + }, [ + statusFilter, + priceFeedMultisigAccount, + priceFeedMultisigProposals, + allProposalsVerifiedArr, + proposalsVotedArr, + ]) + + useEffect(() => { + if (priceFeedMultisigAccount && connected && signerPublicKey) { + const res: boolean[] = [] + priceFeedMultisigProposals.map((proposal) => { + // check if proposal.approved, proposal.cancelled, proposal.rejected has wallet pubkey and return true if anyone of them has wallet pubkey + const isProposalVoted = + proposal.approved.some( + (p) => p.toBase58() === signerPublicKey.toBase58() + ) || + proposal.cancelled.some( + (p) => p.toBase58() === signerPublicKey.toBase58() + ) || + proposal.rejected.some( + (p) => p.toBase58() === signerPublicKey.toBase58() + ) + res.push(isProposalVoted) + }) + setProposalsVotedArr(res) + } + }, [ + priceFeedMultisigAccount, + priceFeedMultisigProposals, + connected, + signerPublicKey, + ]) return (
@@ -1210,7 +1280,8 @@ const Proposals = ({ diff --git a/governance/xc_admin/packages/xc_admin_frontend/images/icons/voted.inline.svg b/governance/xc_admin/packages/xc_admin_frontend/images/icons/voted.inline.svg new file mode 100644 index 00000000..780c62c1 --- /dev/null +++ b/governance/xc_admin/packages/xc_admin_frontend/images/icons/voted.inline.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + +