From 2500da1c240e0bd96ae343ff74e59c55bddd4766 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 30 Jun 2022 14:57:13 -0400 Subject: [PATCH 001/113] Add useProposals and useProposal hooks with mock data --- src/hooks/useProposal.ts | 50 ++++++++++++ src/hooks/useProposals.ts | 165 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 src/hooks/useProposal.ts create mode 100644 src/hooks/useProposals.ts diff --git a/src/hooks/useProposal.ts b/src/hooks/useProposal.ts new file mode 100644 index 0000000000..249d289e65 --- /dev/null +++ b/src/hooks/useProposal.ts @@ -0,0 +1,50 @@ +import { useQuery } from "react-query"; +import { nonNullable } from "src/helpers/types/nonNullable"; + +import { + mockGetNoVotesForProposal, + mockGetProposalContent, + mockGetProposalHasBeenActivated, + mockGetProposalMetadata, + mockGetProposalTotalEndorsements, + mockGetProposalURI, + mockGetYesVotesForProposal, + Proposal, +} from "./useProposals"; + +const proposalQueryKey = (instructionsIndex: number) => ["useProposal", instructionsIndex].filter(nonNullable); + +export const useProposal = (instructionsIndex: number) => { + /// const IPFSDContract = ""; + /// const governanceContract = ""; + + const query = useQuery( + proposalQueryKey(instructionsIndex), + async () => { + const proposal = mockGetProposalMetadata(instructionsIndex); + const isActive = mockGetProposalHasBeenActivated(instructionsIndex); + const endorsements = mockGetProposalTotalEndorsements(instructionsIndex); + const yesVotes = mockGetYesVotesForProposal(instructionsIndex); + const noVotes = mockGetNoVotesForProposal(instructionsIndex); + const proposalURI = mockGetProposalURI(proposal.proposalName); + const proposalContent = mockGetProposalContent(proposalURI); + + const currentProposal = { + proposalName: proposal.proposalName, + proposer: proposal.proposer, + submissionTimestamp: proposal.submissionTimestamp, + isActive: isActive, + endorsements: endorsements, + yesVotes: yesVotes, + noVotes: noVotes, + uri: proposalURI, + content: proposalContent, + }; + + return currentProposal; + }, + { enabled: true }, + ); + + return query as typeof query; +}; diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts new file mode 100644 index 0000000000..9d68f7e540 --- /dev/null +++ b/src/hooks/useProposals.ts @@ -0,0 +1,165 @@ +import { useQuery } from "react-query"; +import { nonNullable } from "src/helpers/types/nonNullable"; + +interface proposalMetadata { + proposalName: string; + proposer: string; + submissionTimestamp: string; +} + +export interface Proposal { + proposalName: string; + proposer: string; + submissionTimestamp: string; + isActive: boolean; + endorsements: number; + yesVotes: number; + noVotes: number; + uri: string; + content: string; +} + +export const mockTotalInstructions = 3; +export const activeProposal = 3; + +export const mockProposalMetadata: { [key: number]: proposalMetadata } = { + 0: { + proposalName: "0x4f49502d310000000000000000000000000000000000000000000000000000", + proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", + submissionTimestamp: "1653948322", + }, + 1: { + proposalName: "0x4f49502d320000000000000000000000000000000000000000000000000000", + proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", + submissionTimestamp: "1655157922", + }, + 2: { + proposalName: "0x4f49502d330000000000000000000000000000000000000000000000000000", + proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", + submissionTimestamp: "1655503522", + }, + 3: { + proposalName: "0x4f49502d340000000000000000000000000000000000000000000000000000", + proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", + submissionTimestamp: "1656626722", + }, +}; + +export const mockProposalTotalEndorsements: { [key: number]: number } = { + 0: 1000, + 1: 50, + 2: 275, + 3: 432, +}; + +export const mockProposalHasBeenActivated: { [key: number]: boolean } = { + 0: true, + 1: false, + 2: true, + 3: true, +}; + +export const mockYesVotesForProposal: { [key: number]: number } = { + 0: 1234, + 1: 0, + 2: 1546, + 3: 2583, +}; + +export const mockNoVotesForProposal: { [key: number]: number } = { + 0: 152, + 1: 0, + 2: 2436, + 3: 1875, +}; + +export const mockProposalURIs: { [key: string]: string } = { + "0x4f49502d310000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberone", + "0x4f49502d320000000000000000000000000000000000000000000000000000": "ipfs://proposalnumbertwo", + "0x4f49502d330000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberthree", + "0x4f49502d340000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberfour", +}; + +export const mockProposalContent: { [key: string]: string } = { + "ipfs://proposalnumberone": "This is OIP-1. The first mock proposal", + "ipfs://proposalnumbertwo": "This is OIP-2. The second mock proposal", + "ipfs://proposalnumberthree": "This is OIP-3. The third mock proposal", + "ipfs://proposalnumberfour": "This is OIP-4. The fourth mock proposal", +}; + +export const mockGetTotalInstructions = (): number => { + return mockTotalInstructions; +}; + +export const mockGetProposalMetadata = (instructionIndex: number) => { + return mockProposalMetadata[instructionIndex]; +}; + +export const mockGetProposalTotalEndorsements = (instructionsIndex: number): number => { + return mockProposalTotalEndorsements[instructionsIndex]; +}; + +export const mockGetProposalHasBeenActivated = (instructionsIndex: number): boolean => { + return mockProposalHasBeenActivated[instructionsIndex]; +}; + +export const mockGetYesVotesForProposal = (instructionsIndex: number): number => { + return mockYesVotesForProposal[instructionsIndex]; +}; + +export const mockGetNoVotesForProposal = (instructionsIndex: number): number => { + return mockNoVotesForProposal[instructionsIndex]; +}; + +export const mockGetProposalURI = (proposalName: string): string => { + return mockProposalURIs[proposalName]; +}; + +export const mockGetProposalContent = (uri: string): string => { + return mockProposalContent[uri]; +}; + +export const proposalsQueryKey = () => ["useProposals"].filter(nonNullable); + +export const useProposals = () => { + /// const INSTRContract = ""; + /// const IPFSDContract = ""; + /// const governanceContract = ""; + + const query = useQuery( + proposalsQueryKey(), + async () => { + const totalInstructions = mockGetTotalInstructions(); + const allProposals: Proposal[] = []; + + for (let i = 0; i < totalInstructions; i++) { + const proposal = mockGetProposalMetadata(i); + const isActive = mockGetProposalHasBeenActivated(i); + const endorsements = mockGetProposalTotalEndorsements(i); + const yesVotes = mockGetYesVotesForProposal(i); + const noVotes = mockGetNoVotesForProposal(i); + const proposalURI = mockGetProposalURI(proposal.proposalName); + const proposalContent = mockGetProposalContent(proposalURI); + + const currentProposal = { + proposalName: proposal.proposalName, + proposer: proposal.proposer, + submissionTimestamp: proposal.submissionTimestamp, + isActive: isActive, + endorsements: endorsements, + yesVotes: yesVotes, + noVotes: noVotes, + uri: proposalURI, + content: proposalContent, + }; + + allProposals.push(currentProposal); + } + + return allProposals; + }, + { enabled: true }, + ); + + return query as typeof query; +}; From d34d77e640dc5344c937ac6460d955fafac5258c Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Fri, 1 Jul 2022 13:11:59 -0400 Subject: [PATCH 002/113] Documentation for useProposals and useProposal --- src/hooks/useProposal.ts | 14 ++++++++++++++ src/hooks/useProposals.ts | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/hooks/useProposal.ts b/src/hooks/useProposal.ts index 249d289e65..74bab67389 100644 --- a/src/hooks/useProposal.ts +++ b/src/hooks/useProposal.ts @@ -1,6 +1,7 @@ import { useQuery } from "react-query"; import { nonNullable } from "src/helpers/types/nonNullable"; +/// Import Proposal data type and mock data getters from useProposals import { mockGetNoVotesForProposal, mockGetProposalContent, @@ -12,8 +13,20 @@ import { Proposal, } from "./useProposals"; +/** + * @notice Query key for useProposal which is dependent on instructionsIndex + * @param instructionsIndex The index number of the proposal to fetch + */ const proposalQueryKey = (instructionsIndex: number) => ["useProposal", instructionsIndex].filter(nonNullable); +/** + * @notice Fetches the metadata, related endorsements, yes votes, and no votes for the proposal + * at the passed index. Uses the proposal metadata to fetch the IPFS URIs containing the + * proposal content. Puts it into a big Proposal object. + * @param instructionsIndex The index number of the proposal to fetch + * @returns Query object in which the data attribute holds a Proposal object for the proposal at + * relevant index + */ export const useProposal = (instructionsIndex: number) => { /// const IPFSDContract = ""; /// const governanceContract = ""; @@ -21,6 +34,7 @@ export const useProposal = (instructionsIndex: number) => { const query = useQuery( proposalQueryKey(instructionsIndex), async () => { + /// For the specified proposal index, fetch the relevant data points used in the frontend const proposal = mockGetProposalMetadata(instructionsIndex); const isActive = mockGetProposalHasBeenActivated(instructionsIndex); const endorsements = mockGetProposalTotalEndorsements(instructionsIndex); diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index 9d68f7e540..913731e9eb 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -1,12 +1,14 @@ import { useQuery } from "react-query"; import { nonNullable } from "src/helpers/types/nonNullable"; +/// Data type for return from getProposalMetadata on Governance.sol interface proposalMetadata { proposalName: string; proposer: string; submissionTimestamp: string; } +/// Data type for returning full proposal informations export interface Proposal { proposalName: string; proposer: string; @@ -19,9 +21,13 @@ export interface Proposal { content: string; } +/// Mock totalInstructions value from INSTR.sol export const mockTotalInstructions = 3; + +/// Mock instructions ID for current active proposal export const activeProposal = 3; +/// Mock mapping data for proposalMetadata in Governance.sol export const mockProposalMetadata: { [key: number]: proposalMetadata } = { 0: { proposalName: "0x4f49502d310000000000000000000000000000000000000000000000000000", @@ -45,6 +51,7 @@ export const mockProposalMetadata: { [key: number]: proposalMetadata } = { }, }; +/// Mock mapping data on total endorsements in Governance.sol export const mockProposalTotalEndorsements: { [key: number]: number } = { 0: 1000, 1: 50, @@ -52,6 +59,7 @@ export const mockProposalTotalEndorsements: { [key: number]: number } = { 3: 432, }; +/// Mock mapping data on proposal activation in Governance.sol export const mockProposalHasBeenActivated: { [key: number]: boolean } = { 0: true, 1: false, @@ -59,6 +67,7 @@ export const mockProposalHasBeenActivated: { [key: number]: boolean } = { 3: true, }; +/// Mock mapping data on proposal yes votes in Governance.sol export const mockYesVotesForProposal: { [key: number]: number } = { 0: 1234, 1: 0, @@ -66,6 +75,7 @@ export const mockYesVotesForProposal: { [key: number]: number } = { 3: 2583, }; +/// Mock mapping data on proposal no votes in Governance.sol export const mockNoVotesForProposal: { [key: number]: number } = { 0: 152, 1: 0, @@ -73,6 +83,7 @@ export const mockNoVotesForProposal: { [key: number]: number } = { 3: 1875, }; +/// Mock IPFS URI values by proposal bytes32 name export const mockProposalURIs: { [key: string]: string } = { "0x4f49502d310000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberone", "0x4f49502d320000000000000000000000000000000000000000000000000000": "ipfs://proposalnumbertwo", @@ -80,6 +91,7 @@ export const mockProposalURIs: { [key: string]: string } = { "0x4f49502d340000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberfour", }; +/// Mock content stores by IPFS URI export const mockProposalContent: { [key: string]: string } = { "ipfs://proposalnumberone": "This is OIP-1. The first mock proposal", "ipfs://proposalnumbertwo": "This is OIP-2. The second mock proposal", @@ -87,40 +99,59 @@ export const mockProposalContent: { [key: string]: string } = { "ipfs://proposalnumberfour": "This is OIP-4. The fourth mock proposal", }; +/// Function to return mock total instructions in lieu of a contract export const mockGetTotalInstructions = (): number => { return mockTotalInstructions; }; +/// Function to return mock proposal metadata in lieu of a contract export const mockGetProposalMetadata = (instructionIndex: number) => { return mockProposalMetadata[instructionIndex]; }; +/// Function to return mock proposal endoresments in lieu of a contract export const mockGetProposalTotalEndorsements = (instructionsIndex: number): number => { return mockProposalTotalEndorsements[instructionsIndex]; }; +/// Function to return mock proposal activation data in lieu of a contract export const mockGetProposalHasBeenActivated = (instructionsIndex: number): boolean => { return mockProposalHasBeenActivated[instructionsIndex]; }; +/// Function to return mock proposal yes votes in lieu of a contract export const mockGetYesVotesForProposal = (instructionsIndex: number): number => { return mockYesVotesForProposal[instructionsIndex]; }; +/// Function to return mock proposal no votes in lieu of a contract export const mockGetNoVotesForProposal = (instructionsIndex: number): number => { return mockNoVotesForProposal[instructionsIndex]; }; +/// Function to return mock proposal URI in lieu of a contract export const mockGetProposalURI = (proposalName: string): string => { return mockProposalURIs[proposalName]; }; +/// Function to return mock proposal content in lieu of content deployed to IPFS export const mockGetProposalContent = (uri: string): string => { return mockProposalContent[uri]; }; +/** + * Query key for useProposals. Doesn't need to be refreshed on address or network changes + * Proposals should be fetched no matter what. + */ export const proposalsQueryKey = () => ["useProposals"].filter(nonNullable); +/** + * @notice Fetches proposals from Governance policy, the related endorsements, yes votes, + * and no votes. Uses the proposal metadata to fetch the IPFS URIs containing the + * proposal content. Puts it into a big Proposal object. + * @returns Query object in which the data attribute holds an array of Proposal objects for + * all proposals in the Governance policy contract + */ export const useProposals = () => { /// const INSTRContract = ""; /// const IPFSDContract = ""; @@ -129,10 +160,12 @@ export const useProposals = () => { const query = useQuery( proposalsQueryKey(), async () => { - const totalInstructions = mockGetTotalInstructions(); + /// Get total number of proposal through INSTR module contract's totalInstructions variable + const numberOfProposals = mockGetTotalInstructions(); const allProposals: Proposal[] = []; - for (let i = 0; i < totalInstructions; i++) { + /// For each proposal, fetch the relevant data points used in the frontend + for (let i = 0; i < numberOfProposals; i++) { const proposal = mockGetProposalMetadata(i); const isActive = mockGetProposalHasBeenActivated(i); const endorsements = mockGetProposalTotalEndorsements(i); From 28d2fb88ff94f984a3b4b78d1cf83bd0d1dd4c26 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Fri, 1 Jul 2022 13:15:20 -0400 Subject: [PATCH 003/113] Update component-library for governance components --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e0502914f7..f164454de5 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@mui/icons-material": "^5.8.3", "@mui/material": "^5.8.4", "@multifarm/widget": "^0.0.159", - "@olympusdao/component-library": "^2.2.1", + "@olympusdao/component-library": "^2.2.2-gov.0", "@rainbow-me/rainbowkit": "^0.3.7", "@reduxjs/toolkit": "^1.8.2", "@types/material-ui": "^0.21.12", diff --git a/yarn.lock b/yarn.lock index a27e515250..1848cc077d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2795,10 +2795,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@olympusdao/component-library@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@olympusdao/component-library/-/component-library-2.2.1.tgz#ac783b1392999e37512ecddc529c418246ee578a" - integrity sha512-its4KxsiC8wXDZWSKYVnY2Oai9Ai77yaeXP2nsfhIDMzJu8xOtqXSAkCFtTRFEAPtCtI3btMNlJvxjps9e2riw== +"@olympusdao/component-library@^2.2.2-gov.0": + version "2.2.2-gov.0" + resolved "https://registry.yarnpkg.com/@olympusdao/component-library/-/component-library-2.2.2-gov.0.tgz#b5d6d6b8c57ecd53e8431897525c5f45886f9bf0" + integrity sha512-qBsM4RU4rzU6kdnEACfeTMzI7vH7iXeBX469vepbkv39SG1eZ7UEcZeO3XIwDdN4s+eHqc1h2Ssiyi63flO5+w== dependencies: "@react-spring/web" "^9.4.5" From ef8b84ff4af383c5007b14367c80f2b21bd14e2f Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Tue, 5 Jul 2022 14:48:51 -0400 Subject: [PATCH 004/113] Add proposals dashboard, frame of filter modal --- src/App.tsx | 3 + src/hooks/useProposals.ts | 19 ++--- src/views/Governance/Governance.scss | 9 +++ src/views/Governance/ProposalsDashboard.tsx | 74 +++++++++++++++++++ .../components/FilterModal/FilterModal.scss | 0 .../components/FilterModal/FilterModal.tsx | 16 ++++ .../components/FilterModal/index.ts | 1 + .../components/SearchBar/SearchBar.scss | 13 ++++ .../components/SearchBar/SearchBar.tsx | 20 +++++ .../Governance/components/SearchBar/index.ts | 1 + 10 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 src/views/Governance/Governance.scss create mode 100644 src/views/Governance/ProposalsDashboard.tsx create mode 100644 src/views/Governance/components/FilterModal/FilterModal.scss create mode 100644 src/views/Governance/components/FilterModal/FilterModal.tsx create mode 100644 src/views/Governance/components/FilterModal/index.ts create mode 100644 src/views/Governance/components/SearchBar/SearchBar.scss create mode 100644 src/views/Governance/components/SearchBar/SearchBar.tsx create mode 100644 src/views/Governance/components/SearchBar/index.ts diff --git a/src/App.tsx b/src/App.tsx index 8122e1a4d6..a64b963af6 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,6 +38,7 @@ import { dark as darkTheme } from "./themes/dark.js"; import { girth as gTheme } from "./themes/girth.js"; import { light as lightTheme } from "./themes/light.js"; import { multifarmDarkTheme, multifarmLightTheme } from "./themes/multifarm"; +import { ProposalsDashboard } from "./views/Governance/ProposalsDashboard"; // Dynamic Imports for code splitting const Bond = lazy(() => import("./views/Bond")); @@ -273,6 +274,8 @@ function App() { } /> }> } /> + + } /> diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index 913731e9eb..aa4849feb5 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -1,3 +1,4 @@ +import { ethers } from "ethers"; import { useQuery } from "react-query"; import { nonNullable } from "src/helpers/types/nonNullable"; @@ -30,22 +31,22 @@ export const activeProposal = 3; /// Mock mapping data for proposalMetadata in Governance.sol export const mockProposalMetadata: { [key: number]: proposalMetadata } = { 0: { - proposalName: "0x4f49502d310000000000000000000000000000000000000000000000000000", + proposalName: "0x4f49502d31000000000000000000000000000000000000000000000000000000", proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", submissionTimestamp: "1653948322", }, 1: { - proposalName: "0x4f49502d320000000000000000000000000000000000000000000000000000", + proposalName: "0x4f49502d32000000000000000000000000000000000000000000000000000000", proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", submissionTimestamp: "1655157922", }, 2: { - proposalName: "0x4f49502d330000000000000000000000000000000000000000000000000000", + proposalName: "0x4f49502d33000000000000000000000000000000000000000000000000000000", proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", submissionTimestamp: "1655503522", }, 3: { - proposalName: "0x4f49502d340000000000000000000000000000000000000000000000000000", + proposalName: "0x4f49502d34000000000000000000000000000000000000000000000000000000", proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", submissionTimestamp: "1656626722", }, @@ -85,10 +86,10 @@ export const mockNoVotesForProposal: { [key: number]: number } = { /// Mock IPFS URI values by proposal bytes32 name export const mockProposalURIs: { [key: string]: string } = { - "0x4f49502d310000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberone", - "0x4f49502d320000000000000000000000000000000000000000000000000000": "ipfs://proposalnumbertwo", - "0x4f49502d330000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberthree", - "0x4f49502d340000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberfour", + "0x4f49502d31000000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberone", + "0x4f49502d32000000000000000000000000000000000000000000000000000000": "ipfs://proposalnumbertwo", + "0x4f49502d33000000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberthree", + "0x4f49502d34000000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberfour", }; /// Mock content stores by IPFS URI @@ -175,7 +176,7 @@ export const useProposals = () => { const proposalContent = mockGetProposalContent(proposalURI); const currentProposal = { - proposalName: proposal.proposalName, + proposalName: ethers.utils.parseBytes32String(proposal.proposalName), proposer: proposal.proposer, submissionTimestamp: proposal.submissionTimestamp, isActive: isActive, diff --git a/src/views/Governance/Governance.scss b/src/views/Governance/Governance.scss new file mode 100644 index 0000000000..67ecd8885d --- /dev/null +++ b/src/views/Governance/Governance.scss @@ -0,0 +1,9 @@ +.proposals-dash { + width: 100%; + display: flex; + justify-content: center; + + .dashboard-actions { + margin-bottom: 25px; + } +} diff --git a/src/views/Governance/ProposalsDashboard.tsx b/src/views/Governance/ProposalsDashboard.tsx new file mode 100644 index 0000000000..624ca80226 --- /dev/null +++ b/src/views/Governance/ProposalsDashboard.tsx @@ -0,0 +1,74 @@ +import "./Governance.scss"; + +import { t } from "@lingui/macro"; +import { Grid, Link } from "@mui/material"; +import { Paper, Proposal, SecondaryButton } from "@olympusdao/component-library"; +import { useMemo, useState } from "react"; +import { Link as RouterLink } from "react-router-dom"; +import { Proposal as ProposalType, useProposals } from "src/hooks/useProposals"; + +import { FilterModal } from "./components/FilterModal"; +import { SearchBar } from "./components/SearchBar/SearchBar"; + +export const ProposalsDashboard = () => { + const [isFilterModalOpen, setIsFilterModalOpen] = useState(false); + + const _useProposals = useProposals(); + const allProposalsData: ProposalType[] = useMemo(() => { + if (_useProposals.isLoading || !_useProposals.data) return []; + return _useProposals.data; + }, [_useProposals]); + + const handleFilterClick = () => { + setIsFilterModalOpen(true); + }; + + const handleFilterModalCancel = () => { + setIsFilterModalOpen(false); + }; + + const renderProposals = () => { + return allProposalsData.map(proposal => { + return ( + + + + + + ); + }); + }; + + return ( +
+ + + + Filter + + + + + {renderProposals()} + + + + +
+ ); +}; diff --git a/src/views/Governance/components/FilterModal/FilterModal.scss b/src/views/Governance/components/FilterModal/FilterModal.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/views/Governance/components/FilterModal/FilterModal.tsx b/src/views/Governance/components/FilterModal/FilterModal.tsx new file mode 100644 index 0000000000..37a60f2e93 --- /dev/null +++ b/src/views/Governance/components/FilterModal/FilterModal.tsx @@ -0,0 +1,16 @@ +import { Typography } from "@mui/material"; +import { Modal } from "@olympusdao/component-library"; +import { CancelCallback } from "src/views/Give/Interfaces"; + +type FilterModalProps = { + isModalOpen: boolean; + cancelFunc: CancelCallback; +}; + +export const FilterModal = ({ isModalOpen, cancelFunc }: FilterModalProps) => { + return ( + + Filter Modal + + ); +}; diff --git a/src/views/Governance/components/FilterModal/index.ts b/src/views/Governance/components/FilterModal/index.ts new file mode 100644 index 0000000000..65b7f68c0a --- /dev/null +++ b/src/views/Governance/components/FilterModal/index.ts @@ -0,0 +1 @@ +export { FilterModal } from "./FilterModal"; diff --git a/src/views/Governance/components/SearchBar/SearchBar.scss b/src/views/Governance/components/SearchBar/SearchBar.scss new file mode 100644 index 0000000000..a374c33171 --- /dev/null +++ b/src/views/Governance/components/SearchBar/SearchBar.scss @@ -0,0 +1,13 @@ +.search-bar { + display: flex; + justify-content: flex-end; + + .search-input { + width: 100%; + color: #bbbdc0; + + .MuiSvgIcon-root { + fill: #bbbdc0; + } + } +} diff --git a/src/views/Governance/components/SearchBar/SearchBar.tsx b/src/views/Governance/components/SearchBar/SearchBar.tsx new file mode 100644 index 0000000000..d247d97b17 --- /dev/null +++ b/src/views/Governance/components/SearchBar/SearchBar.tsx @@ -0,0 +1,20 @@ +import "./SearchBar.scss"; + +import SearchIcon from "@mui/icons-material/Search"; +import { Grid, InputAdornment, OutlinedInput } from "@mui/material"; + +export const SearchBar = () => { + return ( + + + + + } + placeholder="Search proposal" + /> + + ); +}; diff --git a/src/views/Governance/components/SearchBar/index.ts b/src/views/Governance/components/SearchBar/index.ts new file mode 100644 index 0000000000..5932700db5 --- /dev/null +++ b/src/views/Governance/components/SearchBar/index.ts @@ -0,0 +1 @@ +export { SearchBar } from "./SearchBar"; From 84d9befe0b57ba0e6047ac09ecaa8800226bd649 Mon Sep 17 00:00:00 2001 From: appleseed-iii Date: Thu, 7 Jul 2022 13:30:22 -0500 Subject: [PATCH 005/113] remove childPaperBackground compile issue --- src/views/Give/Give.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/Give/Give.tsx b/src/views/Give/Give.tsx index 10d8f33657..86ce00eba8 100644 --- a/src/views/Give/Give.tsx +++ b/src/views/Give/Give.tsx @@ -47,7 +47,7 @@ function Give({ selectedIndex = 0 }) { Date: Thu, 7 Jul 2022 15:47:27 -0500 Subject: [PATCH 006/113] mocked up modal --- .../components/FilterModal/FilterModal.tsx | 87 ++++++++++++++++++- 1 file changed, 84 insertions(+), 3 deletions(-) diff --git a/src/views/Governance/components/FilterModal/FilterModal.tsx b/src/views/Governance/components/FilterModal/FilterModal.tsx index 37a60f2e93..a5e2e56dee 100644 --- a/src/views/Governance/components/FilterModal/FilterModal.tsx +++ b/src/views/Governance/components/FilterModal/FilterModal.tsx @@ -1,5 +1,8 @@ -import { Typography } from "@mui/material"; -import { Modal } from "@olympusdao/component-library"; +import { t } from "@lingui/macro"; +import { CheckBoxOutlineBlank, CheckBoxOutlined } from "@mui/icons-material"; +import { Box, Checkbox, FormControlLabel } from "@mui/material"; +import { Modal, PrimaryButton, SecondaryButton } from "@olympusdao/component-library"; +import { useState } from "react"; import { CancelCallback } from "src/views/Give/Interfaces"; type FilterModalProps = { @@ -8,9 +11,87 @@ type FilterModalProps = { }; export const FilterModal = ({ isModalOpen, cancelFunc }: FilterModalProps) => { + const [checkedActive, setCheckedActive] = useState(false); + const [checkedEndorsements, setCheckedEndorsements] = useState(false); + const [checkedDiscussions, setCheckedDiscussions] = useState(false); + const [checkedDraft, setCheckedDraft] = useState(false); + const [checkedClosed, setCheckedClosed] = useState(false); + return ( - Filter Modal + <> + + setCheckedActive(event.target.checked)} + icon={} + checkedIcon={} + /> + } + label={t`Active`} + /> + + + setCheckedEndorsements(event.target.checked)} + icon={} + checkedIcon={} + /> + } + label={t`Endorsements`} + /> + + + setCheckedDiscussions(event.target.checked)} + icon={} + checkedIcon={} + /> + } + label={t`Discussions`} + /> + + + setCheckedDraft(event.target.checked)} + icon={} + checkedIcon={} + /> + } + label={t`Draft`} + /> + + + setCheckedClosed(event.target.checked)} + icon={} + checkedIcon={} + /> + } + label={t`Closed`} + /> + + + + Cancel + + Save + + ); }; From faffeab7d209d3333989ee07da448721b801dd56 Mon Sep 17 00:00:00 2001 From: appleseed-iii Date: Tue, 12 Jul 2022 12:51:21 -0500 Subject: [PATCH 007/113] wip - filtration work in progress --- src/hooks/useProposals.ts | 19 ++++++++++++++----- src/views/Governance/ProposalsDashboard.tsx | 2 +- .../components/FilterModal/FilterModal.tsx | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index aa4849feb5..afcaefbbd9 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -144,7 +144,13 @@ export const mockGetProposalContent = (uri: string): string => { * Query key for useProposals. Doesn't need to be refreshed on address or network changes * Proposals should be fetched no matter what. */ -export const proposalsQueryKey = () => ["useProposals"].filter(nonNullable); +export const proposalsQueryKey = (filters: { isActive?: boolean }) => { + if (filters) { + return ["useProposals", filters].filter(nonNullable); + } else { + return ["useProposals"].filter(nonNullable); + } +}; /** * @notice Fetches proposals from Governance policy, the related endorsements, yes votes, @@ -153,13 +159,13 @@ export const proposalsQueryKey = () => ["useProposals"].filter(nonNullable); * @returns Query object in which the data attribute holds an array of Proposal objects for * all proposals in the Governance policy contract */ -export const useProposals = () => { +export const useProposals = (filters: { isActive?: boolean }) => { /// const INSTRContract = ""; /// const IPFSDContract = ""; /// const governanceContract = ""; const query = useQuery( - proposalsQueryKey(), + proposalsQueryKey(filters), async () => { /// Get total number of proposal through INSTR module contract's totalInstructions variable const numberOfProposals = mockGetTotalInstructions(); @@ -189,8 +195,11 @@ export const useProposals = () => { allProposals.push(currentProposal); } - - return allProposals; + if (filters) { + return allProposals.filter(proposal => proposal.isActive === filters.isActive); + } else { + return allProposals; + } }, { enabled: true }, ); diff --git a/src/views/Governance/ProposalsDashboard.tsx b/src/views/Governance/ProposalsDashboard.tsx index 624ca80226..da6aa3d468 100644 --- a/src/views/Governance/ProposalsDashboard.tsx +++ b/src/views/Governance/ProposalsDashboard.tsx @@ -13,7 +13,7 @@ import { SearchBar } from "./components/SearchBar/SearchBar"; export const ProposalsDashboard = () => { const [isFilterModalOpen, setIsFilterModalOpen] = useState(false); - const _useProposals = useProposals(); + const _useProposals = useProposals({ isActive: false }); const allProposalsData: ProposalType[] = useMemo(() => { if (_useProposals.isLoading || !_useProposals.data) return []; return _useProposals.data; diff --git a/src/views/Governance/components/FilterModal/FilterModal.tsx b/src/views/Governance/components/FilterModal/FilterModal.tsx index a5e2e56dee..6e401f440d 100644 --- a/src/views/Governance/components/FilterModal/FilterModal.tsx +++ b/src/views/Governance/components/FilterModal/FilterModal.tsx @@ -85,7 +85,7 @@ export const FilterModal = ({ isModalOpen, cancelFunc }: FilterModalProps) => { label={t`Closed`} /> - + Cancel From c73c5399d003a71a329462a995ce15c677501c4d Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Wed, 13 Jul 2022 14:27:21 -0400 Subject: [PATCH 008/113] Set up proposal page routing and frame proposal page component --- src/App.tsx | 4 +- src/hooks/useProposal.ts | 4 +- src/hooks/useProposals.ts | 2 + src/views/Governance/Governance.tsx | 15 +++++ src/views/Governance/ProposalsDashboard.tsx | 2 +- .../components/ProposalPage/ProposalPage.scss | 5 ++ .../components/ProposalPage/ProposalPage.tsx | 61 +++++++++++++++++++ .../components/ProposalPage/index.ts | 1 + src/views/Governance/constants.ts | 14 +++++ 9 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 src/views/Governance/Governance.tsx create mode 100644 src/views/Governance/components/ProposalPage/ProposalPage.scss create mode 100644 src/views/Governance/components/ProposalPage/ProposalPage.tsx create mode 100644 src/views/Governance/components/ProposalPage/index.ts create mode 100644 src/views/Governance/constants.ts diff --git a/src/App.tsx b/src/App.tsx index 55aa5dac48..63b27ea632 100755 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,7 +38,7 @@ import { dark as darkTheme } from "./themes/dark.js"; import { girth as gTheme } from "./themes/girth.js"; import { light as lightTheme } from "./themes/light.js"; import { multifarmDarkTheme, multifarmLightTheme } from "./themes/multifarm"; -import { ProposalsDashboard } from "./views/Governance/ProposalsDashboard"; +import { Governance } from "./views/Governance/Governance"; // Dynamic Imports for code splitting const Bond = lazy(() => import("./views/Bond")); @@ -274,7 +274,7 @@ function App() { }> } /> - } /> + } /> diff --git a/src/hooks/useProposal.ts b/src/hooks/useProposal.ts index 74bab67389..b1a8a1f286 100644 --- a/src/hooks/useProposal.ts +++ b/src/hooks/useProposal.ts @@ -1,3 +1,4 @@ +import { ethers } from "ethers"; import { useQuery } from "react-query"; import { nonNullable } from "src/helpers/types/nonNullable"; @@ -44,7 +45,8 @@ export const useProposal = (instructionsIndex: number) => { const proposalContent = mockGetProposalContent(proposalURI); const currentProposal = { - proposalName: proposal.proposalName, + id: instructionsIndex, + proposalName: ethers.utils.parseBytes32String(proposal.proposalName), proposer: proposal.proposer, submissionTimestamp: proposal.submissionTimestamp, isActive: isActive, diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index afcaefbbd9..5b0c3d25a4 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -11,6 +11,7 @@ interface proposalMetadata { /// Data type for returning full proposal informations export interface Proposal { + id: number; proposalName: string; proposer: string; submissionTimestamp: string; @@ -182,6 +183,7 @@ export const useProposals = (filters: { isActive?: boolean }) => { const proposalContent = mockGetProposalContent(proposalURI); const currentProposal = { + id: i, proposalName: ethers.utils.parseBytes32String(proposal.proposalName), proposer: proposal.proposer, submissionTimestamp: proposal.submissionTimestamp, diff --git a/src/views/Governance/Governance.tsx b/src/views/Governance/Governance.tsx new file mode 100644 index 0000000000..52a0e123aa --- /dev/null +++ b/src/views/Governance/Governance.tsx @@ -0,0 +1,15 @@ +import { Route, Routes } from "react-router-dom"; + +import { ProposalPage } from "./components/ProposalPage"; +import { ProposalsDashboard } from "./ProposalsDashboard"; + +export const Governance = () => { + return ( + <> + + } /> + } /> + + + ); +}; diff --git a/src/views/Governance/ProposalsDashboard.tsx b/src/views/Governance/ProposalsDashboard.tsx index da6aa3d468..958e0b639b 100644 --- a/src/views/Governance/ProposalsDashboard.tsx +++ b/src/views/Governance/ProposalsDashboard.tsx @@ -31,7 +31,7 @@ export const ProposalsDashboard = () => { return allProposalsData.map(proposal => { return ( - + { + const { passedId } = useParams(); + const proposalId = useMemo(() => { + if (!passedId) return -1; + return parseInt(passedId); + }, [passedId]); + + const _useProposal = useProposal(proposalId); + const proposal: ProposalType = useMemo(() => { + if (_useProposal.isLoading || !_useProposal.data) return NULL_PROPOSAL; + return _useProposal.data; + }, [_useProposal]); + + return ( +
+ + + + + Back + + + Create new proposal + + + + + + Posted on {proposal.submissionTimestamp} by {proposal.proposer} + + + + {proposal.proposalName} + + + {proposal.isActive} + + + + + + + + + + +
+ ); +}; diff --git a/src/views/Governance/components/ProposalPage/index.ts b/src/views/Governance/components/ProposalPage/index.ts new file mode 100644 index 0000000000..3ddad00079 --- /dev/null +++ b/src/views/Governance/components/ProposalPage/index.ts @@ -0,0 +1 @@ +export { ProposalPage } from "./ProposalPage"; diff --git a/src/views/Governance/constants.ts b/src/views/Governance/constants.ts new file mode 100644 index 0000000000..97072ec133 --- /dev/null +++ b/src/views/Governance/constants.ts @@ -0,0 +1,14 @@ +import { Proposal } from "src/hooks/useProposals"; + +export const NULL_PROPOSAL: Proposal = { + id: -1, + proposalName: "", + proposer: "", + submissionTimestamp: "", + isActive: false, + endorsements: 0, + yesVotes: 0, + noVotes: 0, + uri: "", + content: "", +}; From 5ee1368857a7250020562687a355c71fec81b846 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Wed, 13 Jul 2022 21:22:28 -0400 Subject: [PATCH 009/113] Modified alignment --- src/hooks/useProposals.ts | 12 ++--- .../components/ProposalPage/ProposalPage.scss | 25 +++++++++++ .../components/ProposalPage/ProposalPage.tsx | 44 ++++++++++++++++--- src/views/Governance/constants.ts | 2 +- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index 5b0c3d25a4..3c87ca9d5b 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -6,7 +6,7 @@ import { nonNullable } from "src/helpers/types/nonNullable"; interface proposalMetadata { proposalName: string; proposer: string; - submissionTimestamp: string; + submissionTimestamp: number; } /// Data type for returning full proposal informations @@ -14,7 +14,7 @@ export interface Proposal { id: number; proposalName: string; proposer: string; - submissionTimestamp: string; + submissionTimestamp: number; isActive: boolean; endorsements: number; yesVotes: number; @@ -34,22 +34,22 @@ export const mockProposalMetadata: { [key: number]: proposalMetadata } = { 0: { proposalName: "0x4f49502d31000000000000000000000000000000000000000000000000000000", proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", - submissionTimestamp: "1653948322", + submissionTimestamp: 1653948322, }, 1: { proposalName: "0x4f49502d32000000000000000000000000000000000000000000000000000000", proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", - submissionTimestamp: "1655157922", + submissionTimestamp: 1655157922, }, 2: { proposalName: "0x4f49502d33000000000000000000000000000000000000000000000000000000", proposer: "0x6e36b2f9f2BcC273f090ff049952Fa4B5Cc67567", - submissionTimestamp: "1655503522", + submissionTimestamp: 1655503522, }, 3: { proposalName: "0x4f49502d34000000000000000000000000000000000000000000000000000000", proposer: "0x0adfA199aB9485CE53859CD237836bFE6019F5Fa", - submissionTimestamp: "1656626722", + submissionTimestamp: 1656626722, }, }; diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.scss b/src/views/Governance/components/ProposalPage/ProposalPage.scss index 887c8931dc..13242a14b8 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.scss +++ b/src/views/Governance/components/ProposalPage/ProposalPage.scss @@ -2,4 +2,29 @@ width: 100%; display: flex; justify-content: center; + + .page-content { + .back-button { + display: flex; + justify-content: flex-start; + + .MuiButton-root { + margin-left: 0px; + padding-left: 0px; + } + } + } + + .published-date { + margin-top: 6px; + line-height: 18px; + } + + .proposal-title { + font-weight: 700; + } + + #simple-tab-0 { + margin-left: 0px; + } } diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index 3c6179ed1d..18b478c83b 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,16 +1,19 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; -import { Grid, Typography } from "@mui/material"; -import { Paper, Tab, Tabs, TertiaryButton, TextButton } from "@olympusdao/component-library"; +import { Grid, Typography, useTheme } from "@mui/material"; +import { Chip, OHMChipProps, Paper, Tab, Tabs, TertiaryButton, TextButton } from "@olympusdao/component-library"; import { useMemo } from "react"; import { useParams } from "react-router-dom"; +import { shorten } from "src/helpers"; import { useProposal } from "src/hooks/useProposal"; import { Proposal as ProposalType } from "src/hooks/useProposals"; import { NULL_PROPOSAL } from "../../constants"; export const ProposalPage = () => { + const theme = useTheme(); + const { passedId } = useParams(); const proposalId = useMemo(() => { if (!passedId) return -1; @@ -23,12 +26,37 @@ export const ProposalPage = () => { return _useProposal.data; }, [_useProposal]); + const dateFormat = new Intl.DateTimeFormat([], { + month: "short", + day: "numeric", + year: "numeric", + timeZoneName: "short", + hour: "numeric", + minute: "numeric", + }); + const formattedPublishedDate = dateFormat.format(proposal.submissionTimestamp); + + const mapStatus = (status: string) => { + switch (status) { + case "active": + return "success" as OHMChipProps["template"]; + case "endorsement": + return "purple" as OHMChipProps["template"]; + case "discussion": + return "userFeedback" as OHMChipProps["template"]; + case "closed": + return "gray" as OHMChipProps["template"]; + case "draft": + return "darkGray" as OHMChipProps["template"]; + } + }; + return (
- + Back @@ -37,15 +65,17 @@ export const ProposalPage = () => { - - Posted on {proposal.submissionTimestamp} by {proposal.proposer} + + Posted on {formattedPublishedDate} by {shorten(proposal.proposer)} - {proposal.proposalName} + + {proposal.proposalName} + - {proposal.isActive} + diff --git a/src/views/Governance/constants.ts b/src/views/Governance/constants.ts index 97072ec133..823a0f420f 100644 --- a/src/views/Governance/constants.ts +++ b/src/views/Governance/constants.ts @@ -4,7 +4,7 @@ export const NULL_PROPOSAL: Proposal = { id: -1, proposalName: "", proposer: "", - submissionTimestamp: "", + submissionTimestamp: 0, isActive: false, endorsements: 0, yesVotes: 0, From bba87d3064a93e1b87783aafd28a407f7d763830 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 14 Jul 2022 09:23:55 -0400 Subject: [PATCH 010/113] Styling and tab functionality --- .../components/ProposalPage/ProposalPage.scss | 33 ++++++++++++ .../components/ProposalPage/ProposalPage.tsx | 51 +++++++++++++++---- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.scss b/src/views/Governance/components/ProposalPage/ProposalPage.scss index 13242a14b8..d277ab604f 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.scss +++ b/src/views/Governance/components/ProposalPage/ProposalPage.scss @@ -4,6 +4,10 @@ justify-content: center; .page-content { + .navigation { + margin-bottom: 30px; + } + .back-button { display: flex; justify-content: flex-start; @@ -12,19 +16,48 @@ margin-left: 0px; padding-left: 0px; } + + .css-ihuj2u-MuiTypography-root-MuiLink-root.active { + text-decoration: none; + } } } + .proposal-header { + margin-bottom: 36px; + } + .published-date { margin-top: 6px; + margin-bottom: 4px; line-height: 18px; } .proposal-title { + line-height: 32px; font-weight: 700; } #simple-tab-0 { margin-left: 0px; } + + #simple-tabpanel-0 { + .MuiBox-root { + padding-left: 0px; + } + } + + #simple-tabpanel-1 { + .MuiBox-root { + padding-left: 0px; + } + } + + .discussion-button { + .MuiButton-root { + margin-left: 0px; + padding-left: 0px; + } + } } diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index 18b478c83b..a2fa704345 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,10 +1,19 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; -import { Grid, Typography, useTheme } from "@mui/material"; -import { Chip, OHMChipProps, Paper, Tab, Tabs, TertiaryButton, TextButton } from "@olympusdao/component-library"; -import { useMemo } from "react"; -import { useParams } from "react-router-dom"; +import { Grid, Link, Typography, useTheme } from "@mui/material"; +import { + Chip, + OHMChipProps, + Paper, + SecondaryButton, + Tab, + TabPanel, + Tabs, + TextButton, +} from "@olympusdao/component-library"; +import { useMemo, useState } from "react"; +import { NavLink as RouterLink, useParams } from "react-router-dom"; import { shorten } from "src/helpers"; import { useProposal } from "src/hooks/useProposal"; import { Proposal as ProposalType } from "src/hooks/useProposals"; @@ -14,6 +23,8 @@ import { NULL_PROPOSAL } from "../../constants"; export const ProposalPage = () => { const theme = useTheme(); + const [selectedIndex, setSelectedIndex] = useState(0); + const { passedId } = useParams(); const proposalId = useMemo(() => { if (!passedId) return -1; @@ -55,18 +66,21 @@ export const ProposalPage = () => {
- + - Back + + Back + - Create new proposal + Create new proposal - Posted on {formattedPublishedDate} by {shorten(proposal.proposer)} + Posted on {formattedPublishedDate} by:{" "} + {shorten(proposal.proposer)} @@ -78,11 +92,28 @@ export const ProposalPage = () => { - - + + setSelectedIndex(view)} + > + + + + {proposal.content} + + + + Votes will go here + + + + Discussion From f78a3505c8130f31484bd708626250697cf62c68 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 14 Jul 2022 09:38:44 -0400 Subject: [PATCH 011/113] Placeholder end date countdown --- .../components/ProposalPage/ProposalPage.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index a2fa704345..fd4b00e880 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,9 +1,10 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; -import { Grid, Link, Typography, useTheme } from "@mui/material"; +import { Box, Grid, Link, Typography, useTheme } from "@mui/material"; import { Chip, + Icon, OHMChipProps, Paper, SecondaryButton, @@ -88,8 +89,19 @@ export const ProposalPage = () => { {proposal.proposalName} - - + + + + + + + + + + Ends in 12 hours + + + From acd9b6fe6235f8e7120e456ea9b4578aae4177c5 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 14 Jul 2022 09:51:11 -0400 Subject: [PATCH 012/113] Switch from x to left chevron for back button --- .../Governance/components/ProposalPage/ProposalPage.scss | 8 ++++++-- .../Governance/components/ProposalPage/ProposalPage.tsx | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.scss b/src/views/Governance/components/ProposalPage/ProposalPage.scss index d277ab604f..2821ae81ca 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.scss +++ b/src/views/Governance/components/ProposalPage/ProposalPage.scss @@ -12,9 +12,13 @@ display: flex; justify-content: flex-start; + .MuiLink-root { + display: flex; + align-items: center; + } + .MuiButton-root { - margin-left: 0px; - padding-left: 0px; + padding-left: 9px; } .css-ihuj2u-MuiTypography-root-MuiLink-root.active { diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index fd4b00e880..4203163735 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,6 +1,7 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; +import { ChevronLeft } from "@mui/icons-material"; import { Box, Grid, Link, Typography, useTheme } from "@mui/material"; import { Chip, @@ -70,7 +71,8 @@ export const ProposalPage = () => { - Back + + Back From 46c9a11d0cce5cace30a1bd28c924dfe46a4cdda Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Fri, 15 Jul 2022 12:01:05 -0400 Subject: [PATCH 013/113] Adding content for votes section --- .../components/ProposalPage/ProposalPage.tsx | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index 4203163735..54806b80dd 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -2,17 +2,20 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; import { ChevronLeft } from "@mui/icons-material"; -import { Box, Grid, Link, Typography, useTheme } from "@mui/material"; +import { Box, Grid, Link, OutlinedInput, Typography, useTheme } from "@mui/material"; import { Chip, Icon, OHMChipProps, Paper, + PrimaryButton, + Radio, SecondaryButton, Tab, TabPanel, Tabs, TextButton, + VoteBreakdown, } from "@olympusdao/component-library"; import { useMemo, useState } from "react"; import { NavLink as RouterLink, useParams } from "react-router-dom"; @@ -123,7 +126,44 @@ export const ProposalPage = () => { - Votes will go here + + + Cast your vote + + + + Your Yes vote will be approving the policy at{" "} + this location + + + + + + + + + + + + Vote + + + + + + + + Top Voters + + + From f9f9fafbd61e02058a151631c10892757dcc38cc Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Mon, 18 Jul 2022 21:03:29 -0400 Subject: [PATCH 014/113] Start create proposal form --- src/views/Governance/Governance.tsx | 2 + .../CreateProposal/CreateProposal.scss | 31 ++++++++ .../CreateProposal/CreateProposal.tsx | 79 +++++++++++++++++++ .../components/CreateProposal/index.ts | 1 + .../components/ProposalPage/ProposalPage.scss | 26 ++++++ .../components/ProposalPage/ProposalPage.tsx | 32 ++++---- 6 files changed, 156 insertions(+), 15 deletions(-) create mode 100644 src/views/Governance/components/CreateProposal/CreateProposal.scss create mode 100644 src/views/Governance/components/CreateProposal/CreateProposal.tsx create mode 100644 src/views/Governance/components/CreateProposal/index.ts diff --git a/src/views/Governance/Governance.tsx b/src/views/Governance/Governance.tsx index 52a0e123aa..e0f7500601 100644 --- a/src/views/Governance/Governance.tsx +++ b/src/views/Governance/Governance.tsx @@ -1,5 +1,6 @@ import { Route, Routes } from "react-router-dom"; +import { CreateProposal } from "./components/CreateProposal"; import { ProposalPage } from "./components/ProposalPage"; import { ProposalsDashboard } from "./ProposalsDashboard"; @@ -9,6 +10,7 @@ export const Governance = () => { } /> } /> + } /> ); diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.scss b/src/views/Governance/components/CreateProposal/CreateProposal.scss new file mode 100644 index 0000000000..a5e6b188de --- /dev/null +++ b/src/views/Governance/components/CreateProposal/CreateProposal.scss @@ -0,0 +1,31 @@ +.create-proposal-form { + width: 100%; + display: flex; + justify-content: center; + + .back-button { + display: flex; + justify-content: flex-start; + + .MuiLink-root { + display: flex; + align-items: center; + } + + .MuiButton-root { + padding-left: 9px; + } + + .css-ihuj2u-MuiTypography-root-MuiLink-root.active { + text-decoration: none; + } + } + + .create-proposal-input { + width: 100%; + } + + .create-proposal-section { + padding: 5px 5px 5px 5px; + } +} diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.tsx b/src/views/Governance/components/CreateProposal/CreateProposal.tsx new file mode 100644 index 0000000000..7ee3756417 --- /dev/null +++ b/src/views/Governance/components/CreateProposal/CreateProposal.tsx @@ -0,0 +1,79 @@ +import "./CreateProposal.scss"; + +import { ChevronLeft } from "@mui/icons-material"; +import { Grid, Link, MenuItem, OutlinedInput, Select, Typography } from "@mui/material"; +import { Paper, TextButton } from "@olympusdao/component-library"; +import { Link as RouterLink } from "react-router-dom"; + +export const CreateProposal = () => { + return ( +
+ + + + + + Back + + + + + Title + + + + + + + + + Description + + + 0/14,400 + + + + + + + + + Discussion + + + + + + + + + Action + + + + + + + + Target + + + + + + + + +
+ ); +}; diff --git a/src/views/Governance/components/CreateProposal/index.ts b/src/views/Governance/components/CreateProposal/index.ts new file mode 100644 index 0000000000..881e6fe273 --- /dev/null +++ b/src/views/Governance/components/CreateProposal/index.ts @@ -0,0 +1 @@ +export { CreateProposal } from "./CreateProposal"; diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.scss b/src/views/Governance/components/ProposalPage/ProposalPage.scss index 2821ae81ca..4151225f73 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.scss +++ b/src/views/Governance/components/ProposalPage/ProposalPage.scss @@ -53,6 +53,32 @@ } #simple-tabpanel-1 { + width: 100%; + + .cast-vote-header { + margin-bottom: 6px; + } + + .install-location { + margin-bottom: 20px; + } + + .vote-submission-section { + margin-bottom: 45px; + } + + .your-comment { + width: 100%; + } + + .vote-breakdown { + margin-bottom: 27px; + + .PaperCard-container { + padding: 18px; + } + } + .MuiBox-root { padding-left: 0px; } diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index 54806b80dd..c68987cb9d 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -94,7 +94,7 @@ export const ProposalPage = () => { {proposal.proposalName}
- + @@ -121,34 +121,39 @@ export const ProposalPage = () => { - - {proposal.content} + + + {proposal.content} + + + Discussion + - + Cast your vote - - + + Your Yes vote will be approving the policy at{" "} this location - - + + - + - - Vote + + Vote - + { - - Discussion -
From 6800e6419d1002ac260819c146e5c4e57d33a295 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Tue, 19 Jul 2022 11:12:14 -0400 Subject: [PATCH 015/113] Clean up create proposals page code --- .../components/BackButton/BackButton.scss | 17 +++ .../components/BackButton/BackButton.tsx | 17 +++ .../Governance/components/BackButton/index.ts | 1 + .../CreateProposal/CreateProposal.scss | 28 ++--- .../CreateProposal/CreateProposal.tsx | 116 ++++++++---------- .../CreateProposal/components/TextEntry.tsx | 35 ++++++ .../components/ProposalPage/ProposalPage.scss | 18 --- .../components/ProposalPage/ProposalPage.tsx | 16 ++- 8 files changed, 136 insertions(+), 112 deletions(-) create mode 100644 src/views/Governance/components/BackButton/BackButton.scss create mode 100644 src/views/Governance/components/BackButton/BackButton.tsx create mode 100644 src/views/Governance/components/BackButton/index.ts create mode 100644 src/views/Governance/components/CreateProposal/components/TextEntry.tsx diff --git a/src/views/Governance/components/BackButton/BackButton.scss b/src/views/Governance/components/BackButton/BackButton.scss new file mode 100644 index 0000000000..f62ce0f6d3 --- /dev/null +++ b/src/views/Governance/components/BackButton/BackButton.scss @@ -0,0 +1,17 @@ +.back-button { + display: flex; + justify-content: flex-start; + + .MuiLink-root { + display: flex; + align-items: center; + } + + .MuiButton-root { + padding-left: 9px; + } + + .css-ihuj2u-MuiTypography-root-MuiLink-root.active { + text-decoration: none; + } +} diff --git a/src/views/Governance/components/BackButton/BackButton.tsx b/src/views/Governance/components/BackButton/BackButton.tsx new file mode 100644 index 0000000000..5d62bbddef --- /dev/null +++ b/src/views/Governance/components/BackButton/BackButton.tsx @@ -0,0 +1,17 @@ +import "./BackButton.scss"; + +import { ChevronLeft } from "@mui/icons-material"; +import { Grid, Link } from "@mui/material"; +import { TextButton } from "@olympusdao/component-library"; +import { Link as RouterLink } from "react-router-dom"; + +export const BackButton = () => { + return ( + + + + Back + + + ); +}; diff --git a/src/views/Governance/components/BackButton/index.ts b/src/views/Governance/components/BackButton/index.ts new file mode 100644 index 0000000000..f2438ee192 --- /dev/null +++ b/src/views/Governance/components/BackButton/index.ts @@ -0,0 +1 @@ +export { BackButton } from "./BackButton"; diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.scss b/src/views/Governance/components/CreateProposal/CreateProposal.scss index a5e6b188de..106f7b559f 100644 --- a/src/views/Governance/components/CreateProposal/CreateProposal.scss +++ b/src/views/Governance/components/CreateProposal/CreateProposal.scss @@ -3,29 +3,15 @@ display: flex; justify-content: center; - .back-button { - display: flex; - justify-content: flex-start; - - .MuiLink-root { - display: flex; - align-items: center; - } - - .MuiButton-root { - padding-left: 9px; - } - - .css-ihuj2u-MuiTypography-root-MuiLink-root.active { - text-decoration: none; - } - } - - .create-proposal-input { + .input-box { width: 100%; } - .create-proposal-section { - padding: 5px 5px 5px 5px; + .create-proposal-entry { + padding: 10px 5px 10px 5px; + + .entry-title { + margin-bottom: 6px; + } } } diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.tsx b/src/views/Governance/components/CreateProposal/CreateProposal.tsx index 7ee3756417..58c63a39de 100644 --- a/src/views/Governance/components/CreateProposal/CreateProposal.tsx +++ b/src/views/Governance/components/CreateProposal/CreateProposal.tsx @@ -1,76 +1,64 @@ import "./CreateProposal.scss"; -import { ChevronLeft } from "@mui/icons-material"; -import { Grid, Link, MenuItem, OutlinedInput, Select, Typography } from "@mui/material"; -import { Paper, TextButton } from "@olympusdao/component-library"; -import { Link as RouterLink } from "react-router-dom"; +import { Grid, MenuItem, Select, Typography } from "@mui/material"; +import { Paper } from "@olympusdao/component-library"; +import { useState } from "react"; + +import { BackButton } from "../BackButton"; +import { TextEntry } from "./components/TextEntry"; export const CreateProposal = () => { + const [proposalTitle, setProposalTitle] = useState(""); + const [proposalDescription, setProposalDescription] = useState(""); + const [proposalDiscussion, setProposalDiscussion] = useState(""); + const [proposalAction, setProposalAction] = useState("installModule"); + const [proposalContract, setProposalContract] = useState(""); + + const selectionInput = () => { + return ( + + + Action + + + + + + ); + }; + return (
- - - - Back - - - - - Title - - - - - - - - - Description - - - 0/14,400 - - - - - - - - - Discussion - - - - - + + + + - - - Action - - - - - - - - Target - - - - - + {selectionInput()} + diff --git a/src/views/Governance/components/CreateProposal/components/TextEntry.tsx b/src/views/Governance/components/CreateProposal/components/TextEntry.tsx new file mode 100644 index 0000000000..4461afcac9 --- /dev/null +++ b/src/views/Governance/components/CreateProposal/components/TextEntry.tsx @@ -0,0 +1,35 @@ +import { Grid, OutlinedInput, Typography } from "@mui/material"; + +type TextEntryProps = { + inputTitle: string; + gridSize: number; + handleChange: (value: string) => void; + secondaryTitle?: string; + placeholder?: string; +}; + +export const TextEntry = ({ inputTitle, gridSize, handleChange, secondaryTitle, placeholder }: TextEntryProps) => { + return ( + + + + {inputTitle} + + {secondaryTitle ? ( + + {secondaryTitle} + + ) : ( + <> + )} + + + handleChange(e.target.value)} + /> + + + ); +}; diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.scss b/src/views/Governance/components/ProposalPage/ProposalPage.scss index 4151225f73..e05a148cc9 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.scss +++ b/src/views/Governance/components/ProposalPage/ProposalPage.scss @@ -7,24 +7,6 @@ .navigation { margin-bottom: 30px; } - - .back-button { - display: flex; - justify-content: flex-start; - - .MuiLink-root { - display: flex; - align-items: center; - } - - .MuiButton-root { - padding-left: 9px; - } - - .css-ihuj2u-MuiTypography-root-MuiLink-root.active { - text-decoration: none; - } - } } .proposal-header { diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index c68987cb9d..e007343163 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,7 +1,6 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; -import { ChevronLeft } from "@mui/icons-material"; import { Box, Grid, Link, OutlinedInput, Typography, useTheme } from "@mui/material"; import { Chip, @@ -18,12 +17,14 @@ import { VoteBreakdown, } from "@olympusdao/component-library"; import { useMemo, useState } from "react"; -import { NavLink as RouterLink, useParams } from "react-router-dom"; +import { useParams } from "react-router-dom"; +import { Link as RouterLink } from "react-router-dom"; import { shorten } from "src/helpers"; import { useProposal } from "src/hooks/useProposal"; import { Proposal as ProposalType } from "src/hooks/useProposals"; import { NULL_PROPOSAL } from "../../constants"; +import { BackButton } from "../BackButton"; export const ProposalPage = () => { const theme = useTheme(); @@ -72,14 +73,11 @@ export const ProposalPage = () => { - - - - Back - - + - Create new proposal + + Create new proposal + From 9ce3226e38c34d4bfb310d468dea2e9024d17b48 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Tue, 19 Jul 2022 11:22:10 -0400 Subject: [PATCH 016/113] Add continue button --- .../components/CreateProposal/CreateProposal.scss | 6 ++++++ .../Governance/components/CreateProposal/CreateProposal.tsx | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.scss b/src/views/Governance/components/CreateProposal/CreateProposal.scss index 106f7b559f..72846aa0dd 100644 --- a/src/views/Governance/components/CreateProposal/CreateProposal.scss +++ b/src/views/Governance/components/CreateProposal/CreateProposal.scss @@ -11,7 +11,13 @@ padding: 10px 5px 10px 5px; .entry-title { + justify-content: space-between; margin-bottom: 6px; } } + + .continue-button { + width: 25%; + margin-top: 12px; + } } diff --git a/src/views/Governance/components/CreateProposal/CreateProposal.tsx b/src/views/Governance/components/CreateProposal/CreateProposal.tsx index 58c63a39de..cc7cbdf29b 100644 --- a/src/views/Governance/components/CreateProposal/CreateProposal.tsx +++ b/src/views/Governance/components/CreateProposal/CreateProposal.tsx @@ -1,7 +1,7 @@ import "./CreateProposal.scss"; import { Grid, MenuItem, Select, Typography } from "@mui/material"; -import { Paper } from "@olympusdao/component-library"; +import { Paper, PrimaryButton } from "@olympusdao/component-library"; import { useState } from "react"; import { BackButton } from "../BackButton"; @@ -60,6 +60,7 @@ export const CreateProposal = () => { handleChange={setProposalContract} /> + Continue
From f18dab487a9379eb4140908e58b1e0856ef41877 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Tue, 19 Jul 2022 12:00:55 -0400 Subject: [PATCH 017/113] Clean up proposals page implementation --- .../components/ProposalPage/ProposalPage.tsx | 126 ++++++------------ .../components/PollDetailsTab.tsx | 16 +++ .../ProposalPage/components/VotesTab.tsx | 48 +++++++ src/views/Governance/interfaces.ts | 5 + 4 files changed, 107 insertions(+), 88 deletions(-) create mode 100644 src/views/Governance/components/ProposalPage/components/PollDetailsTab.tsx create mode 100644 src/views/Governance/components/ProposalPage/components/VotesTab.tsx create mode 100644 src/views/Governance/interfaces.ts diff --git a/src/views/Governance/components/ProposalPage/ProposalPage.tsx b/src/views/Governance/components/ProposalPage/ProposalPage.tsx index e007343163..30b3c99dd1 100644 --- a/src/views/Governance/components/ProposalPage/ProposalPage.tsx +++ b/src/views/Governance/components/ProposalPage/ProposalPage.tsx @@ -1,21 +1,8 @@ import "./ProposalPage.scss"; import { t } from "@lingui/macro"; -import { Box, Grid, Link, OutlinedInput, Typography, useTheme } from "@mui/material"; -import { - Chip, - Icon, - OHMChipProps, - Paper, - PrimaryButton, - Radio, - SecondaryButton, - Tab, - TabPanel, - Tabs, - TextButton, - VoteBreakdown, -} from "@olympusdao/component-library"; +import { Box, Grid, Link, Typography, useTheme } from "@mui/material"; +import { Chip, Icon, OHMChipProps, Paper, SecondaryButton, Tab, TabPanel, Tabs } from "@olympusdao/component-library"; import { useMemo, useState } from "react"; import { useParams } from "react-router-dom"; import { Link as RouterLink } from "react-router-dom"; @@ -25,6 +12,8 @@ import { Proposal as ProposalType } from "src/hooks/useProposals"; import { NULL_PROPOSAL } from "../../constants"; import { BackButton } from "../BackButton"; +import { PollDetailsTab } from "./components/PollDetailsTab"; +import { VotesTab } from "./components/VotesTab"; export const ProposalPage = () => { const theme = useTheme(); @@ -68,6 +57,37 @@ export const ProposalPage = () => { } }; + const proposalHeader = () => { + return ( + + + + Posted on {formattedPublishedDate} by:{" "} + {shorten(proposal.proposer)} + + + + + {proposal.proposalName} + + + + + + + + + + + Ends in 12 hours + + + + + + ); + }; + return (
@@ -80,33 +100,7 @@ export const ProposalPage = () => { - - - - Posted on {formattedPublishedDate} by:{" "} - {shorten(proposal.proposer)} - - - - - {proposal.proposalName} - - - - - - - - - - - - Ends in 12 hours - - - - - + {proposalHeader()} { - - - {proposal.content} - - - Discussion - - + - - - Cast your vote - - - - Your Yes vote will be approving the policy at{" "} - this location - - - - - - - - - - - - Vote - - - - - - - - Top Voters - - - + diff --git a/src/views/Governance/components/ProposalPage/components/PollDetailsTab.tsx b/src/views/Governance/components/ProposalPage/components/PollDetailsTab.tsx new file mode 100644 index 0000000000..b2616b0a76 --- /dev/null +++ b/src/views/Governance/components/ProposalPage/components/PollDetailsTab.tsx @@ -0,0 +1,16 @@ +import { Grid, Typography } from "@mui/material"; +import { TextButton } from "@olympusdao/component-library"; +import { ProposalTabProps } from "src/views/Governance/interfaces"; + +export const PollDetailsTab = ({ proposal }: ProposalTabProps) => { + return ( + + + {proposal.content} + + + Discussion + + + ); +}; diff --git a/src/views/Governance/components/ProposalPage/components/VotesTab.tsx b/src/views/Governance/components/ProposalPage/components/VotesTab.tsx new file mode 100644 index 0000000000..da6ee04ee6 --- /dev/null +++ b/src/views/Governance/components/ProposalPage/components/VotesTab.tsx @@ -0,0 +1,48 @@ +import { Grid, OutlinedInput, Typography, useTheme } from "@mui/material"; +import { PrimaryButton, Radio, VoteBreakdown } from "@olympusdao/component-library"; +import { ProposalTabProps } from "src/views/Governance/interfaces"; + +export const VotesTab = ({ proposal }: ProposalTabProps) => { + const theme = useTheme(); + + return ( + + + Cast your vote + + + + Your Yes vote will be approving the policy at{" "} + this location + + + + + + + + + + + + Vote + + + + + + + + Top Voters + + + + ); +}; diff --git a/src/views/Governance/interfaces.ts b/src/views/Governance/interfaces.ts new file mode 100644 index 0000000000..8aef786ad7 --- /dev/null +++ b/src/views/Governance/interfaces.ts @@ -0,0 +1,5 @@ +import { Proposal as ProposalType } from "src/hooks/useProposals"; + +export type ProposalTabProps = { + proposal: ProposalType; +}; From de64850b9dd94e78b26e2ebbf2e8bdc6e30fc8f4 Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 21 Jul 2022 13:48:11 -0400 Subject: [PATCH 018/113] Mock proposal states --- src/hooks/useProposal.ts | 3 ++ src/hooks/useProposals.ts | 31 +++++++++++++++---- src/views/Governance/ProposalsDashboard.tsx | 7 +++-- .../components/ProposalPage/ProposalPage.tsx | 3 +- src/views/Governance/constants.ts | 1 + src/views/Governance/helpers/index.ts | 3 ++ 6 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 src/views/Governance/helpers/index.ts diff --git a/src/hooks/useProposal.ts b/src/hooks/useProposal.ts index b1a8a1f286..ee54e1b8ba 100644 --- a/src/hooks/useProposal.ts +++ b/src/hooks/useProposal.ts @@ -8,6 +8,7 @@ import { mockGetProposalContent, mockGetProposalHasBeenActivated, mockGetProposalMetadata, + mockGetProposalState, mockGetProposalTotalEndorsements, mockGetProposalURI, mockGetYesVotesForProposal, @@ -43,6 +44,7 @@ export const useProposal = (instructionsIndex: number) => { const noVotes = mockGetNoVotesForProposal(instructionsIndex); const proposalURI = mockGetProposalURI(proposal.proposalName); const proposalContent = mockGetProposalContent(proposalURI); + const proposalState = mockGetProposalState(proposal.proposalName); const currentProposal = { id: instructionsIndex, @@ -50,6 +52,7 @@ export const useProposal = (instructionsIndex: number) => { proposer: proposal.proposer, submissionTimestamp: proposal.submissionTimestamp, isActive: isActive, + state: proposalState, endorsements: endorsements, yesVotes: yesVotes, noVotes: noVotes, diff --git a/src/hooks/useProposals.ts b/src/hooks/useProposals.ts index 3c87ca9d5b..dd3529f5ea 100644 --- a/src/hooks/useProposals.ts +++ b/src/hooks/useProposals.ts @@ -16,6 +16,7 @@ export interface Proposal { proposer: string; submissionTimestamp: number; isActive: boolean; + state: Status; endorsements: number; yesVotes: number; noVotes: number; @@ -23,11 +24,13 @@ export interface Proposal { content: string; } +export type Status = "active" | "endorsement" | "discussion" | "draft" | "closed"; + /// Mock totalInstructions value from INSTR.sol export const mockTotalInstructions = 3; /// Mock instructions ID for current active proposal -export const activeProposal = 3; +export const activeProposal = 0; /// Mock mapping data for proposalMetadata in Governance.sol export const mockProposalMetadata: { [key: number]: proposalMetadata } = { @@ -64,9 +67,9 @@ export const mockProposalTotalEndorsements: { [key: number]: number } = { /// Mock mapping data on proposal activation in Governance.sol export const mockProposalHasBeenActivated: { [key: number]: boolean } = { 0: true, - 1: false, - 2: true, - 3: true, + 1: true, + 2: false, + 3: false, }; /// Mock mapping data on proposal yes votes in Governance.sol @@ -93,7 +96,7 @@ export const mockProposalURIs: { [key: string]: string } = { "0x4f49502d34000000000000000000000000000000000000000000000000000000": "ipfs://proposalnumberfour", }; -/// Mock content stores by IPFS URI +/// Mock content stored at IPFS URI export const mockProposalContent: { [key: string]: string } = { "ipfs://proposalnumberone": "This is OIP-1. The first mock proposal", "ipfs://proposalnumbertwo": "This is OIP-2. The second mock proposal", @@ -101,6 +104,14 @@ export const mockProposalContent: { [key: string]: string } = { "ipfs://proposalnumberfour": "This is OIP-4. The fourth mock proposal", }; +/// Mock proposal state (don't know if this will be stored at IPFS URI or in-contract) +export const mockProposalState: { [key: string]: Status } = { + "0x4f49502d31000000000000000000000000000000000000000000000000000000": "active", + "0x4f49502d32000000000000000000000000000000000000000000000000000000": "discussion", + "0x4f49502d33000000000000000000000000000000000000000000000000000000": "closed", + "0x4f49502d34000000000000000000000000000000000000000000000000000000": "draft", +}; + /// Function to return mock total instructions in lieu of a contract export const mockGetTotalInstructions = (): number => { return mockTotalInstructions; @@ -141,6 +152,11 @@ export const mockGetProposalContent = (uri: string): string => { return mockProposalContent[uri]; }; +/// Function to return mock proposal state in lieu of contract/content deployed to IPFS +export const mockGetProposalState = (proposalName: string): Status => { + return mockProposalState[proposalName]; +}; + /** * Query key for useProposals. Doesn't need to be refreshed on address or network changes * Proposals should be fetched no matter what. @@ -173,7 +189,7 @@ export const useProposals = (filters: { isActive?: boolean }) => { const allProposals: Proposal[] = []; /// For each proposal, fetch the relevant data points used in the frontend - for (let i = 0; i < numberOfProposals; i++) { + for (let i = 0; i <= numberOfProposals; i++) { const proposal = mockGetProposalMetadata(i); const isActive = mockGetProposalHasBeenActivated(i); const endorsements = mockGetProposalTotalEndorsements(i); @@ -181,6 +197,7 @@ export const useProposals = (filters: { isActive?: boolean }) => { const noVotes = mockGetNoVotesForProposal(i); const proposalURI = mockGetProposalURI(proposal.proposalName); const proposalContent = mockGetProposalContent(proposalURI); + const proposalState = mockGetProposalState(proposal.proposalName); const currentProposal = { id: i, @@ -188,6 +205,7 @@ export const useProposals = (filters: { isActive?: boolean }) => { proposer: proposal.proposer, submissionTimestamp: proposal.submissionTimestamp, isActive: isActive, + state: proposalState, endorsements: endorsements, yesVotes: yesVotes, noVotes: noVotes, @@ -196,6 +214,7 @@ export const useProposals = (filters: { isActive?: boolean }) => { }; allProposals.push(currentProposal); + console.log(allProposals); } if (filters) { return allProposals.filter(proposal => proposal.isActive === filters.isActive); diff --git a/src/views/Governance/ProposalsDashboard.tsx b/src/views/Governance/ProposalsDashboard.tsx index 958e0b639b..a63f00f689 100644 --- a/src/views/Governance/ProposalsDashboard.tsx +++ b/src/views/Governance/ProposalsDashboard.tsx @@ -9,6 +9,7 @@ import { Proposal as ProposalType, useProposals } from "src/hooks/useProposals"; import { FilterModal } from "./components/FilterModal"; import { SearchBar } from "./components/SearchBar/SearchBar"; +import { toCapitalCase } from "./helpers"; export const ProposalsDashboard = () => { const [isFilterModalOpen, setIsFilterModalOpen] = useState(false); @@ -30,13 +31,13 @@ export const ProposalsDashboard = () => { const renderProposals = () => { return allProposalsData.map(proposal => { return ( - + { - + diff --git a/src/views/Governance/constants.ts b/src/views/Governance/constants.ts index 823a0f420f..d67cab9521 100644 --- a/src/views/Governance/constants.ts +++ b/src/views/Governance/constants.ts @@ -6,6 +6,7 @@ export const NULL_PROPOSAL: Proposal = { proposer: "", submissionTimestamp: 0, isActive: false, + state: "closed", endorsements: 0, yesVotes: 0, noVotes: 0, diff --git a/src/views/Governance/helpers/index.ts b/src/views/Governance/helpers/index.ts new file mode 100644 index 0000000000..3c95f95ff6 --- /dev/null +++ b/src/views/Governance/helpers/index.ts @@ -0,0 +1,3 @@ +export const toCapitalCase = (value: string): string => { + return value.charAt(0).toUpperCase() + value.slice(1); +}; From 7ad6c9c731a61d6d83ce72ac4feae56937c13dcd Mon Sep 17 00:00:00 2001 From: Lienid <0xLienid@protonmail.com> Date: Thu, 21 Jul 2022 14:15:16 -0400 Subject: [PATCH 019/113] Update snapshots, unsure why Give was failing --- .../Give/__tests__/__snapshots__/Give.unit.test.jsx.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/Give/__tests__/__snapshots__/Give.unit.test.jsx.snap b/src/views/Give/__tests__/__snapshots__/Give.unit.test.jsx.snap index 18392aa1af..fee2e38530 100644 --- a/src/views/Give/__tests__/__snapshots__/Give.unit.test.jsx.snap +++ b/src/views/Give/__tests__/__snapshots__/Give.unit.test.jsx.snap @@ -1168,7 +1168,7 @@ exports[`Give View Disconnected should render Causes Dashboard 1`] = ` class="MuiGrid-root MuiGrid-container MuiGrid-item MuiGrid-grid-xs-12 MuiGrid-grid-sm-4 css-18ow2ad-MuiGrid-root" >

- Next Reward Yield + Next Rebase Yield

- ROI (5-Day Rate) + Rebases (5-Day Rate)

- Next Reward Amount + Your Next Rebase

- Next Reward Yield + Next Rebase Yield

- ROI (5-Day Rate) + Rebases (5-Day Rate)

- Next Reward Amount + Your Next Rebase

- Next Reward Yield + Next Rebase Yield

- ROI (5-Day Rate) + Rebases (5-Day Rate)

should render component 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake

@@ -97,11 +97,11 @@ exports[` should render component 1`] = `

- APY + Annualized Rebases

should render component 1`] = `

should render component 1`] = `

should render component 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -745,7 +745,7 @@ exports[` should render component 1`] = ` style="padding: 8px 0px;" >
should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render component 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake

@@ -3047,11 +3047,11 @@ exports[` should render correct staking headers 1`] = `

- APY + Annualized Rebases

should render correct staking headers 1`] = `

should render correct staking headers 1`] = `

should render correct staking headers 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -3695,7 +3695,7 @@ exports[` should render correct staking headers 1`] = ` style="padding: 8px 0px;" >
should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" > should render correct staking headers 1`] = ` style="padding: 8px 0px;" >

Single Stake

@@ -97,11 +97,11 @@ exports[`Mobile Resolution should render all supported multi chain staking contr

- APY + Annualized Rebases

{ const { data: rebaseRate } = useStakingRebaseRate(); - const props: PropsOf = { title: t`ROI (5-Day Rate)` }; + const props: PropsOf = { title: t`Rebases (5-Day Rate)` }; if (rebaseRate) { const fiveDayRate = (Math.pow(1 + rebaseRate, 5 * 3) - 1) * 100; diff --git a/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx b/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx index 87c1acc518..b19e076a3d 100644 --- a/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeInputArea/StakeInputArea.tsx @@ -82,13 +82,6 @@ export const StakeInputArea: React.FC<{ isZoomed: boolean }> = props => { return ( - {currentAction === "UNSTAKE" && liveInverseBonds && ( - - {t`Unstaking your OHM? Trade for Treasury Stables with no slippage & zero trading fees via`} -   - {t`Inverse Bonds`} - - )} = props => { - + {currentAction === "UNSTAKE" && liveInverseBonds && ( + + {t`Unstaking your OHM? Trade for Treasury Stables with no slippage & zero trading fees via`} +   + {t`Inverse Bonds`} + + )} { .filter(nonNullable) .reduce((res, bal) => res.add(bal), new DecimalBigNumber("0", 18)); - const props: PropsOf = { title: t`Next Reward Amount` }; + const props: PropsOf = { title: t`Your Next Rebase` }; if (rebaseRate && sohmBalances && totalGohmBalance && currentIndex) { const nextRewardAmount = rebaseRate * totalGohmBalance.mul(currentIndex).add(totalSohmBalance).toApproxNumber(); diff --git a/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx b/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx index 6f6984f62c..9fea68f424 100644 --- a/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx +++ b/src/views/Stake/components/StakeArea/components/StakeRebaseYield.tsx @@ -6,7 +6,7 @@ import { useStakingRebaseRate } from "src/hooks/useStakingRebaseRate"; export const StakeRebaseYield = () => { const { data: rebaseRate } = useStakingRebaseRate(); - const props: PropsOf = { title: t`Next Reward Yield` }; + const props: PropsOf = { title: t`Next Rebase Yield` }; if (rebaseRate) props.balance = `${formatNumber(rebaseRate * 100, 4)}%`; else props.isLoading = true; diff --git a/src/views/TreasuryDashboard/__tests__/__snapshots__/TreasuryDashboard.unit.test.tsx.snap b/src/views/TreasuryDashboard/__tests__/__snapshots__/TreasuryDashboard.unit.test.tsx.snap index 5e59ce5f24..a66727a697 100644 --- a/src/views/TreasuryDashboard/__tests__/__snapshots__/TreasuryDashboard.unit.test.tsx.snap +++ b/src/views/TreasuryDashboard/__tests__/__snapshots__/TreasuryDashboard.unit.test.tsx.snap @@ -150,7 +150,7 @@ exports[` should render component 1`] = `

should render component 1`] = `

should render component 1`] = `

should render component 1`] = `

should render component 1`] = `

should render component 1`] = `

Mobile should render component 1`] = `

Mobile should render component 1`] = `

Mobile should render component 1`] = `

Mobile should render component 1`] = `

Mobile should render component 1`] = `

Mobile should render component 1`] = `

= props => { const _props: MetricProps = { ...props, - label: t`APY`, + label: t`Annualized Rebases`, }; if (rebaseRate) { diff --git a/src/views/TreasuryDashboard/treasuryData.ts b/src/views/TreasuryDashboard/treasuryData.ts index d1f6583974..178a7d2a55 100644 --- a/src/views/TreasuryDashboard/treasuryData.ts +++ b/src/views/TreasuryDashboard/treasuryData.ts @@ -189,8 +189,8 @@ export const tooltipItems = { coin: ["DAI", "FRAX", "ETH", "LUSD", "BTC", "UST", "Other"], rfv: ["DAI", "FRAX", "LUSD", "UST"], holder: ["OHMies"], - apy: ["APY"], - runway: [t`Current`, "7.5K APY", "5K APY", "2.5K APY"], + apy: ["Rebase Rate (RR)"], // NOTE(appleseed): these aren't currently used + runway: [t`Current`, "7.5K RR", "5K RR", "2.5K RR"], // NOTE(appleseed): these aren't currently used pol: [t`SLP Treasury`, t`Market SLP`], }; @@ -205,8 +205,8 @@ export const tooltipInfoMessages = () => { pol: t`Protocol Owned Liquidity, is the amount of LP the treasury owns and controls. The more POL the better for the protocol and its users.`, holder: t`Holders, represents the total number of Ohmies (sOHM holders)`, staked: t`OHM Staked is the ratio of sOHM to circulating supply of OHM (staked vs total)`, - apy: t`Annual Percentage Yield, is the normalized representation of an interest rate, based on a compounding period over one year. Note that APYs provided are rather ballpark level indicators and not so much precise future results.`, - runway: t`Runway, is the number of days sOHM emissions can be sustained at a given rate. Lower APY = longer runway`, + apy: t`Annual Percentage Yield, is the normalized representation of an interest rate, based on a compounding period over one year. Note that Rebase Rates provided are rather ballpark level indicators and not so much precise future results.`, + runway: t`Runway, is the number of days sOHM emissions can be sustained at a given rate. Lower Annualized Rebases = longer runway`, }; }; diff --git a/src/views/V1-Stake/V1-Stake.jsx b/src/views/V1-Stake/V1-Stake.jsx index 827bfb817d..51ddd29b76 100644 --- a/src/views/V1-Stake/V1-Stake.jsx +++ b/src/views/V1-Stake/V1-Stake.jsx @@ -191,7 +191,7 @@ function V1Stake({ setMigrationModalOpen }) { @@ -395,14 +395,14 @@ function V1Stake({ setMigrationModalOpen }) { - + diff --git a/src/views/V1-Stake/__tests__/__snapshots__/V1-Stake.unit.test.tsx.snap b/src/views/V1-Stake/__tests__/__snapshots__/V1-Stake.unit.test.tsx.snap index b4a5e2498c..d0fe2763eb 100644 --- a/src/views/V1-Stake/__tests__/__snapshots__/V1-Stake.unit.test.tsx.snap +++ b/src/views/V1-Stake/__tests__/__snapshots__/V1-Stake.unit.test.tsx.snap @@ -28,7 +28,7 @@ exports[` should render component. not connected 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake (3, 3)

@@ -84,11 +84,11 @@ exports[` should render component. not connected 1`] = `

- APY (v1) + Annualized Rebases (v1)

should render component. not connected 1`] = `

should render component. not connected 1`] = `

should render component. not connected 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -716,7 +716,7 @@ exports[` should render component. not connected 1`] = ` style="padding: 8px 0px;" >
should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render component. not connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake (3, 3)

@@ -3005,11 +3005,11 @@ exports[` should render the stake input Area when connected 1`] = `

- APY (v1) + Annualized Rebases (v1)

should render the stake input Area when connected 1`] = `

should render the stake input Area when connected 1`] = `

should render the stake input Area when connected 1`] = ` class="stake-action-row v1-row MuiBox-root css-70qvj9" > should render the stake input Area when connected 1`] = `

- Next Reward Amount + Your Next Rebase

should render the stake input Area when connected 1`] = `

- Next Reward Yield + Next Rebase Yield

should render the stake input Area when connected 1`] = `

- ROI (5-Day Rate) + Rebases (5-Day Rate)

should render the stake input Area when connected 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -3957,7 +3957,7 @@ exports[` should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" >
should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the stake input Area when connected 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake (3, 3)

@@ -6372,11 +6372,11 @@ exports[` should render the v1 migration modal 1`] = `

- APY (v1) + Annualized Rebases (v1)

should render the v1 migration modal 1`] = `

should render the v1 migration modal 1`] = `

should render the v1 migration modal 1`] = ` class="stake-action-row v1-row MuiBox-root css-70qvj9" > should render the v1 migration modal 1`] = `

- Next Reward Amount + Your Next Rebase

should render the v1 migration modal 1`] = `

- Next Reward Yield + Next Rebase Yield

should render the v1 migration modal 1`] = `

- ROI (5-Day Rate) + Rebases (5-Day Rate)

should render the v1 migration modal 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -7324,7 +7324,7 @@ exports[` should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" >
should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` class="MuiBox-root css-u4p24i" >

Single Stake (3, 3)

@@ -9739,11 +9739,11 @@ exports[` should render the v1 migration modal and banner 1`] = `

- APY (v1) + Annualized Rebases (v1)

should render the v1 migration modal and banner 1`] = `

should render the v1 migration modal and banner 1`] = `

should render the v1 migration modal and banner 1`] = ` class="stake-action-row v1-row MuiBox-root css-70qvj9" > should render the v1 migration modal and banner 1`] = `

- Next Reward Amount + Your Next Rebase

should render the v1 migration modal and banner 1`] = `

- Next Reward Yield + Next Rebase Yield

should render the v1 migration modal and banner 1`] = `

- ROI (5-Day Rate) + Rebases (5-Day Rate)

should render the v1 migration modal and banner 1`] = ` class="MuiBox-root css-u4p24i" >

Farm Pool

@@ -10691,7 +10691,7 @@ exports[` should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" >
should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" > should render the v1 migration modal and banner 1`] = ` style="padding: 8px 0px;" >

Wrap / Unwrap

@@ -106,7 +106,7 @@ exports[`Wrap Input Area Should Render Input when has Token Approval 1`] = `

Should Render Wrap Input Area with Wallet Connected 1`] = ` class="MuiBox-root css-u4p24i" >

Wrap / Unwrap

@@ -103,7 +103,7 @@ exports[` Should Render Wrap Input Area with Wallet Connected 1`] = `

Should Render Wrap Input Area with Wallet Connected 1`] = `

Should Render Wrap Input Area with Wallet Connected 1`] = `

Should Render Wrap Input Area with Wallet Connected 1`] = ` Got wsOHM on Avalanche or Arbitrum? Click below to switch networks and migrate to gOHM (no bridge required!)