From e4d23c687c3219e3563c6e23a9e1fdc93dc313fd Mon Sep 17 00:00:00 2001 From: hans Date: Thu, 13 Jan 2022 18:27:33 -0800 Subject: [PATCH] bugfix: fixed strategy selection --- packages/react-app/src/routes/party/Party.jsx | 145 +++++++++--------- .../src/routes/party/components/ViewTable.jsx | 42 +++-- 2 files changed, 91 insertions(+), 96 deletions(-) diff --git a/packages/react-app/src/routes/party/Party.jsx b/packages/react-app/src/routes/party/Party.jsx index 49d0a381..bf349825 100644 --- a/packages/react-app/src/routes/party/Party.jsx +++ b/packages/react-app/src/routes/party/Party.jsx @@ -1,16 +1,13 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useMemo } from "react"; import { Button, Box, Center, Menu, - MenuOptionGroup, MenuButton, MenuList, - MenuItemOption, - Spacer, + MenuItem, Text, - HStack, } from "@chakra-ui/react"; import { ArrowBackIcon, ChevronDownIcon } from "@chakra-ui/icons"; import { useParams, useHistory } from "react-router-dom"; @@ -37,87 +34,95 @@ export default function Party({ const [canVote, setCanVote] = useState(false); const [isParticipant, setIsParticipant] = useState(false); const [distribution, setDistribution] = useState(); - const [strategy, setStrategy] = useState("linear"); + const [strategy, setStrategy] = useState("quadratic"); const [isPaid, setIsPaid] = useState(false); const db = new MongoDBController(); useEffect(async () => { - db.fetchParty(id) - .then(res => { - setPartyData(res.data); - const votes = res?.data?.ballots?.filter(b => b.data.ballot.address === address); - const participating = res.data.participants.includes(address); - setAccountVoteData(votes); - setCanVote(votes.length === 0 && participating ? true : false); - setIsParticipant(participating); - setIsPaid(res.data.receipts.length > 0); - }) - .catch(err => { - console.log(err); - }); - }, [id]); + const party = await db.fetchParty(id); + const votes = party.data.ballots.filter(b => b.data.ballot.address === address); + const participating = party.data.participants.includes(address); + setAccountVoteData(votes); + setCanVote(votes.length === 0 && participating); + setPartyData(party.data); + }, []); - // Calculate percent distribution from submitted ballots - const calcDistribution = () => { - if (partyData && partyData.ballots && partyData.ballots.length > 0) { - const votes = partyData.ballots.map(b => JSON.parse(b.data.ballot.votes.replace(/[ \n\r]/g, ""))); - let sum = 0; - let processed = []; - // let strategy = partyData.config.strategy; - if (!strategy || strategy === "") { - strategy = "linear"; - console.log("Reverted to linear strategy"); + // Calculate percent distribution from submitted ballots and memo table + const calculateDistribution = () => { + const votes = partyData.ballots.map(b => JSON.parse(b.data.ballot.votes.replace(/[ \n\r]/g, ""))); + let sum = 0; + let processed = []; + let result; + for (let i = 0; i < partyData.candidates.length; i++) { + const candidate = partyData.candidates[i]; + switch (strategy.toLowerCase()) { + default: + result = votes.reduce((total, vote) => vote[candidate] + total, 0); + break; + case "linear": + result = votes.reduce((total, vote) => vote[candidate] + total, 0); + break; + case "quadratic": + result = votes.reduce((total, vote) => vote[candidate] ** 0.5 + total, 0); + break; } - for (let i = 0; i < partyData.candidates.length; i++) { - const candidate = partyData.candidates[i]; - // Strategy handling - // TODO: Switch statement - if (strategy === "linear") { - let c = votes.reduce((total, vote) => vote[candidate] + total, 0); - sum += c; - processed.push({ address: candidate, reduced: c }); - } else if (strategy === "quadratic") { - let c = votes.reduce((total, vote) => vote[candidate] ** 0.5 + total, 0); - sum += c; - processed.push({ address: candidate, reduced: c }); - } - } - let final = []; - for (let i = 0; i < partyData.candidates.length; i++) { - const candidate = partyData.candidates[i]; - final.push({ address: candidate, score: processed[i].reduced / sum }); - } - setDistribution(final); + sum += result; + processed.push({ address: candidate, reduced: result }); } - }; + let final = []; + for (let i = 0; i < partyData.candidates.length; i++) { + const candidate = partyData.candidates[i]; + final.push({ address: candidate, score: processed[i].reduced / sum }); + } + return final; + } + + // Cache the calculated distribution and table component + const cachedViewTable = useMemo(() => { + try { + const dist = calculateDistribution(); + setDistribution(dist); + return ( + + ); + } catch { + return null; + } + }, [partyData, strategy]); const StrategySelect = () => { return ( - + }> {strategy} - setStrategy(e)}> - - Linear - - , - - Quadratic - - + { + setStrategy("quadratic"); + }} + > + Quadratic + + { + setStrategy("linear"); + }} + > + Linear + ); }; - // Calculate the distribution on load - useEffect(() => { - calcDistribution(); - }, [partyData, strategy]); - return (