Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Voting Power column on GSC voting activity table #419

Merged
merged 2 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions apps/council-ui/pages/proposals/details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function ProposalPage(): ReactElement {
);
const { gscMembers } = useGscMembers();

// // voting activity filtering
// voting activity filtering
const [gscOnly, setGscOnly] = useState(false);
const filteredVotes = useMemo(() => {
if (data?.votes && gscOnly && gscMembers) {
Expand All @@ -58,7 +58,7 @@ export default function ProposalPage(): ReactElement {
return dedupeVotes(data?.votes);
}, [data, gscOnly, gscMembers]);

// // Redirect to proposals page if the voting contract is not found.
// Redirect to proposals page if the voting contract is not found.
if (!usedCoreVoting) {
replace("/proposals");
// Returning empty fragment is to remove the undefined type from the query params.
Expand All @@ -67,8 +67,6 @@ export default function ProposalPage(): ReactElement {

const proposalTitle = data?.title ?? `Proposal ${id}`;

// return <>{status}</>;

return (
<Page>
<div className="space-y-2">
Expand Down Expand Up @@ -155,6 +153,9 @@ export default function ProposalPage(): ReactElement {
<VotingActivityTable
votes={filteredVotes}
voterEnsRecords={data.voterEnsRecords}
// The GSC voting contract does not count voting power, you either
// can or cannot vote and the voting power will always be 1 wei.
showVotingPower={!data.isGsc}
/>
) : (
<VotingActivityTableSkeleton />
Expand All @@ -181,7 +182,7 @@ export default function ProposalPage(): ReactElement {

interface ProposalDetailsPageData {
proposalExists: boolean;
type: "core" | "gsc";
isGsc: boolean;
status: ProposalStatus;
isActive: boolean;
votes?: ReadVote[];
Expand Down Expand Up @@ -226,7 +227,7 @@ function useProposalDetailsPageData(

const enabled = !!proposal;

const { data, status, error } = useQuery<ProposalDetailsPageData>({
const { data, status } = useQuery<ProposalDetailsPageData>({
queryKey: ["proposalDetailsPage", coreVotingAddress, String(proposal?.id)],
enabled,
queryFn: enabled
Expand Down Expand Up @@ -272,7 +273,7 @@ function useProposalDetailsPageData(

return {
proposalExists: !!proposal,
type: isGsc ? "gsc" : "core",
isGsc,
votingContractName,
status: getProposalStatus({
isExecuted,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Ballot, ReadVote } from "@delvtech/council-viem";
import { ReactElement, useMemo, useState } from "react";
import { ReactElement, ReactNode, useMemo, useState } from "react";
import { makeVoterURL } from "src/routes";
import { formatVotingPower } from "src/ui/base/formatting/formatVotingPower";
import {
Column,
SortOptions,
SortableGridTable,
} from "src/ui/base/tables/SortableGridTable";
Expand All @@ -15,11 +16,17 @@ type SortField = "votingPower" | "ballot";
interface VotingActivityTableProps {
votes: ReadVote[];
voterEnsRecords: EnsRecords;
/**
* Whether to show the voting power used by each voter.
* @default true
*/
showVotingPower?: boolean;
}

export function VotingActivityTable({
votes,
voterEnsRecords,
showVotingPower = true,
}: VotingActivityTableProps): ReactElement {
const [sortOptions, setSortOptions] = useState<SortOptions<SortField>>({
key: "votingPower",
Expand All @@ -31,35 +38,50 @@ export function VotingActivityTable({
[sortOptions, votes],
);

const cols = useMemo(() => {
const cols: Column<SortField>[] = ["Voter"];

if (showVotingPower) {
cols.push({
cell: "Voting Power",
sortKey: "votingPower",
});
}

cols.push({
cell: "Ballot",
sortKey: "ballot",
});

return cols;
}, [showVotingPower]);

return (
<div className="max-h-96 w-full overflow-auto">
<SortableGridTable
headingRowClassName="grid-cols-[2fr-1fr-1fr]"
bodyRowClassName="grid-cols-[2fr-1fr-1fr]"
headingRowClassName={
showVotingPower ? "grid-cols-[2fr_1fr_1fr]" : "grid-cols-[2fr_1fr]"
}
bodyRowClassName={
showVotingPower ? "grid-cols-[2fr_1fr_1fr]" : "grid-cols-[2fr_1fr]"
}
onSort={setSortOptions}
cols={[
"Voter",
{
cell: "Voting Power",
sortKey: "votingPower",
},
{
cell: "Ballot",
sortKey: "ballot",
},
]}
cols={cols}
rows={sortedData.map(({ voter, power, ballot }, i) => {
const cells: ReactNode[] = [
<VoterAddress
key={`${i}-address`}
address={voter.address}
label={voterEnsRecords[voter.address] || undefined}
/>,
];
if (showVotingPower) {
cells.push(formatVotingPower(power));
}
cells.push(<FormattedBallot key={`${i}-ballot`} ballot={ballot} />);
return {
href: makeVoterURL(voter.address),
cells: [
<VoterAddress
key={`${i}-address`}
address={voter.address}
label={voterEnsRecords[voter.address] || undefined}
/>,
formatVotingPower(power),
<FormattedBallot key={`${i}-ballot`} ballot={ballot} />,
],
cells,
};
})}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,18 @@ export class ReadCoreVoting extends Model {
},
} of voteEvents) {
const proposal = await this.getProposal({ id: proposalId });
if (!proposal) {
throw new Error(
`Vote event for proposal ${proposalId} from voter ${voter} references a non-existent proposal.`,
);
}
votes.push(
new ReadVote({
ballot: BALLOTS[castBallot],
contractFactory: this.contractFactory,
network: this.network,
power: votingPower,
proposal: proposal!,
proposal,
voter,
}),
);
Expand Down