From e5c770d78982fdbf0c87b93838d2e054aa480e52 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 16 Jun 2022 22:13:12 -0300 Subject: [PATCH 01/59] create ActionButton component --- .../client/src/components/ActionButton.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 frontend/packages/client/src/components/ActionButton.js diff --git a/frontend/packages/client/src/components/ActionButton.js b/frontend/packages/client/src/components/ActionButton.js new file mode 100644 index 000000000..242a82b83 --- /dev/null +++ b/frontend/packages/client/src/components/ActionButton.js @@ -0,0 +1,30 @@ +import React from "react"; +import Loader from "components/Loader"; +import classnames from "classnames"; + +export default function ActionButton({ + enabled = true, + onClick = () => {}, + loading = false, + label = "", + classNames, +} = {}) { + const clNames = classnames( + "button transition-all is-flex is-align-items-centered rounded-sm is-uppercase", + "m-0 p-0", + "has-background-yellow", + { "is-enabled": enabled }, + { "is-disabled": !enabled }, + { [classNames]: !!classNames } + ); + return ( + + ); +} From c1d1b6677d6e1988204cdbabc9f471936b27a808 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 16 Jun 2022 22:13:21 -0300 Subject: [PATCH 02/59] create components --- frontend/packages/client/src/components/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/packages/client/src/components/index.js b/frontend/packages/client/src/components/index.js index 3cabd65ba..a83230970 100644 --- a/frontend/packages/client/src/components/index.js +++ b/frontend/packages/client/src/components/index.js @@ -23,6 +23,8 @@ export { default as CommunityEditorProfile } from "./Community/CommunityEditorPr export { default as CommunityEditorLinks } from "./Community/CommunityEditorLinks"; export { default as CommunityEditorDetails } from "./Community/CommunityEditorDetails"; export { default as AddButton } from "./AddButton"; +export { default as ActionButton } from "./ActionButton"; +export { default as CommunityPropsAndVoting } from "./Community/CommunityPropsAndVoting"; export { PropCreateStepOne, PropCreateStepTwo, From 5e876a567827839db5f7c1580285389d2361b700 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 16 Jun 2022 22:17:46 -0300 Subject: [PATCH 03/59] add new tab --- .../client/src/pages/CommunityEditor.js | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/frontend/packages/client/src/pages/CommunityEditor.js b/frontend/packages/client/src/pages/CommunityEditor.js index fcadfe2a9..15558a76c 100644 --- a/frontend/packages/client/src/pages/CommunityEditor.js +++ b/frontend/packages/client/src/pages/CommunityEditor.js @@ -1,20 +1,21 @@ import React, { useState, useCallback, useEffect } from "react"; import { Link, useParams, useHistory } from "react-router-dom"; -import { useWebContext } from "../contexts/Web3"; +import { useWebContext } from "contexts/Web3"; import { CommunityEditorProfile, CommunityEditorLinks, CommunityEditorDetails, + CommunityPropsAndVoting, Dropdown, Loader, -} from "../components"; -import { ArrowLeft, ArrowLeftBold } from "../components/Svg"; +} from "components"; +import { ArrowLeft, ArrowLeftBold } from "components/Svg"; import { useCommunityDetails, useMediaQuery, useFileUploader, useUserRoleOnCommunity, -} from "../hooks"; +} from "hooks"; const MenuTabs = ({ tabs, communityId, onClickButtonTab = () => {} } = {}) => { return ( @@ -50,6 +51,16 @@ const MenuTabs = ({ tabs, communityId, onClickButtonTab = () => {} } = {}) => { Community Details +
+ +
); }; @@ -78,6 +89,7 @@ const DropdownMenu = ({ communityId, onClickButtonTab = () => {} } = {}) => { values={[ { label: "Community Profile", value: "profile" }, { label: "Community Details", value: "details" }, + { label: "Proposals & Voting", value: "proposals-and-voting" }, ]} onSelectValue={(value) => { onClickButtonTab(value)(); @@ -104,7 +116,11 @@ export default function CommunityEditorPage() { const [tabs, setTab] = useState({ profile: true, details: false }); const onClickButtonTab = (value) => () => { - setTab({ profile: value === "profile", details: value === "details" }); + setTab({ + profile: value === "profile", + details: value === "details", + proposalsAndVoting: value === "proposals-and-voting", + }); }; const updateCommunity = useCallback( @@ -183,6 +199,13 @@ export default function CommunityEditorPage() { {tabs.details && ( )} + {tabs.proposalsAndVoting && ( + + )} From 5ec001ae48cdc0614252d92bd41d7884e195a569 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 16 Jun 2022 22:17:55 -0300 Subject: [PATCH 04/59] use mocked data --- frontend/packages/client/src/hooks/useCommunityDetails.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/packages/client/src/hooks/useCommunityDetails.js b/frontend/packages/client/src/hooks/useCommunityDetails.js index 92aff3003..7bb98a8bc 100644 --- a/frontend/packages/client/src/hooks/useCommunityDetails.js +++ b/frontend/packages/client/src/hooks/useCommunityDetails.js @@ -26,6 +26,8 @@ export default function useCommunityDetails(id) { about: { textAbout: details.body, }, + // mocked data + strategies: ["one-address-one-vote"], ...details, }; From 703199eb780b00096b20d93b5345a0f6a14d1813 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 16 Jun 2022 22:18:04 -0300 Subject: [PATCH 05/59] add component --- .../Community/CommunityPropsAndVoting.js | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js new file mode 100644 index 000000000..4a79cd004 --- /dev/null +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -0,0 +1,154 @@ +import React from "react"; +import { WrapperResponsive, Loader, AddButton, ActionButton } from "components"; +import { Bin } from "components/Svg"; +import { useModalContext } from "contexts/NotificationModal"; +import { useVotingStrategies } from "hooks"; + +const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { + return ( +
+ +
+
onDeleteStrategy(index)} + > + +
+
+
+ ); +}; + +const StrategyModalSelector = ({ + onDismiss = () => {}, + enableDismiss = true, +} = {}) => { + return ( +
+
+
+

Edit Strategy Details

+
+
+ × +
+
+
+
+
+
+
+
+
+ ); +}; + +export default function CommunityProposalsAndVoting({ + loading, + communityVotingStrategies = [], +} = {}) { + const { data: allVotingStrategies, loading: loadingAllStrategies } = + useVotingStrategies(); + + console.log(communityVotingStrategies); + + const { openModal, closeModal } = useModalContext(); + + const onAddStrategy = () => { + openModal( closeModal()} />, { + classNameModalContent: "rounded-sm", + }); + }; + + const onDeleteStrategy = () => {}; + const saveData = () => {}; + const savingData = false; + + return ( + +
+
+
+ + Voting Strategies + +
+
+

+ Voting strategies are used to calculate each user’s voting power + on proposals. +

+
+
+
+ {loading && } + {!loading && + communityVotingStrategies.map((commuVotStra, index) => ( + + ))} + + +
+ ); +} From 1439d1eae9b314962432db2d832eea3f1eb4b5d9 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 14:28:49 -0300 Subject: [PATCH 06/59] add responsibe spacing --- frontend/packages/client/src/App.sass | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/frontend/packages/client/src/App.sass b/frontend/packages/client/src/App.sass index e1d247176..63966ebf6 100644 --- a/frontend/packages/client/src/App.sass +++ b/frontend/packages/client/src/App.sass @@ -65,6 +65,49 @@ $popover-max-width: 20rem @import '@creativebulma/bulma-tooltip' @import 'bulma-popover' +=spacing-helpers($suffix: '') + $suffix: if($suffix == '', '', '-' + $suffix) + @each $property, $shortcut in $spacing-shortcuts + @each $name, $value in $spacing-values + @if $property == 'padding' and $value == 'auto' + // Exclude padding value auto + @else + // All directions + .#{$shortcut}-#{$name}#{$suffix} + #{$property}: $value !important + // Cardinal directions + @each $direction, $direction-suffix in $spacing-directions + .#{$shortcut}#{$direction-suffix}-#{$name}#{$suffix} + #{$property}-#{$direction}: $value !important + // Horizontal axis + @if $spacing-horizontal != null + .#{$shortcut}#{$spacing-horizontal}-#{$name}#{$suffix} + #{$property}-left: $value !important + #{$property}-right: $value !important + // Vertical axis + @if $spacing-vertical != null + .#{$shortcut}#{$spacing-vertical}-#{$name}#{$suffix} + #{$property}-top: $value !important + #{$property}-bottom: $value !important +@include spacing-helpers('') + ++mobile + @include spacing-helpers('mobile') + ++mobile + @include spacing-helpers('mobile-only') + ++tablet + @include spacing-helpers('tablet') + ++tablet-only + @include spacing-helpers('tablet-only') + ++desktop + @include spacing-helpers('desktop') + ++desktop-only + @include spacing-helpers('desktop-only') // custom css .App, #root height: 100% From edada720bc76f1fe9014f8c17a528c2ee8e35467 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 18:42:58 -0300 Subject: [PATCH 07/59] add hover to strategy selector --- frontend/packages/client/src/App.sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/client/src/App.sass b/frontend/packages/client/src/App.sass index 9acec7140..0ca9f4205 100644 --- a/frontend/packages/client/src/App.sass +++ b/frontend/packages/client/src/App.sass @@ -473,7 +473,7 @@ span[data-tooltip] .wallet-connect.button.is-primary color: #000000 !important -.community-card:hover, .proposal-card:hover +.community-card:hover, .proposal-card:hover, .strategy-selector:hover border-color: rgba(0, 0, 0, 0.4) border-width: 1px From 9ab2654614e2f8cfed239236f7c3add3697ae6e4 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 18:43:11 -0300 Subject: [PATCH 08/59] add input component --- frontend/packages/client/src/components/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/packages/client/src/components/index.js b/frontend/packages/client/src/components/index.js index a83230970..c0fc8ed10 100644 --- a/frontend/packages/client/src/components/index.js +++ b/frontend/packages/client/src/components/index.js @@ -24,6 +24,7 @@ export { default as CommunityEditorLinks } from "./Community/CommunityEditorLink export { default as CommunityEditorDetails } from "./Community/CommunityEditorDetails"; export { default as AddButton } from "./AddButton"; export { default as ActionButton } from "./ActionButton"; +export { default as Input } from "./Input"; export { default as CommunityPropsAndVoting } from "./Community/CommunityPropsAndVoting"; export { PropCreateStepOne, From 8fe559b1bfa1fe38f6c2c1cd42b341b7d4cc941f Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 18:43:23 -0300 Subject: [PATCH 09/59] create input component --- .../packages/client/src/components/Input.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 frontend/packages/client/src/components/Input.js diff --git a/frontend/packages/client/src/components/Input.js b/frontend/packages/client/src/components/Input.js new file mode 100644 index 000000000..c826d82cd --- /dev/null +++ b/frontend/packages/client/src/components/Input.js @@ -0,0 +1,23 @@ +import React from "react"; + +export default function Input({ + placeholder, + defaultValue, + name, + value, + disabled, + onChange = () => {}, +} = {}) { + return ( + onChange(event.target.value)} + /> + ); +} From 06442489b1e14381ddab9939ef0bb10670a6be8a Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 18:45:33 -0300 Subject: [PATCH 10/59] update component --- .../Community/CommunityPropsAndVoting.js | 92 +++++++++---------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index 4a79cd004..ae8b51880 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,8 +1,9 @@ -import React from "react"; +import React, { useState } from "react"; import { WrapperResponsive, Loader, AddButton, ActionButton } from "components"; import { Bin } from "components/Svg"; import { useModalContext } from "contexts/NotificationModal"; import { useVotingStrategies } from "hooks"; +import StrategyEditorModal from "./StrategyEditorModal"; const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { return ( @@ -40,47 +41,6 @@ const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { ); }; -const StrategyModalSelector = ({ - onDismiss = () => {}, - enableDismiss = true, -} = {}) => { - return ( -
-
-
-

Edit Strategy Details

-
-
- × -
-
-
-
-
-
-
-
-
- ); -}; - export default function CommunityProposalsAndVoting({ loading, communityVotingStrategies = [], @@ -88,18 +48,44 @@ export default function CommunityProposalsAndVoting({ const { data: allVotingStrategies, loading: loadingAllStrategies } = useVotingStrategies(); - console.log(communityVotingStrategies); + const [newStrategies, setNewStrategies] = useState([]); const { openModal, closeModal } = useModalContext(); - + + const strategiesToAdd = (allVotingStrategies || []).filter( + (st) => !communityVotingStrategies.includes(st.key) + ); + + const addNewStrategy = (data) => { + setNewStrategies((state) => [...state, data]); + closeModal(); + }; + const onAddStrategy = () => { - openModal( closeModal()} />, { - classNameModalContent: "rounded-sm", - }); + openModal( + closeModal()} + strategies={strategiesToAdd} + onDone={addNewStrategy} + />, + { + classNameModalContent: "rounded-sm", + showCloseButton: false, + } + ); }; - + + // removes existing strategies on the community const onDeleteStrategy = () => {}; + + // removes new strategies not saved yet + const onDeleteNewStrategy = (index) => { + setNewStrategies((state) => state.filter((st, idx) => idx !== index)); + }; + + // sends updates to backend const saveData = () => {}; + const savingData = false; return ( @@ -131,11 +117,19 @@ export default function CommunityProposalsAndVoting({ {!loading && communityVotingStrategies.map((commuVotStra, index) => ( ))} + {newStrategies.map((st, index) => ( + + ))} Date: Fri, 17 Jun 2022 18:50:12 -0300 Subject: [PATCH 11/59] updates --- .../StrategyInformation.js | 49 ++++++++++++ .../StrategyEditorModal/StrategySelector.js | 36 +++++++++ .../Community/StrategyEditorModal/index.js | 74 +++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js create mode 100644 frontend/packages/client/src/components/Community/StrategyEditorModal/StrategySelector.js create mode 100644 frontend/packages/client/src/components/Community/StrategyEditorModal/index.js diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js new file mode 100644 index 000000000..ad1aefb1e --- /dev/null +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js @@ -0,0 +1,49 @@ +import React, { useState } from "react"; +import { Input, ActionButton } from "components"; + +const staticPlaceholders = { + contractAddress: "Contract Address", + contractName: "Contact Name", + maxWeight: "Max Weight", + minimunBalance: "Minimum Balance", +}; + +export default function StrategyInformation({ onDone = () => {} } = {}) { + const [formData, setFormData] = useState({ + contractAddress: "", + contractName: "", + maxWeight: "", + minimunBalance: "", + }); + + const formFields = Object.keys(formData); + + const setField = (field) => (value) => + setFormData((state) => ({ ...state, [field]: value })); + + const _onDone = () => { + onDone(formData); + }; + + return ( + <> +
+ {formFields.map((field, index) => ( + + ))} +
+ + + ); +} diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategySelector.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategySelector.js new file mode 100644 index 000000000..aea83ac89 --- /dev/null +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategySelector.js @@ -0,0 +1,36 @@ +import React from "react"; + +export default function StrategySelector({ + onDismiss = () => {}, + enableDismiss = true, + strategies = [], + onSelectStrategy, +} = {}) { + const selectStrategy = (stratgy) => () => onSelectStrategy(stratgy); + return ( +
+ {strategies.map((st, index) => { + return ( +
+
+
+

{st.name}

+
+
+

{st.description}

+
+
+
+ ); + })} +
+ ); +} diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js new file mode 100644 index 000000000..21a25de48 --- /dev/null +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from "react"; +import StrategySelector from "./StrategySelector"; +import StrategyInformation from "./StrategyInformation"; + +const ModalSteps = { + 1: "select-strategy", + 2: "strategy-information", +}; + +export default function StrategyEditorModal({ + strategies = [], + enableDismiss = true, + onDismiss = () => {}, + onDone = () => {}, +} = {}) { + const [step, setSep] = useState(ModalSteps[1]); + + const [data, setData] = useState({}); + + const setStrategy = (strategy) => { + setData({ strategy }); + setSep(ModalSteps[2]); + }; + + useEffect(() => { + return setSep(ModalSteps[1]); + }, []); + + const _onDismiss = () => { + setSep(ModalSteps[1]); + onDismiss(); + }; + + const _onDone = (fields) => { + onDone({ ...data, ...fields }); + }; + return ( +
+
+
+

Select a Strategy

+
+
+ × +
+
+
+ {step === ModalSteps[1] && ( + {}} + enableDismiss={true} + strategies={strategies} + onSelectStrategy={setStrategy} + /> + )} + {step === ModalSteps[2] && } +
+
+ ); +} From 1a4690528b7c6c5e33ef89fd835940d760beb059 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 19:25:56 -0300 Subject: [PATCH 12/59] extract state --- .../StrategyInformation.js | 36 ++++++------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js index ad1aefb1e..76a0b38cc 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js @@ -1,30 +1,19 @@ -import React, { useState } from "react"; -import { Input, ActionButton } from "components"; +import React from "react"; +import { Input } from "components"; const staticPlaceholders = { contractAddress: "Contract Address", - contractName: "Contact Name", + contractName: "Contract Name", maxWeight: "Max Weight", minimunBalance: "Minimum Balance", }; -export default function StrategyInformation({ onDone = () => {} } = {}) { - const [formData, setFormData] = useState({ - contractAddress: "", - contractName: "", - maxWeight: "", - minimunBalance: "", - }); - - const formFields = Object.keys(formData); - - const setField = (field) => (value) => - setFormData((state) => ({ ...state, [field]: value })); - - const _onDone = () => { - onDone(formData); - }; - +export default function StrategyInformation({ + formFields = [], + formData = {}, + setField = () => {}, + actionButton, +} = {}) { return ( <>
@@ -38,12 +27,7 @@ export default function StrategyInformation({ onDone = () => {} } = {}) { /> ))}
- + {actionButton} ); } From 47a9c5c54258fcff35c3b1f76c0e687db3105e64 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 20:52:25 -0300 Subject: [PATCH 13/59] fix addbutton --- frontend/packages/client/src/components/AddButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/packages/client/src/components/AddButton.js b/frontend/packages/client/src/components/AddButton.js index 8161bd159..d82f9331a 100644 --- a/frontend/packages/client/src/components/AddButton.js +++ b/frontend/packages/client/src/components/AddButton.js @@ -17,8 +17,8 @@ export default function AddButton({ { "cursor-pointer": !disabled } ); return ( -
- {" "} +
{}}> + {" "} Add{` ${addText}`} From b1038fa06ff30922891a6f2723d29f804307a260 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 20:52:54 -0300 Subject: [PATCH 14/59] updates --- .../Community/CommunityPropsAndVoting.js | 73 ++++++++++++------- .../Community/StrategyEditorModal/index.js | 68 ++++++++++++++--- .../packages/client/src/components/Svg.js | 4 +- .../client/src/pages/CommunityEditor.js | 1 + 4 files changed, 107 insertions(+), 39 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index ae8b51880..b8ec2e56b 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,8 +1,8 @@ import React, { useState } from "react"; -import { WrapperResponsive, Loader, AddButton, ActionButton } from "components"; +import { useVotingStrategies } from "hooks"; +import { Loader, AddButton, ActionButton } from "components"; import { Bin } from "components/Svg"; import { useModalContext } from "contexts/NotificationModal"; -import { useVotingStrategies } from "hooks"; import StrategyEditorModal from "./StrategyEditorModal"; const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { @@ -42,22 +42,35 @@ const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { }; export default function CommunityProposalsAndVoting({ - loading, communityVotingStrategies = [], + communityId, + updateCommunity, + updatingCommunity, } = {}) { const { data: allVotingStrategies, loading: loadingAllStrategies } = useVotingStrategies(); + const [currentStrategies, setCurrentStrategies] = useState( + communityVotingStrategies.map((st) => ({ strategy: st, fromServer: true })) + ); + + // holds array of objects with strategy information to be added const [newStrategies, setNewStrategies] = useState([]); const { openModal, closeModal } = useModalContext(); + // filter strategis: remove existing on community + // and the ones to be added sent to add in the backend const strategiesToAdd = (allVotingStrategies || []).filter( - (st) => !communityVotingStrategies.includes(st.key) + (st) => + ![...currentStrategies, ...newStrategies].find( + (currentSt) => + currentSt.strategy === st.key && currentSt?.removed !== true + ) ); - const addNewStrategy = (data) => { - setNewStrategies((state) => [...state, data]); + const addNewStrategy = (newStrategyInfo) => { + setNewStrategies((state) => [...state, newStrategyInfo]); closeModal(); }; @@ -76,7 +89,17 @@ export default function CommunityProposalsAndVoting({ }; // removes existing strategies on the community - const onDeleteStrategy = () => {}; + const onDeleteStrategy = (index) => { + console.log("called to remove", index); + setCurrentStrategies((state) => + state.map((datum, idx) => { + if (idx === index) { + return { ...datum, removed: true }; + } + return datum; + }) + ); + }; // removes new strategies not saved yet const onDeleteNewStrategy = (index) => { @@ -84,26 +107,21 @@ export default function CommunityProposalsAndVoting({ }; // sends updates to backend - const saveData = () => {}; + const saveData = () => { + console.log("strategies to delete"); + console.log("strategies to add", newStrategies); + }; const savingData = false; return ( - +
- +
Voting Strategies - +

@@ -113,15 +131,16 @@ export default function CommunityProposalsAndVoting({

- {loading && } - {!loading && - communityVotingStrategies.map((commuVotStra, index) => ( + {currentStrategies.map((commuVotStra, index) => + commuVotStra?.removed ? null : ( - ))} + ) + )} {newStrategies.map((st, index) => ( ))} - +
); } diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js index 21a25de48..ac9d8c7c1 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js @@ -1,39 +1,73 @@ import React, { useEffect, useState } from "react"; import StrategySelector from "./StrategySelector"; import StrategyInformation from "./StrategyInformation"; +import { ActionButton } from "components"; +import { isValidAddress } from "utils"; const ModalSteps = { 1: "select-strategy", 2: "strategy-information", }; +const initialFormFields = { + contractAddress: "", + contractName: "", + maxWeight: "", + minimunBalance: "", +}; + +const formFields = Object.keys(initialFormFields); + export default function StrategyEditorModal({ strategies = [], enableDismiss = true, onDismiss = () => {}, + // callback to pass data collected and closed modal onDone = () => {}, } = {}) { const [step, setSep] = useState(ModalSteps[1]); + const [formIsValid, setIsFormValid] = useState(false); - const [data, setData] = useState({}); + const [data, setData] = useState({ + strategy: "", + ...initialFormFields, + }); + // this useEffect validates form on second step + useEffect(() => { + const requiredFields = { + contractAddress: (addr) => + addr?.trim().length > 0 && isValidAddress(addr), + contractName: (name) => + name?.trim().length > 0 && name?.trim().length <= 150, + maxWeight: (maxWeight) => + maxWeight?.trim().length > 0 && /^[0-9]+$/.test(maxWeight), + minimunBalance: (minimunBalance) => + minimunBalance?.trim().length > 0 && /^[0-9]+$/.test(minimunBalance), + }; + const isValid = Object.keys(requiredFields).every( + (field) => data && requiredFields[field](data[field]) + ); + setIsFormValid(isValid); + }, [data]); + + // user selected strategy move to second step to enter information const setStrategy = (strategy) => { - setData({ strategy }); + setData((state) => ({ ...state, strategy })); setSep(ModalSteps[2]); }; - useEffect(() => { - return setSep(ModalSteps[1]); - }, []); - const _onDismiss = () => { - setSep(ModalSteps[1]); onDismiss(); }; - const _onDone = (fields) => { - onDone({ ...data, ...fields }); + const _onDone = () => { + onDone(data); }; + + const setInformationField = (field) => (value) => + setData((state) => ({ ...state, [field]: value })); + return (
)} - {step === ModalSteps[2] && } + {step === ModalSteps[2] && ( + + } + /> + )}
); diff --git a/frontend/packages/client/src/components/Svg.js b/frontend/packages/client/src/components/Svg.js index 7494f2a51..f12e1bb16 100644 --- a/frontend/packages/client/src/components/Svg.js +++ b/frontend/packages/client/src/components/Svg.js @@ -59,7 +59,7 @@ export const Bin = () => ( ); -export const Plus = () => ( +export const Plus = ({ fill = "black" } = {}) => ( ( fill="none" xmlns="http://www.w3.org/2000/svg" > - + ); diff --git a/frontend/packages/client/src/pages/CommunityEditor.js b/frontend/packages/client/src/pages/CommunityEditor.js index 15558a76c..02c93b3b6 100644 --- a/frontend/packages/client/src/pages/CommunityEditor.js +++ b/frontend/packages/client/src/pages/CommunityEditor.js @@ -203,6 +203,7 @@ export default function CommunityEditorPage() { )} From caea941af2e1b81bb2687c5f5b2b6ad1deac1908 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 20:53:03 -0300 Subject: [PATCH 15/59] set state to null --- frontend/packages/client/src/contexts/NotificationModal.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/packages/client/src/contexts/NotificationModal.js b/frontend/packages/client/src/contexts/NotificationModal.js index eeffd89a3..02a89f0d3 100644 --- a/frontend/packages/client/src/contexts/NotificationModal.js +++ b/frontend/packages/client/src/contexts/NotificationModal.js @@ -60,6 +60,8 @@ const NotificationModalProvider = ({ children }) => { const closeModal = useCallback(() => { setModal(false); + // this unmounts the component + setContent(null); modalConfig.onClose(); }, [modalConfig]); From cfcf0000b4f5ca86bd383c1417992029c73d3521 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 21:02:43 -0300 Subject: [PATCH 16/59] remove loader --- .../Community/CommunityPropsAndVoting.js | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index b8ec2e56b..6d6bf6155 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { useVotingStrategies } from "hooks"; -import { Loader, AddButton, ActionButton } from "components"; +import { AddButton, ActionButton } from "components"; import { Bin } from "components/Svg"; import { useModalContext } from "contexts/NotificationModal"; import StrategyEditorModal from "./StrategyEditorModal"; @@ -65,7 +65,7 @@ export default function CommunityProposalsAndVoting({ (st) => ![...currentStrategies, ...newStrategies].find( (currentSt) => - currentSt.strategy === st.key && currentSt?.removed !== true + currentSt.strategy === st.key && currentSt?.toBeremoved !== true ) ); @@ -108,8 +108,18 @@ export default function CommunityProposalsAndVoting({ // sends updates to backend const saveData = () => { - console.log("strategies to delete"); - console.log("strategies to add", newStrategies); + // we need to remove strategies first: + // in case user removes and old one and + // creates the same strategy with different contract information + // use same signature for both requests + console.log( + "--- strategies to delete ---", + currentStrategies.filter((st) => st?.toBeremoved) + ); + // we will add new strategies + console.log("--- strategies to add ---", newStrategies); + + // await updateCommunity() }; const savingData = false; @@ -132,7 +142,7 @@ export default function CommunityProposalsAndVoting({
{currentStrategies.map((commuVotStra, index) => - commuVotStra?.removed ? null : ( + commuVotStra?.toBeremoved ? null : ( Date: Fri, 17 Jun 2022 21:03:19 -0300 Subject: [PATCH 17/59] update for one-address-one-vote --- .../components/Community/StrategyEditorModal/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js index ac9d8c7c1..d97c24bef 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js @@ -54,6 +54,17 @@ export default function StrategyEditorModal({ // user selected strategy move to second step to enter information const setStrategy = (strategy) => { setData((state) => ({ ...state, strategy })); + + // + // Very important!!! + // If strategy selected is 'one-address-one-vote' + // then no more information is required + // modal should be closed and + // strategy should be ready to be added + if (strategy === "one-address-one-vote") { + onDone({ strategy }); + return; + } setSep(ModalSteps[2]); }; From 64c128712f083adf531ea31924de3e9e307f9c7a Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 21:15:06 -0300 Subject: [PATCH 18/59] remove output --- .../client/src/components/Community/CommunityPropsAndVoting.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index 6d6bf6155..b23ea4361 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -90,7 +90,6 @@ export default function CommunityProposalsAndVoting({ // removes existing strategies on the community const onDeleteStrategy = (index) => { - console.log("called to remove", index); setCurrentStrategies((state) => state.map((datum, idx) => { if (idx === index) { From 7b9c3ddd2dba2be17a2ae2bf5e19c7d435bc54ce Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 21:17:52 -0300 Subject: [PATCH 19/59] change name --- .../{StrategyInformation.js => StrategyInformationForm.js} | 2 +- .../src/components/Community/StrategyEditorModal/index.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename frontend/packages/client/src/components/Community/StrategyEditorModal/{StrategyInformation.js => StrategyInformationForm.js} (93%) diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js similarity index 93% rename from frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js rename to frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js index 76a0b38cc..5decc3ddd 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformation.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js @@ -8,7 +8,7 @@ const staticPlaceholders = { minimunBalance: "Minimum Balance", }; -export default function StrategyInformation({ +export default function StrategyInformationForm({ formFields = [], formData = {}, setField = () => {}, diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js index d97c24bef..95bb73316 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; import StrategySelector from "./StrategySelector"; -import StrategyInformation from "./StrategyInformation"; +import StrategyInformationForm from "./StrategyInformationForm"; import { ActionButton } from "components"; import { isValidAddress } from "utils"; @@ -113,7 +113,7 @@ export default function StrategyEditorModal({ /> )} {step === ModalSteps[2] && ( - Date: Fri, 17 Jun 2022 21:20:00 -0300 Subject: [PATCH 20/59] assign null --- .../Community/StrategyEditorModal/StrategyInformationForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js index 5decc3ddd..3398986e7 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/StrategyInformationForm.js @@ -12,7 +12,7 @@ export default function StrategyInformationForm({ formFields = [], formData = {}, setField = () => {}, - actionButton, + actionButton = null, } = {}) { return ( <> From 80806b15542cd573d9b250d864bd1e69d3ca2ceb Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Fri, 17 Jun 2022 21:32:36 -0300 Subject: [PATCH 21/59] add enableDelete --- .../Community/CommunityPropsAndVoting.js | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index b23ea4361..af0e05dfc 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -5,7 +5,12 @@ import { Bin } from "components/Svg"; import { useModalContext } from "contexts/NotificationModal"; import StrategyEditorModal from "./StrategyEditorModal"; -const StrategyInput = ({ index, commuVotStra, onDeleteStrategy } = {}) => { +const StrategyInput = ({ + index, + commuVotStra, + onDeleteStrategy, + enableDelete, +} = {}) => { return (
{ top: 9, }} > -
onDeleteStrategy(index)} - > - -
+ {enableDelete && ( +
onDeleteStrategy(index)} + > + +
+ )}
); @@ -93,7 +100,7 @@ export default function CommunityProposalsAndVoting({ setCurrentStrategies((state) => state.map((datum, idx) => { if (idx === index) { - return { ...datum, removed: true }; + return { ...datum, toBeRemoved: true }; } return datum; }) @@ -123,6 +130,7 @@ export default function CommunityProposalsAndVoting({ const savingData = false; + const enableDelete = currentStrategies.length + newStrategies.length > 1; return (
@@ -147,6 +155,7 @@ export default function CommunityProposalsAndVoting({ key={`existing-${index}`} commuVotStra={commuVotStra.strategy} onDeleteStrategy={onDeleteStrategy} + enableDelete={enableDelete} /> ) )} @@ -156,6 +165,7 @@ export default function CommunityProposalsAndVoting({ key={`new-${index}`} commuVotStra={st.strategy} onDeleteStrategy={onDeleteNewStrategy} + enableDelete={enableDelete} /> ))} Date: Mon, 20 Jun 2022 23:47:39 -0300 Subject: [PATCH 22/59] hook function to save data to backend --- .../Community/CommunityPropsAndVoting.js | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index af0e05dfc..5a6e94f54 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -113,7 +113,7 @@ export default function CommunityProposalsAndVoting({ }; // sends updates to backend - const saveData = () => { + const saveData = async () => { // we need to remove strategies first: // in case user removes and old one and // creates the same strategy with different contract information @@ -125,11 +125,23 @@ export default function CommunityProposalsAndVoting({ // we will add new strategies console.log("--- strategies to add ---", newStrategies); - // await updateCommunity() + // array like: + /* + { + strategies: [ + { + contractAddress: "0x0000012122222222" + contractName: "222" + maxWeight: "2222222" + minimunBalance: "2222" + strategy: "staked-token-weighted-default" + } + ] + } + */ + await updateCommunity({ strategies: newStrategies }); }; - const savingData = false; - const enableDelete = currentStrategies.length + newStrategies.length > 1; return (
@@ -178,7 +190,7 @@ export default function CommunityProposalsAndVoting({ label="save" enabled={!updatingCommunity} onClick={saveData} - loading={savingData} + loading={updatingCommunity} classNames="mt-5" />
From d8c87d43b1c4d8c28698265442b6fc4175221d93 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Mon, 20 Jun 2022 23:49:10 -0300 Subject: [PATCH 23/59] remove wait --- frontend/packages/client/src/hooks/useCommunityDetails.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/frontend/packages/client/src/hooks/useCommunityDetails.js b/frontend/packages/client/src/hooks/useCommunityDetails.js index 7bb98a8bc..524ce2213 100644 --- a/frontend/packages/client/src/hooks/useCommunityDetails.js +++ b/frontend/packages/client/src/hooks/useCommunityDetails.js @@ -73,14 +73,6 @@ export default function useCommunityDetails(id) { dispatch({ type: "PROCESSING" }); const response = await fetch(url, fetchOptions); const json = await checkResponse(response); - const wait = async () => - new Promise((resolve) => { - setTimeout(() => { - resolve(true); - }, 4000); - }); - - await wait(); dispatch({ type: "SUCCESS", payload: json, From 9a157bcfdf24172d8628320032fd1bdefcd1e2b3 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 15:29:51 -0300 Subject: [PATCH 24/59] extract Strategy Selector --- .../Community/CommunityPropsAndVoting.js | 195 +++--------------- .../components/Community/StrategySelector.js | 136 ++++++++++++ 2 files changed, 160 insertions(+), 171 deletions(-) create mode 100644 frontend/packages/client/src/components/Community/StrategySelector.js diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index 5a6e94f54..d58b51b8b 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,130 +1,15 @@ -import React, { useState } from "react"; -import { useVotingStrategies } from "hooks"; -import { AddButton, ActionButton } from "components"; -import { Bin } from "components/Svg"; -import { useModalContext } from "contexts/NotificationModal"; -import StrategyEditorModal from "./StrategyEditorModal"; - -const StrategyInput = ({ - index, - commuVotStra, - onDeleteStrategy, - enableDelete, -} = {}) => { - return ( -
- -
- {enableDelete && ( -
onDeleteStrategy(index)} - > - -
- )} -
-
- ); -}; +import React from "react"; +import ActionButton from "components/ActionButton"; +import StrategySelector from "components/Community/StrategySelector"; export default function CommunityProposalsAndVoting({ communityVotingStrategies = [], - communityId, updateCommunity, updatingCommunity, } = {}) { - const { data: allVotingStrategies, loading: loadingAllStrategies } = - useVotingStrategies(); - - const [currentStrategies, setCurrentStrategies] = useState( - communityVotingStrategies.map((st) => ({ strategy: st, fromServer: true })) - ); - - // holds array of objects with strategy information to be added - const [newStrategies, setNewStrategies] = useState([]); - - const { openModal, closeModal } = useModalContext(); - - // filter strategis: remove existing on community - // and the ones to be added sent to add in the backend - const strategiesToAdd = (allVotingStrategies || []).filter( - (st) => - ![...currentStrategies, ...newStrategies].find( - (currentSt) => - currentSt.strategy === st.key && currentSt?.toBeremoved !== true - ) - ); - - const addNewStrategy = (newStrategyInfo) => { - setNewStrategies((state) => [...state, newStrategyInfo]); - closeModal(); - }; - - const onAddStrategy = () => { - openModal( - closeModal()} - strategies={strategiesToAdd} - onDone={addNewStrategy} - />, - { - classNameModalContent: "rounded-sm", - showCloseButton: false, - } - ); - }; - - // removes existing strategies on the community - const onDeleteStrategy = (index) => { - setCurrentStrategies((state) => - state.map((datum, idx) => { - if (idx === index) { - return { ...datum, toBeRemoved: true }; - } - return datum; - }) - ); - }; - - // removes new strategies not saved yet - const onDeleteNewStrategy = (index) => { - setNewStrategies((state) => state.filter((st, idx) => idx !== index)); - }; - // sends updates to backend - const saveData = async () => { - // we need to remove strategies first: - // in case user removes and old one and - // creates the same strategy with different contract information - // use same signature for both requests - console.log( - "--- strategies to delete ---", - currentStrategies.filter((st) => st?.toBeremoved) - ); - // we will add new strategies - console.log("--- strategies to add ---", newStrategies); - + const saveData = async (strategies) => { + console.log("--- strategies to update ---", strategies); // array like: /* { @@ -139,60 +24,28 @@ export default function CommunityProposalsAndVoting({ ] } */ - await updateCommunity({ strategies: newStrategies }); + await updateCommunity({ strategies }); }; - const enableDelete = currentStrategies.length + newStrategies.length > 1; + // used like this until backend returns strategies + const st = communityVotingStrategies.map((st) => ({ + strategy: st, + })); + return ( -
-
-
-
-
- Voting Strategies -
-
-
-

- Voting strategies are used to calculate each user’s voting power - on proposals. -

-
-
-
- {currentStrategies.map((commuVotStra, index) => - commuVotStra?.toBeremoved ? null : ( - - ) - )} - {newStrategies.map((st, index) => ( - ( + saveData(st)} + loading={updatingCommunity} + classNames="mt-5" /> - ))} - - -
+ )} + /> ); } diff --git a/frontend/packages/client/src/components/Community/StrategySelector.js b/frontend/packages/client/src/components/Community/StrategySelector.js new file mode 100644 index 000000000..9891d7320 --- /dev/null +++ b/frontend/packages/client/src/components/Community/StrategySelector.js @@ -0,0 +1,136 @@ +import React, { useState } from "react"; +import { useVotingStrategies } from "hooks"; +import { AddButton } from "components"; +import { Bin } from "components/Svg"; +import { useModalContext } from "contexts/NotificationModal"; +import StrategyEditorModal from "./StrategyEditorModal"; + +const StrategyInput = ({ + index, + commuVotStra, + onDeleteStrategy, + enableDelete, + onChange = () => {}, +} = {}) => { + return ( +
+ +
+ {enableDelete && ( +
onDeleteStrategy(index)} + > + +
+ )} +
+
+ ); +}; + +export default function StrategySelector({ + existingStrategies = [], + disableAddButton = false, + callToAction = () => {}, +} = {}) { + // holds array of objects with strategy information + const [strategies, setStrategies] = useState(existingStrategies); + + const { data: allVotingStrategies, loading: loadingAllStrategies } = + useVotingStrategies(); + + const { openModal, closeModal } = useModalContext(); + + const strategiesToAdd = (allVotingStrategies || []).filter( + (st) => + !strategies.find( + (currentSt) => + currentSt.strategy === st.key && currentSt?.toBeremoved !== true + ) + ); + + const addNewStrategy = (newStrategyInfo) => { + setStrategies((state) => [...state, newStrategyInfo]); + closeModal(); + }; + + const onAddStrategy = () => { + openModal( + closeModal()} + strategies={strategiesToAdd} + onDone={addNewStrategy} + />, + { + classNameModalContent: "rounded-sm", + showCloseButton: false, + } + ); + }; + + const onDeleteStrategy = (index) => { + setStrategies((state) => state.filter((_, idx) => idx !== index)); + }; + + const enableDelete = strategies.length > 1; + + const callToActionComponent = callToAction(strategies); + + return ( +
+
+
+
+
+ Voting Strategies +
+
+
+

+ Voting strategies are used to calculate each user’s voting power + on proposals. +

+
+
+
+ {strategies.map((st, index) => ( + + ))} + + {callToActionComponent} +
+ ); +} From 30faea71951aa482c1471760d4d662693c5985ff Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 15:30:02 -0300 Subject: [PATCH 25/59] add new step --- .../client/src/components/CommunityCreate/StepFour.js | 5 +++++ .../packages/client/src/components/CommunityCreate/index.js | 1 + 2 files changed, 6 insertions(+) create mode 100644 frontend/packages/client/src/components/CommunityCreate/StepFour.js diff --git a/frontend/packages/client/src/components/CommunityCreate/StepFour.js b/frontend/packages/client/src/components/CommunityCreate/StepFour.js new file mode 100644 index 000000000..8b3726588 --- /dev/null +++ b/frontend/packages/client/src/components/CommunityCreate/StepFour.js @@ -0,0 +1,5 @@ +import React from "react"; + +export default function StepFour() { + return
StepFour
; +} diff --git a/frontend/packages/client/src/components/CommunityCreate/index.js b/frontend/packages/client/src/components/CommunityCreate/index.js index c0bbd2fa1..089b9a9cf 100644 --- a/frontend/packages/client/src/components/CommunityCreate/index.js +++ b/frontend/packages/client/src/components/CommunityCreate/index.js @@ -2,3 +2,4 @@ export { default as StartSteps } from "./StartSteps"; export { default as StepOne } from "./StepOne"; export { default as StepTwo } from "./StepTwo"; export { default as StepThree } from "./StepThree"; +export { default as StepFour } from "./StepFour"; From 3dc92a281562f87d040fec1d31dd09777e6f24e3 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 15:29:51 -0300 Subject: [PATCH 26/59] extract Strategy Selector --- .../Community/CommunityPropsAndVoting.js | 195 +++--------------- .../components/Community/StrategySelector.js | 136 ++++++++++++ 2 files changed, 160 insertions(+), 171 deletions(-) create mode 100644 frontend/packages/client/src/components/Community/StrategySelector.js diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index 5a6e94f54..d58b51b8b 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,130 +1,15 @@ -import React, { useState } from "react"; -import { useVotingStrategies } from "hooks"; -import { AddButton, ActionButton } from "components"; -import { Bin } from "components/Svg"; -import { useModalContext } from "contexts/NotificationModal"; -import StrategyEditorModal from "./StrategyEditorModal"; - -const StrategyInput = ({ - index, - commuVotStra, - onDeleteStrategy, - enableDelete, -} = {}) => { - return ( -
- -
- {enableDelete && ( -
onDeleteStrategy(index)} - > - -
- )} -
-
- ); -}; +import React from "react"; +import ActionButton from "components/ActionButton"; +import StrategySelector from "components/Community/StrategySelector"; export default function CommunityProposalsAndVoting({ communityVotingStrategies = [], - communityId, updateCommunity, updatingCommunity, } = {}) { - const { data: allVotingStrategies, loading: loadingAllStrategies } = - useVotingStrategies(); - - const [currentStrategies, setCurrentStrategies] = useState( - communityVotingStrategies.map((st) => ({ strategy: st, fromServer: true })) - ); - - // holds array of objects with strategy information to be added - const [newStrategies, setNewStrategies] = useState([]); - - const { openModal, closeModal } = useModalContext(); - - // filter strategis: remove existing on community - // and the ones to be added sent to add in the backend - const strategiesToAdd = (allVotingStrategies || []).filter( - (st) => - ![...currentStrategies, ...newStrategies].find( - (currentSt) => - currentSt.strategy === st.key && currentSt?.toBeremoved !== true - ) - ); - - const addNewStrategy = (newStrategyInfo) => { - setNewStrategies((state) => [...state, newStrategyInfo]); - closeModal(); - }; - - const onAddStrategy = () => { - openModal( - closeModal()} - strategies={strategiesToAdd} - onDone={addNewStrategy} - />, - { - classNameModalContent: "rounded-sm", - showCloseButton: false, - } - ); - }; - - // removes existing strategies on the community - const onDeleteStrategy = (index) => { - setCurrentStrategies((state) => - state.map((datum, idx) => { - if (idx === index) { - return { ...datum, toBeRemoved: true }; - } - return datum; - }) - ); - }; - - // removes new strategies not saved yet - const onDeleteNewStrategy = (index) => { - setNewStrategies((state) => state.filter((st, idx) => idx !== index)); - }; - // sends updates to backend - const saveData = async () => { - // we need to remove strategies first: - // in case user removes and old one and - // creates the same strategy with different contract information - // use same signature for both requests - console.log( - "--- strategies to delete ---", - currentStrategies.filter((st) => st?.toBeremoved) - ); - // we will add new strategies - console.log("--- strategies to add ---", newStrategies); - + const saveData = async (strategies) => { + console.log("--- strategies to update ---", strategies); // array like: /* { @@ -139,60 +24,28 @@ export default function CommunityProposalsAndVoting({ ] } */ - await updateCommunity({ strategies: newStrategies }); + await updateCommunity({ strategies }); }; - const enableDelete = currentStrategies.length + newStrategies.length > 1; + // used like this until backend returns strategies + const st = communityVotingStrategies.map((st) => ({ + strategy: st, + })); + return ( -
-
-
-
-
- Voting Strategies -
-
-
-

- Voting strategies are used to calculate each user’s voting power - on proposals. -

-
-
-
- {currentStrategies.map((commuVotStra, index) => - commuVotStra?.toBeremoved ? null : ( - - ) - )} - {newStrategies.map((st, index) => ( - ( + saveData(st)} + loading={updatingCommunity} + classNames="mt-5" /> - ))} - - -
+ )} + /> ); } diff --git a/frontend/packages/client/src/components/Community/StrategySelector.js b/frontend/packages/client/src/components/Community/StrategySelector.js new file mode 100644 index 000000000..9891d7320 --- /dev/null +++ b/frontend/packages/client/src/components/Community/StrategySelector.js @@ -0,0 +1,136 @@ +import React, { useState } from "react"; +import { useVotingStrategies } from "hooks"; +import { AddButton } from "components"; +import { Bin } from "components/Svg"; +import { useModalContext } from "contexts/NotificationModal"; +import StrategyEditorModal from "./StrategyEditorModal"; + +const StrategyInput = ({ + index, + commuVotStra, + onDeleteStrategy, + enableDelete, + onChange = () => {}, +} = {}) => { + return ( +
+ +
+ {enableDelete && ( +
onDeleteStrategy(index)} + > + +
+ )} +
+
+ ); +}; + +export default function StrategySelector({ + existingStrategies = [], + disableAddButton = false, + callToAction = () => {}, +} = {}) { + // holds array of objects with strategy information + const [strategies, setStrategies] = useState(existingStrategies); + + const { data: allVotingStrategies, loading: loadingAllStrategies } = + useVotingStrategies(); + + const { openModal, closeModal } = useModalContext(); + + const strategiesToAdd = (allVotingStrategies || []).filter( + (st) => + !strategies.find( + (currentSt) => + currentSt.strategy === st.key && currentSt?.toBeremoved !== true + ) + ); + + const addNewStrategy = (newStrategyInfo) => { + setStrategies((state) => [...state, newStrategyInfo]); + closeModal(); + }; + + const onAddStrategy = () => { + openModal( + closeModal()} + strategies={strategiesToAdd} + onDone={addNewStrategy} + />, + { + classNameModalContent: "rounded-sm", + showCloseButton: false, + } + ); + }; + + const onDeleteStrategy = (index) => { + setStrategies((state) => state.filter((_, idx) => idx !== index)); + }; + + const enableDelete = strategies.length > 1; + + const callToActionComponent = callToAction(strategies); + + return ( +
+
+
+
+
+ Voting Strategies +
+
+
+

+ Voting strategies are used to calculate each user’s voting power + on proposals. +

+
+
+
+ {strategies.map((st, index) => ( + + ))} + + {callToActionComponent} +
+ ); +} From 0b94a234559948d93a0d0c3c0edf326b8faf785a Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 16:21:59 -0300 Subject: [PATCH 27/59] update name of component --- .../components/Community/CommunityPropsAndVoting.js | 4 ++-- .../Community/StrategyEditorModal/StrategySelector.js | 11 +++++++---- .../{StrategySelector.js => StrategySelectorForm.js} | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) rename frontend/packages/client/src/components/Community/{StrategySelector.js => StrategySelectorForm.js} (98%) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index d58b51b8b..c2598268a 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -1,6 +1,6 @@ import React from "react"; import ActionButton from "components/ActionButton"; -import StrategySelector from "components/Community/StrategySelector"; +import StrategySelectorForm from "components/Community/StrategySelectorForm"; export default function CommunityProposalsAndVoting({ communityVotingStrategies = [], @@ -33,7 +33,7 @@ export default function CommunityProposalsAndVoting({ })); return ( - {}, - enableDismiss = true, strategies = [], onSelectStrategy, } = {}) { @@ -10,7 +8,7 @@ export default function StrategySelector({ return (
{strategies.map((st, index) => { return ( @@ -22,7 +20,7 @@ export default function StrategySelector({ >
-

{st.name}

+

{st.name}

{st.description}

@@ -31,6 +29,11 @@ export default function StrategySelector({
); })} + {strategies.length === 0 && ( +
+

No more Strategies to Add

+
+ )}
); } diff --git a/frontend/packages/client/src/components/Community/StrategySelector.js b/frontend/packages/client/src/components/Community/StrategySelectorForm.js similarity index 98% rename from frontend/packages/client/src/components/Community/StrategySelector.js rename to frontend/packages/client/src/components/Community/StrategySelectorForm.js index 9891d7320..3636f8849 100644 --- a/frontend/packages/client/src/components/Community/StrategySelector.js +++ b/frontend/packages/client/src/components/Community/StrategySelectorForm.js @@ -50,7 +50,7 @@ const StrategyInput = ({ ); }; -export default function StrategySelector({ +export default function StrategySelectorForm({ existingStrategies = [], disableAddButton = false, callToAction = () => {}, From 9f7d5697d6dea5b43bdfb35967543259ed916a07 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 16:39:04 -0300 Subject: [PATCH 28/59] update step four --- .../components/CommunityCreate/StepFour.js | 27 +++++++++++++++++-- .../components/CommunityCreate/StepThree.js | 25 +++++++++-------- .../client/src/pages/CommunityCreate.js | 16 +++++------ 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/frontend/packages/client/src/components/CommunityCreate/StepFour.js b/frontend/packages/client/src/components/CommunityCreate/StepFour.js index 8b3726588..6d607bfa8 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepFour.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepFour.js @@ -1,5 +1,28 @@ import React from "react"; -export default function StepFour() { - return
StepFour
; +export default function StepFour({ + stepData, + setStepValid, + onDataChange, + onSubmit, + isStepValid, +} = {}) { + const { strategies } = stepData || {}; + + return ( +
+ StepFour +
+ +
+
+ ); } diff --git a/frontend/packages/client/src/components/CommunityCreate/StepThree.js b/frontend/packages/client/src/components/CommunityCreate/StepThree.js index eb3a716fc..ecdc27747 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepThree.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepThree.js @@ -6,8 +6,8 @@ export default function StepThree({ stepData, setStepValid, onDataChange, - onSubmit, isStepValid, + moveToNextStep, }) { const { proposalThreshold = "", @@ -110,16 +110,19 @@ export default function StepThree({

-
- + +
+
+ +
); diff --git a/frontend/packages/client/src/pages/CommunityCreate.js b/frontend/packages/client/src/pages/CommunityCreate.js index 40ae8bb54..957067a28 100644 --- a/frontend/packages/client/src/pages/CommunityCreate.js +++ b/frontend/packages/client/src/pages/CommunityCreate.js @@ -8,6 +8,7 @@ import { StepOne, StepTwo, StepThree, + StepFour, } from "components/CommunityCreate"; import useCommunity from "hooks/useCommunity"; import { generateSlug } from "utils"; @@ -93,21 +94,20 @@ export default function CommunityCreate() { steps: [ { label: "Community Profile", - description: - "Some description of what you can write here that is useful.", component: , }, { label: "Community Details", - description: - "Some description of what you can write here that is useful.", - component: , + component: , }, { label: "Proposal & Voting", - description: - "Some description of what you can write here that is useful.", - component: , + description: "", + component: , + }, + { + label: "Voting Strategies", + component: , }, ], }; From e4feb62ec534ad2f80f3597b8341cc895f876f64 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 16:50:38 -0300 Subject: [PATCH 29/59] remove strategy --- .../components/Community/StrategySelector.js | 136 ------------------ 1 file changed, 136 deletions(-) delete mode 100644 frontend/packages/client/src/components/Community/StrategySelector.js diff --git a/frontend/packages/client/src/components/Community/StrategySelector.js b/frontend/packages/client/src/components/Community/StrategySelector.js deleted file mode 100644 index 9891d7320..000000000 --- a/frontend/packages/client/src/components/Community/StrategySelector.js +++ /dev/null @@ -1,136 +0,0 @@ -import React, { useState } from "react"; -import { useVotingStrategies } from "hooks"; -import { AddButton } from "components"; -import { Bin } from "components/Svg"; -import { useModalContext } from "contexts/NotificationModal"; -import StrategyEditorModal from "./StrategyEditorModal"; - -const StrategyInput = ({ - index, - commuVotStra, - onDeleteStrategy, - enableDelete, - onChange = () => {}, -} = {}) => { - return ( -
- -
- {enableDelete && ( -
onDeleteStrategy(index)} - > - -
- )} -
-
- ); -}; - -export default function StrategySelector({ - existingStrategies = [], - disableAddButton = false, - callToAction = () => {}, -} = {}) { - // holds array of objects with strategy information - const [strategies, setStrategies] = useState(existingStrategies); - - const { data: allVotingStrategies, loading: loadingAllStrategies } = - useVotingStrategies(); - - const { openModal, closeModal } = useModalContext(); - - const strategiesToAdd = (allVotingStrategies || []).filter( - (st) => - !strategies.find( - (currentSt) => - currentSt.strategy === st.key && currentSt?.toBeremoved !== true - ) - ); - - const addNewStrategy = (newStrategyInfo) => { - setStrategies((state) => [...state, newStrategyInfo]); - closeModal(); - }; - - const onAddStrategy = () => { - openModal( - closeModal()} - strategies={strategiesToAdd} - onDone={addNewStrategy} - />, - { - classNameModalContent: "rounded-sm", - showCloseButton: false, - } - ); - }; - - const onDeleteStrategy = (index) => { - setStrategies((state) => state.filter((_, idx) => idx !== index)); - }; - - const enableDelete = strategies.length > 1; - - const callToActionComponent = callToAction(strategies); - - return ( -
-
-
-
-
- Voting Strategies -
-
-
-

- Voting strategies are used to calculate each user’s voting power - on proposals. -

-
-
-
- {strategies.map((st, index) => ( - - ))} - - {callToActionComponent} -
- ); -} From 31f1b4edd1b2fa6803c68c92fa59edfa8fcff980 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Tue, 21 Jun 2022 16:54:46 -0300 Subject: [PATCH 30/59] add validation to step four --- .../components/CommunityCreate/StepFour.js | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/frontend/packages/client/src/components/CommunityCreate/StepFour.js b/frontend/packages/client/src/components/CommunityCreate/StepFour.js index 6d607bfa8..d27cfdea4 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepFour.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepFour.js @@ -1,4 +1,6 @@ -import React from "react"; +import React, { useEffect } from "react"; +import StrategySelectorForm from "components/Community/StrategySelectorForm"; +import { ActionButton } from "components"; export default function StepFour({ stepData, @@ -9,9 +11,29 @@ export default function StepFour({ } = {}) { const { strategies } = stepData || {}; + useEffect(() => { + if (strategies.length > 1) { + setStepValid(true); + } + }, [strategies, setStepValid]); + return (
- StepFour + { + onDataChange({ strategies: st }); + return ( + onSubmit() : () => {}} + classNames="mt-5" + /> + ); + }} + />
-
+
@@ -87,9 +87,9 @@ const DropdownMenu = ({ communityId, onClickButtonTab = () => {} } = {}) => { { onClickButtonTab(value)(); @@ -117,9 +117,9 @@ export default function CommunityEditorPage() { const onClickButtonTab = (value) => () => { setTab({ - profile: value === "profile", - details: value === "details", - proposalsAndVoting: value === "proposals-and-voting", + profile: value === 'profile', + details: value === 'details', + proposalsAndVoting: value === 'proposals-and-voting', }); }; From ae67d9aabcedcda3c21e56b73714e8f1084b3561 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 22 Jun 2022 10:57:46 -0300 Subject: [PATCH 32/59] eslint fixes --- .../client/src/components/ActionButton.js | 20 ++++++------- .../Community/StrategySelectorForm.js | 28 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/frontend/packages/client/src/components/ActionButton.js b/frontend/packages/client/src/components/ActionButton.js index 242a82b83..79b15d383 100644 --- a/frontend/packages/client/src/components/ActionButton.js +++ b/frontend/packages/client/src/components/ActionButton.js @@ -1,25 +1,25 @@ -import React from "react"; -import Loader from "components/Loader"; -import classnames from "classnames"; +import React from 'react'; +import Loader from 'components/Loader'; +import classnames from 'classnames'; export default function ActionButton({ enabled = true, onClick = () => {}, loading = false, - label = "", + label = '', classNames, } = {}) { const clNames = classnames( - "button transition-all is-flex is-align-items-centered rounded-sm is-uppercase", - "m-0 p-0", - "has-background-yellow", - { "is-enabled": enabled }, - { "is-disabled": !enabled }, + 'button transition-all is-flex is-align-items-centered rounded-sm is-uppercase', + 'm-0 p-0', + 'has-background-yellow', + { 'is-enabled': enabled }, + { 'is-disabled': !enabled }, { [classNames]: !!classNames } ); return ( -
); } diff --git a/frontend/packages/client/src/components/CommunityCreate/StepThree.js b/frontend/packages/client/src/components/CommunityCreate/StepThree.js index bec7e6922..cbe34af78 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepThree.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepThree.js @@ -34,7 +34,7 @@ export default function StepThree({ }, [stepData, setStepValid]); return ( <> -
+

From 0bfaa72355fb9416f9c510f29c89300a502b9cc4 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Sat, 25 Jun 2022 22:11:55 -0300 Subject: [PATCH 46/59] fix dep --- .../client/src/components/Community/StrategySelectorForm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/packages/client/src/components/Community/StrategySelectorForm.js b/frontend/packages/client/src/components/Community/StrategySelectorForm.js index 80bad4492..8574bf13c 100644 --- a/frontend/packages/client/src/components/Community/StrategySelectorForm.js +++ b/frontend/packages/client/src/components/Community/StrategySelectorForm.js @@ -70,7 +70,7 @@ export default function StrategySelectorForm({ // notify parent component useEffect(() => { onStrategySelection(strategies); - }, [strategies]); + }, [strategies, onStrategySelection]); const { data: allVotingStrategies, loading: loadingAllStrategies } = useVotingStrategies(); From 0d27df211c3a27ef74d5b519842d0d4e0ddf23b1 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Mon, 27 Jun 2022 10:42:07 -0300 Subject: [PATCH 47/59] update onStrategySelection callback call --- .../src/components/Community/StrategySelectorForm.js | 11 +++++++---- frontend/packages/client/src/hooks/useCommunity.js | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/frontend/packages/client/src/components/Community/StrategySelectorForm.js b/frontend/packages/client/src/components/Community/StrategySelectorForm.js index 8574bf13c..f1d404982 100644 --- a/frontend/packages/client/src/components/Community/StrategySelectorForm.js +++ b/frontend/packages/client/src/components/Community/StrategySelectorForm.js @@ -4,6 +4,7 @@ import { AddButton } from 'components'; import { Bin } from 'components/Svg'; import { useModalContext } from 'contexts/NotificationModal'; import StrategyEditorModal from './StrategyEditorModal'; +import isEqual from 'lodash/isEqual'; import { kebabToString } from 'utils'; const StrategyInput = ({ @@ -57,7 +58,7 @@ export default function StrategySelectorForm({ // this fc returns a component(Button) to render callToAction = () => {}, // callback to return strategies selected - onStrategySelection = () => {}, + onStrategySelection, } = {}) { // holds array of objects with strategy information const [strategies, setStrategies] = useState([]); @@ -67,10 +68,12 @@ export default function StrategySelectorForm({ setStrategies(existingStrategies); }, [existingStrategies]); - // notify parent component + // only notify parent component if callback was passed useEffect(() => { - onStrategySelection(strategies); - }, [strategies, onStrategySelection]); + if (onStrategySelection && !isEqual(strategies, existingStrategies)) { + onStrategySelection(strategies); + } + }, [strategies, onStrategySelection, existingStrategies]); const { data: allVotingStrategies, loading: loadingAllStrategies } = useVotingStrategies(); diff --git a/frontend/packages/client/src/hooks/useCommunity.js b/frontend/packages/client/src/hooks/useCommunity.js index 1f55828c4..3c0f2d681 100644 --- a/frontend/packages/client/src/hooks/useCommunity.js +++ b/frontend/packages/client/src/hooks/useCommunity.js @@ -80,6 +80,7 @@ export default function useCommunity() { contractName, storagePath, onlyAuthorsToSubmitProposals, + strategies, } = communityData; let communityLogo; @@ -118,6 +119,7 @@ export default function useCommunity() { contractName, storagePath, onlyAuthorsToSubmitProposals: Boolean(onlyAuthorsToSubmitProposals), + strategies, timestamp, compositeSignatures, }), From ec9d9e3053f4fc7b1e2a33f18b8626330a2d175e Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 12:03:29 -0300 Subject: [PATCH 48/59] add config for strategies --- frontend/packages/client/src/networks.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/frontend/packages/client/src/networks.js b/frontend/packages/client/src/networks.js index 677c3d9f8..620eacdfb 100644 --- a/frontend/packages/client/src/networks.js +++ b/frontend/packages/client/src/networks.js @@ -4,14 +4,35 @@ const networksConfig = { walletDiscovery: process.env.REACT_APP_EMULATOR_WALLET_DISCOVERY || 'http://localhost:8701/fcl/authn', + strategiesConfig: { + 'one-address-one-vote': { + name: 'FlowToken', + addr: '0x0ae53cb6e3f42a79', + publicPath: 'flowTokenBalance', + }, + }, }, testnet: { accessApi: 'https://access-testnet.onflow.org', walletDiscovery: 'https://fcl-discovery.onflow.org/testnet/authn', + strategiesConfig: { + 'one-address-one-vote': { + name: 'FlowToken', + addr: '0x7e60df042a9c0868', + publicPath: 'flowTokenBalance', + }, + }, }, mainnet: { accessApi: 'https://mainnet.onflow.org', walletDiscovery: 'https://fcl-discovery.onflow.org/authn', + strategiesConfig: { + 'one-address-one-vote': { + name: 'FlowToken', + addr: '0x1654653399040a61', + publicPath: 'flowTokenBalance', + }, + }, }, }; From 40a93688eae4a85066e113eca3640c49dfdc7b57 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 12:04:44 -0300 Subject: [PATCH 49/59] update payload --- .../Community/CommunityPropsAndVoting.js | 7 +---- .../Community/StrategyEditorModal/index.js | 26 ++++++++++++++----- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index e31ca31af..58c717212 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -42,12 +42,7 @@ export default function CommunityProposalsAndVoting({ .filter((st) => st?.toDelete !== true) .map((st) => ({ name: st.name, - // only other strategies than 'one-address-one-vote' have contract information - ...(st.name !== 'one-address-one-vote' - ? { - contract: mapFieldsForBackend(st.contract), - } - : undefined), + contract: mapFieldsForBackend(st.contract), })); await updateCommunity({ strategies: updatePayload, diff --git a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js index 36409b047..7f849951e 100644 --- a/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js +++ b/frontend/packages/client/src/components/Community/StrategyEditorModal/index.js @@ -1,9 +1,12 @@ import React, { useEffect, useState } from 'react'; +import networks from 'networks'; import StrategySelector from './StrategySelector'; import StrategyInformationForm from './StrategyInformationForm'; import { ActionButton } from 'components'; import { isValidAddress } from 'utils'; +const networkConfig = networks[process.env.REACT_APP_FLOW_ENV]; + const ModalSteps = { 1: 'select-strategy', 2: 'strategy-information', @@ -56,18 +59,27 @@ export default function StrategyEditorModal({ // user selected strategy move to second step to enter information const setStrategy = (strategyName) => { - setStrategyData((state) => ({ ...state, name: strategyName })); - // - // Very important!!! + // STRATEGY CONFIGURATION + // // If strategy selected is 'one-address-one-vote' - // then no more information is required - // modal should be closed and - // strategy should be ready to be added + // then no more information is required(FE uses strategy configuration) + // modal should be closed and strategy should be ready to be added if (strategyName === 'one-address-one-vote') { - onDone({ name: strategyName }); + const strategyConfig = + networkConfig.strategiesConfig['one-address-one-vote']; + onDone({ + name: strategyName, + contract: { + contractName: strategyConfig.name, + contractAddress: strategyConfig.addr, + publicPath: strategyConfig.publicPath, + minimunBalance: '0', + }, + }); return; } + setStrategyData((state) => ({ ...state, name: strategyName })); // else go to second step setSep(ModalSteps[2]); }; From 6acbb9bede4d57d62695232ea2d5ccb3022c0bf9 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 12:36:44 -0300 Subject: [PATCH 50/59] update mapping function --- .../src/components/Community/CommunityPropsAndVoting.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index 58c717212..1daae684d 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -14,7 +14,7 @@ const fieldMapPayload = { publicPath: 'publicPath', }; -// this function renames fields to prepare payload for backend +// this function renames fields if necessary to prepare payload for backend const mapFieldsForBackend = (contract) => { return Object.assign( {}, @@ -23,6 +23,8 @@ const mapFieldsForBackend = (contract) => { ? { [fieldMapPayload[key]]: value, } + : value + ? { [key]: value } : undefined), })) ); From 14e0929f0495ed64a87f27dfe94aaf8073253c72 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 13:13:23 -0300 Subject: [PATCH 51/59] remove output --- .../client/src/components/Community/hooks/useLinkValidator.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frontend/packages/client/src/components/Community/hooks/useLinkValidator.js b/frontend/packages/client/src/components/Community/hooks/useLinkValidator.js index 1d5a79f10..b5d61b25a 100644 --- a/frontend/packages/client/src/components/Community/hooks/useLinkValidator.js +++ b/frontend/packages/client/src/components/Community/hooks/useLinkValidator.js @@ -86,10 +86,6 @@ export default function useLinkValidator({ links, initialValues }) { // chech if object fields has changed from original one const hasChanged = !isEqual(linksObjUpdated, initialProps); - console.log('initialProps ->', initialProps); - console.log('hasChanged', hasChanged); - console.log('linksObjUpdated', linksObjUpdated); - if (isValid !== baseValidation || hasChangedFromOriginal !== hasChanged) { setValidations({ isValid: baseValidation, From 38b8d6bd42e1bb1877afd6f51b87de647267f4c1 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 13:28:58 -0300 Subject: [PATCH 52/59] export and import helper function --- .../Community/CommunityPropsAndVoting.js | 4 +- .../components/CommunityCreate/StepFour.js | 38 ++++++++++--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js index e31ca31af..db4775187 100644 --- a/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js +++ b/frontend/packages/client/src/components/Community/CommunityPropsAndVoting.js @@ -14,8 +14,8 @@ const fieldMapPayload = { publicPath: 'publicPath', }; -// this function renames fields to prepare payload for backend -const mapFieldsForBackend = (contract) => { +// this function renames fields if necessary to prepare payload for backend +export const mapFieldsForBackend = (contract) => { return Object.assign( {}, ...Object.entries(contract).map(([key, value]) => ({ diff --git a/frontend/packages/client/src/components/CommunityCreate/StepFour.js b/frontend/packages/client/src/components/CommunityCreate/StepFour.js index 6ca4c39d1..36463f12d 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepFour.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepFour.js @@ -1,6 +1,7 @@ import React from 'react'; import StrategySelectorForm from 'components/Community/StrategySelectorForm'; import ActionButton from 'components/ActionButton'; +import { mapFieldsForBackend } from '../Community/CommunityPropsAndVoting'; export default function StepFour({ stepData, @@ -17,25 +18,28 @@ export default function StepFour({ } else { setStepValid(false); } - onDataChange({ strategies }); + onDataChange({ + strategies: strategies.map((st) => ({ + name: st.name, + contract: mapFieldsForBackend(st.contract), + })), + }); }; return ( -
- { - return ( - onSubmit() : () => {}} - classNames="mt-5" - /> - ); - }} - /> -
+ { + return ( + onSubmit() : () => {}} + classNames="mt-5" + /> + ); + }} + /> ); } From 42cb55b421e2f77ba50a38a043cd58e274b93340 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Wed, 29 Jun 2022 15:10:04 -0300 Subject: [PATCH 53/59] update data --- .../client/src/components/CommunityCreate/StepFour.js | 8 +------- frontend/packages/client/src/pages/CommunityCreate.js | 7 +++++++ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/packages/client/src/components/CommunityCreate/StepFour.js b/frontend/packages/client/src/components/CommunityCreate/StepFour.js index 36463f12d..008e1a231 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepFour.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepFour.js @@ -1,7 +1,6 @@ import React from 'react'; import StrategySelectorForm from 'components/Community/StrategySelectorForm'; import ActionButton from 'components/ActionButton'; -import { mapFieldsForBackend } from '../Community/CommunityPropsAndVoting'; export default function StepFour({ stepData, @@ -18,12 +17,7 @@ export default function StepFour({ } else { setStepValid(false); } - onDataChange({ - strategies: strategies.map((st) => ({ - name: st.name, - contract: mapFieldsForBackend(st.contract), - })), - }); + onDataChange({ strategies }); }; return ( diff --git a/frontend/packages/client/src/pages/CommunityCreate.js b/frontend/packages/client/src/pages/CommunityCreate.js index a538156f2..c7b832139 100644 --- a/frontend/packages/client/src/pages/CommunityCreate.js +++ b/frontend/packages/client/src/pages/CommunityCreate.js @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import { StepByStep, WalletConnect, Error } from 'components'; +import { mapFieldsForBackend } from 'components/Community/CommunityPropsAndVoting'; import { useWebContext } from 'contexts/Web3'; import { useModalContext } from 'contexts/NotificationModal'; import { @@ -69,6 +70,12 @@ export default function CommunityCreate() { const proposalData = { creatorAddr, ...fields, + ...{ + strategies: fields.strategies.map((st) => ({ + name: st.name, + contract: mapFieldsForBackend(st.contract), + })), + }, slug: generateSlug(), }; From d2be9f48042cb788a4a4ab62d8e09a0d7e95f9a1 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 30 Jun 2022 15:26:05 -0300 Subject: [PATCH 54/59] remove map func --- frontend/packages/client/src/pages/CommunityCreate.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/packages/client/src/pages/CommunityCreate.js b/frontend/packages/client/src/pages/CommunityCreate.js index c7b832139..a538156f2 100644 --- a/frontend/packages/client/src/pages/CommunityCreate.js +++ b/frontend/packages/client/src/pages/CommunityCreate.js @@ -1,7 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import { StepByStep, WalletConnect, Error } from 'components'; -import { mapFieldsForBackend } from 'components/Community/CommunityPropsAndVoting'; import { useWebContext } from 'contexts/Web3'; import { useModalContext } from 'contexts/NotificationModal'; import { @@ -70,12 +69,6 @@ export default function CommunityCreate() { const proposalData = { creatorAddr, ...fields, - ...{ - strategies: fields.strategies.map((st) => ({ - name: st.name, - contract: mapFieldsForBackend(st.contract), - })), - }, slug: generateSlug(), }; From 6e7dbc9530c6e894064b8e32b34785c7ac275d69 Mon Sep 17 00:00:00 2001 From: German Urrustarazu Date: Thu, 30 Jun 2022 15:30:04 -0300 Subject: [PATCH 55/59] revert change removing wrapper --- .../client/src/components/CommunityCreate/StepThree.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/packages/client/src/components/CommunityCreate/StepThree.js b/frontend/packages/client/src/components/CommunityCreate/StepThree.js index cbe34af78..69dabefc4 100644 --- a/frontend/packages/client/src/components/CommunityCreate/StepThree.js +++ b/frontend/packages/client/src/components/CommunityCreate/StepThree.js @@ -1,4 +1,5 @@ import React, { useEffect } from 'react'; +import { WrapperResponsive } from 'components'; import { isValidAddress } from 'utils'; export default function StepThree({ @@ -34,7 +35,11 @@ export default function StepThree({ }, [stepData, setStepValid]); return ( <> -
+

@@ -104,7 +109,7 @@ export default function StepThree({ Allow only authors to submit a proposal

-

+