From 8b1f9ec0a658276b53ee239e04e6caf0d5ed06bd Mon Sep 17 00:00:00 2001 From: Ashutosh Kumar Date: Wed, 23 Oct 2024 15:07:09 +0530 Subject: [PATCH] Changes for adding ACI Executor and simplified UI components --- src/components/ui/Table.tsx | 18 +++ src/config.ts | 15 ++ .../explorer/components/AllProposalsList.tsx | 14 +- .../ArbitraryContractInteractionForm.tsx | 31 +++- .../explorer/components/CodeCollapse.tsx | 11 +- .../components/ConfigProposalFormLambda.tsx | 13 +- .../explorer/components/ContentContainer.tsx | 1 + src/modules/explorer/components/Hero.tsx | 4 +- .../explorer/components/NetworkSheet.tsx | 4 +- .../components/ProposalActionsDialog.tsx | 134 ++++++++++-------- .../explorer/components/ProposalsList.tsx | 13 +- src/modules/explorer/hooks/useQueryParams.ts | 48 +++++++ src/modules/explorer/pages/Config/index.tsx | 2 +- src/modules/explorer/pages/DAO/index.tsx | 14 +- src/modules/explorer/pages/DAOList/index.tsx | 88 +++++++----- .../explorer/pages/Proposals/index.tsx | 11 +- 16 files changed, 272 insertions(+), 149 deletions(-) create mode 100644 src/components/ui/Table.tsx create mode 100644 src/config.ts create mode 100644 src/modules/explorer/hooks/useQueryParams.ts diff --git a/src/components/ui/Table.tsx b/src/components/ui/Table.tsx new file mode 100644 index 00000000..e868ac9a --- /dev/null +++ b/src/components/ui/Table.tsx @@ -0,0 +1,18 @@ +import { styled, Grid, Theme } from "@material-ui/core" + +export const ContentContainer = styled(Grid)(({ theme }) => ({ + borderRadius: 8, + background: "#24282D" +})) + +export const TableHeader = styled(Grid)(({ theme }: { theme: Theme }) => ({ + padding: "16px 46px", + minHeight: 34, + [theme.breakpoints.down("sm")]: { + gap: 10 + } +})) + +export const TableContainer = styled(ContentContainer)({ + width: "100%" +}) diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 00000000..a46b1a6c --- /dev/null +++ b/src/config.ts @@ -0,0 +1,15 @@ +const AppConfig = { + env: process.env.REACT_APP_ENV, + CONST: { + ARBITRARY_CONTRACT_INTERACTION: "arbitrary_contract_interaction" + }, + ACI: { + EXECUTOR_FUNCTION_NAME: "simple_lambda_3", + EXECUTOR_LAMBDA: { + code: `(Left (Left (Pair (Pair { UNPAIR; UNPAIR; SWAP; UNPACK (pair (lambda %code (pair (pair (map %handler_storage string bytes) (bytes %packed_argument)) (pair %proposal_info (address %from) (nat %frozen_token) (bytes %proposal_metadata))) (pair (pair (option %guardian address) (map %handler_storage string bytes)) (list %operations operation))) (bytes %packed_argument)); ASSERT_SOME; UNPAIR; DIP{ SWAP; PAIR; PAIR}; SWAP; EXEC} {DROP; UNIT}) "simple_lambda_3")))`, + type: `(or (or (pair %add_handler (pair (lambda %code (pair (pair (map %handler_storage string bytes) (bytes %packed_argument)) (pair %proposal_info (address %from) (nat %frozen_token) (bytes %proposal_metadata))) (pair (pair (option %guardian address) (map %handler_storage string bytes)) (list %operations operation))) (lambda %handler_check (pair bytes (map string bytes)) unit)) (string %name)) (pair %execute_handler (string %handler_name) (bytes %packed_argument))) (string %remove_handler))` + } + } +} + +export default AppConfig diff --git a/src/modules/explorer/components/AllProposalsList.tsx b/src/modules/explorer/components/AllProposalsList.tsx index b817388c..3fb701bd 100644 --- a/src/modules/explorer/components/AllProposalsList.tsx +++ b/src/modules/explorer/components/AllProposalsList.tsx @@ -3,20 +3,8 @@ import { ProposalItem } from "modules/explorer/pages/User" import React, { useCallback, useEffect, useState } from "react" import { Link } from "react-router-dom" import { Proposal, ProposalStatus } from "services/services/dao/mappers/proposal/types" -import { ContentContainer } from "./ContentContainer" import { ProposalFilter } from "./ProposalsFilter" - -const TableContainer = styled(ContentContainer)({ - width: "100%" -}) - -const TableHeader = styled(Grid)(({ theme }: { theme: Theme }) => ({ - padding: "16px 46px", - minHeight: 34, - [theme.breakpoints.down("sm")]: { - gap: 10 - } -})) +import { TableContainer, TableHeader } from "components/ui/Table" const ProposalsFooter = styled(Grid)({ padding: "16px 46px", diff --git a/src/modules/explorer/components/ArbitraryContractInteractionForm.tsx b/src/modules/explorer/components/ArbitraryContractInteractionForm.tsx index 0e707cfb..5b7c40d9 100644 --- a/src/modules/explorer/components/ArbitraryContractInteractionForm.tsx +++ b/src/modules/explorer/components/ArbitraryContractInteractionForm.tsx @@ -32,6 +32,8 @@ import { Schema } from "@taquito/michelson-encoder" import BigNumber from "bignumber.js" import { useDAO } from "services/services/dao/hooks/useDAO" import { useDAOID } from "../pages/DAO/router" +import AppConfig from "config" +import { Link } from "react-router-dom" // Base ACI Lambda const aciBaseLambda = { @@ -197,7 +199,8 @@ const ContractInteractionForm = ({ setFieldTouched, setFieldError, isValid, - showHeader + showHeader, + daoLambdas }: any) => { const daoId = useDAOID() const [state, setState] = useState(Status.NEW_INTERACTION) @@ -206,6 +209,8 @@ const ContractInteractionForm = ({ const theme = useTheme() const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) const { mutate: fetchContractData, data } = useArbitraryContractData() + const isAciDeployerDeployed = daoLambdas?.find((lambda: any) => lambda.key === AppConfig.ACI.EXECUTOR_FUNCTION_NAME) + // console.log("FormData", data) const { tezos, network } = useTezos() const [isLoading, setIsLoading] = useState(false) @@ -246,6 +251,17 @@ const ContractInteractionForm = ({ setEndpoint(undefined) } + if (!isAciDeployerDeployed && !isLoading) { + return ( +
+ We need to deploy the ACI Deployer Contract + + Deploy ACI Deployer Contract + +
+ ) + } + return ( <> {state === Status.NEW_INTERACTION ? ( @@ -499,6 +515,8 @@ const ContractInteractionForm = ({ ) const result = await contractMethod.send() + debugger + await result.confirmation(1) console.log("RESULT", result) } catch (error) { console.log("ERROR", error) @@ -518,9 +536,11 @@ const ContractInteractionForm = ({ ) } -export const ArbitraryContractInteractionForm: React.FC<{ showHeader: (state: boolean) => void }> = ({ - showHeader -}) => { +export const ArbitraryContractInteractionForm: React.FC<{ + daoLambdas: Array | undefined + showHeader: (state: boolean) => void +}> = ({ daoLambdas, showHeader }) => { + const daoId = useDAOID() const { mutate: executeProposeLambda } = useLambdaExecutePropose() const isInvalidKtOrTzAddress = (address: string) => validateContractAddress(address) !== 3 @@ -561,6 +581,8 @@ export const ArbitraryContractInteractionForm: React.FC<{ showHeader: (state: bo console.log("saveInfo") } + console.log({ daoLambdas }) + return ( ) diff --git a/src/modules/explorer/components/CodeCollapse.tsx b/src/modules/explorer/components/CodeCollapse.tsx index 8f9338fc..86fc3ba1 100644 --- a/src/modules/explorer/components/CodeCollapse.tsx +++ b/src/modules/explorer/components/CodeCollapse.tsx @@ -3,20 +3,11 @@ import { ProposalItem } from "modules/explorer/pages/User" import React, { useState } from "react" import { Link } from "react-router-dom" import { Proposal } from "services/services/dao/mappers/proposal/types" -import { ContentContainer } from "./ContentContainer" import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown" import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp" import { ProposalCodeEditorInput } from "./ProposalFormInput" import Prism, { highlight } from "prismjs" - -const TableContainer = styled(ContentContainer)({ - width: "100%" -}) - -const TableHeader = styled(Grid)({ - padding: "16px 46px", - minHeight: 34 -}) +import { TableContainer, TableHeader } from "components/ui/Table" const ProposalsFooter = styled(Grid)({ padding: "16px 46px", diff --git a/src/modules/explorer/components/ConfigProposalFormLambda.tsx b/src/modules/explorer/components/ConfigProposalFormLambda.tsx index 8b11c521..338389d2 100644 --- a/src/modules/explorer/components/ConfigProposalFormLambda.tsx +++ b/src/modules/explorer/components/ConfigProposalFormLambda.tsx @@ -18,6 +18,7 @@ import { Lambda } from "services/bakingBad/lambdas/types" import { useLambdaExecutePropose } from "services/contracts/baseDAO/hooks/useLambdaExecutePropose" import { parseLambdaCode } from "utils" import { ArbitraryContractInteractionForm } from "./ArbitraryContractInteractionForm" +import AppConfig from "config" const StyledSendButton = styled(MainButton)(({ theme }) => ({ "width": 101, @@ -173,6 +174,7 @@ export const ProposalFormLambda: React.FC<{ const [showHeader, setShowHeader] = useState(true) const lambdaForm = useForm() + const proposalTypeQuery = new URLSearchParams(window.location.search).get("type") const [lambda, setLambda] = React.useState(null) const [state, setState] = React.useState(LambdaProposalState.write_action) @@ -180,7 +182,7 @@ export const ProposalFormLambda: React.FC<{ const [lambdaArguments, setLambdaArguments] = React.useState("") const [code, setCode] = React.useState("") - const ARBITRARY_CONTRACT_INTERACTION = "arbitrary_contract_interaction" + const ARBITRARY_CONTRACT_INTERACTION = AppConfig.CONST.ARBITRARY_CONTRACT_INTERACTION const ACI: Lambda = { key: ARBITRARY_CONTRACT_INTERACTION, @@ -213,6 +215,13 @@ export const ProposalFormLambda: React.FC<{ // eslint-disable-next-line react-hooks/exhaustive-deps }, [daoLambdas]) + useEffect(() => { + if (proposalTypeQuery === "add-function") { + setCode(AppConfig.ACI.EXECUTOR_LAMBDA.code) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [proposalTypeQuery]) + const onSubmit = useCallback( (_: Values) => { const agoraPostId = Number(0) @@ -405,7 +414,7 @@ export const ProposalFormLambda: React.FC<{ /> ) : ( - + )} ) diff --git a/src/modules/explorer/components/ContentContainer.tsx b/src/modules/explorer/components/ContentContainer.tsx index 76fdc40b..c0424b09 100644 --- a/src/modules/explorer/components/ContentContainer.tsx +++ b/src/modules/explorer/components/ContentContainer.tsx @@ -1,3 +1,4 @@ +// TODO: Replace imports with components/ui/Table import { styled, Grid } from "@material-ui/core" export const ContentContainer = styled(Grid)(({ theme }) => ({ diff --git a/src/modules/explorer/components/Hero.tsx b/src/modules/explorer/components/Hero.tsx index 38ea79f7..a3855610 100644 --- a/src/modules/explorer/components/Hero.tsx +++ b/src/modules/explorer/components/Hero.tsx @@ -1,6 +1,6 @@ -import { Grid, GridProps, styled } from "@material-ui/core" import React from "react" -import { ContentContainer } from "./ContentContainer" +import { Grid, GridProps, styled } from "@material-ui/core" +import { ContentContainer } from "components/ui/Table" const Container = styled(ContentContainer)({ "padding": "0px", diff --git a/src/modules/explorer/components/NetworkSheet.tsx b/src/modules/explorer/components/NetworkSheet.tsx index 5dce70b2..fbad8205 100644 --- a/src/modules/explorer/components/NetworkSheet.tsx +++ b/src/modules/explorer/components/NetworkSheet.tsx @@ -4,9 +4,9 @@ import { useTezos } from "services/beacon/hooks/useTezos" import { Network } from "services/beacon" import { ResponsiveDialog } from "./ResponsiveDialog" import { ColorDot, networkDotColorMap } from "./ChangeNetworkButton" -import { ContentContainer } from "./ContentContainer" -import { EnvKey, getEnv } from "services/config" + import { ActionTypes, CreatorContext } from "modules/creator/state" +import { ContentContainer } from "components/ui/Table" const SheetItem = styled(ContentContainer)({ "height": 50, diff --git a/src/modules/explorer/components/ProposalActionsDialog.tsx b/src/modules/explorer/components/ProposalActionsDialog.tsx index 282f242a..bb3a2a2f 100644 --- a/src/modules/explorer/components/ProposalActionsDialog.tsx +++ b/src/modules/explorer/components/ProposalActionsDialog.tsx @@ -2,7 +2,7 @@ import { Grid, styled, Typography, useMediaQuery, useTheme } from "@material-ui/core" import { RegistryProposalFormValues } from "modules/explorer/components/UpdateRegistryDialog" import { TreasuryProposalFormValues } from "modules/explorer/components/NewTreasuryProposalDialog" -import React, { useState } from "react" +import React, { useCallback, useEffect, useState } from "react" import { NFTTransferFormValues } from "./NFTTransfer" import { useDAOID } from "../pages/DAO/router" import { ConfigProposalForm } from "./ConfigProposalForm" @@ -15,6 +15,7 @@ import { useDAO } from "services/services/dao/hooks/useDAO" import { ProposalCreatorModal } from "modules/lite/explorer/pages/CreateProposal/ProposalCreatorModal" import { useIsProposalButtonDisabled } from "services/contracts/baseDAO/hooks/useCycleInfo" import { ProposalFormContainer } from "./ProposalForm" +import { useQueryParams } from "../hooks/useQueryParams" type RecursivePartial = { [P in keyof T]?: RecursivePartial @@ -137,15 +138,17 @@ const getTreasuryActions = (): GenericAction[] => [ interface Props { open: boolean handleClose: () => void + queryType: string | null } const defaultOpenSupportedExecuteProposalModal = "none" -export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => { +export const ProposalActionsDialog: React.FC = ({ open, handleClose, queryType }) => { const daoId = useDAOID() const { data } = useDAO(daoId) const theme = useTheme() const isMobileSmall = useMediaQuery(theme.breakpoints.down("sm")) + const { clearParams } = useQueryParams() const [proposalAction, setProposalAction] = useState(ProposalAction.none) const [openProposalFormLambda, setOpenProposalFormLambda] = useState(false) @@ -154,14 +157,19 @@ export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => const liteDAOId = data?.liteDAOData?._id const shouldDisable = useIsProposalButtonDisabled(daoId) + const proposalActions = getActions() - const handleOpenCustomProposalModal = (key: ProposalAction) => { - setProposalAction(key) - setOpenProposalFormLambda(true) - handleClose() - } + const handleOpenCustomProposalModal = useCallback( + (key: ProposalAction) => { + setProposalAction(key) + setOpenProposalFormLambda(true) + handleClose() + }, + [handleClose] + ) const handleCloseCustomProposalModal = () => { + clearParams() setProposalAction(ProposalAction.none) setOpenProposalFormLambda(false) handleClose() @@ -197,6 +205,12 @@ export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => defaultOpenSupportedExecuteProposalModal ) + useEffect(() => { + if (queryType === "add-function") { + handleOpenCustomProposalModal(ProposalAction.new) + } + }, [handleOpenCustomProposalModal, queryType]) + return ( <> @@ -205,34 +219,32 @@ export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => Configuration Proposal - {getActions() - .slice(0, 3) - .map((elem, index) => - !liteDAOId && elem.id === "off-chain" ? null : ( - - - elem.id === "off-chain" - ? handleLiteProposal() - : !shouldDisable - ? elem.isLambda - ? handleOpenCustomProposalModal(elem.id) - : handleOpenSupportedExecuteProposalModal(elem.id) - : null - } + {proposalActions.slice(0, 3).map((elem, index) => + !liteDAOId && elem.id === "off-chain" ? null : ( + + + elem.id === "off-chain" + ? handleLiteProposal() + : !shouldDisable + ? elem.isLambda + ? handleOpenCustomProposalModal(elem.id) + : handleOpenSupportedExecuteProposalModal(elem.id) + : null + } + > + + {elem.name} + + - - {elem.name} - - - {elem.description}{" "} - - - - ) - )} + {elem.description}{" "} + + + + ) + )} @@ -259,7 +271,7 @@ export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => Off-Chain Proposal - {getActions() + {proposalActions .filter(item => item.id === "off-chain") .map((elem, index) => !liteDAOId && elem.id !== "off-chain" ? null : ( @@ -278,34 +290,32 @@ export const ProposalActionsDialog: React.FC = ({ open, handleClose }) => Function Proposal - {getActions() - .slice(3, 6) - .map((elem, index) => - !liteDAOId && elem.id === "off-chain" ? null : ( - - - elem.id === "off-chain" - ? handleLiteProposal() - : !shouldDisable - ? elem.isLambda - ? handleOpenCustomProposalModal(elem.id) - : handleOpenSupportedExecuteProposalModal(elem.id) - : null - } + {proposalActions.slice(3, 6).map((elem, index) => + !liteDAOId && elem.id === "off-chain" ? null : ( + + + elem.id === "off-chain" + ? handleLiteProposal() + : !shouldDisable + ? elem.isLambda + ? handleOpenCustomProposalModal(elem.id) + : handleOpenSupportedExecuteProposalModal(elem.id) + : null + } + > + + {elem.name} + + - - {elem.name} - - - {elem.description}{" "} - - - - ) - )} + {elem.description}{" "} + + + + ) + )} diff --git a/src/modules/explorer/components/ProposalsList.tsx b/src/modules/explorer/components/ProposalsList.tsx index d0b72119..d72eb9f1 100644 --- a/src/modules/explorer/components/ProposalsList.tsx +++ b/src/modules/explorer/components/ProposalsList.tsx @@ -44,20 +44,21 @@ export const ProposalsList: React.FC = ({ const [offset, setOffset] = useState(0) const [open, setopen] = useState(true) + const itemsPerPage = 24 const pageCount = Math.ceil( proposals && liteProposals - ? proposals.length + liteProposals.length / 4 + ? proposals.length + liteProposals.length / itemsPerPage : proposals && liteProposals?.length === undefined - ? proposals.length / 4 + ? proposals.length / itemsPerPage : proposals?.length === undefined && liteProposals - ? liteProposals.length / 4 + ? liteProposals.length / itemsPerPage : 0 ) // Invoke when user click to request another page. const handlePageClick = (event: { selected: number }) => { if (proposals) { - const newOffset = (event.selected * 4) % proposals.length + const newOffset = (event.selected * itemsPerPage) % proposals.length setOffset(newOffset) setCurrentPage(event.selected) } @@ -78,7 +79,7 @@ export const ProposalsList: React.FC = ({ // style={{ display: "block" }} direction="column" > - {proposals.slice(offset, offset + 4).map((p, i) => ( + {proposals.slice(offset, offset + itemsPerPage).map((p, i) => ( @@ -90,7 +91,7 @@ export const ProposalsList: React.FC = ({ ) : null} {liteProposals && liteProposals.length > 0 - ? liteProposals.slice(offset, offset + 4).map((poll, i) => { + ? liteProposals.slice(offset, offset + itemsPerPage).map((poll, i) => { return (
diff --git a/src/modules/explorer/hooks/useQueryParams.ts b/src/modules/explorer/hooks/useQueryParams.ts new file mode 100644 index 00000000..38557721 --- /dev/null +++ b/src/modules/explorer/hooks/useQueryParams.ts @@ -0,0 +1,48 @@ +// In react-router-dom v6, useHistory is deprecated and useNavigate is recommended. +// react-router-dom v5 is used in this project. +import { useCallback, useMemo } from "react" +import { useLocation, useHistory } from "react-router-dom" + +const useQuery = () => { + const { search } = useLocation() + return useMemo(() => new URLSearchParams(search), [search]) +} + +export const useQueryParams = >() => { + const location = useLocation() + const history = useHistory() + + const searchParams = useQuery() + + const getParam = useCallback( + (key: keyof T) => { + return searchParams.get(key as string) as T[keyof T] | null + }, + [searchParams] + ) + + const setParam = useCallback( + (key: keyof T, value: T[keyof T]) => { + history.replace({ pathname: location.pathname, search: searchParams.toString() }) + }, + [history, location.pathname, searchParams] + ) + + const removeParam = useCallback( + (key: keyof T) => { + history.replace({ pathname: location.pathname, search: searchParams.toString() }) + }, + [history, location.pathname, searchParams] + ) + + const clearParams = useCallback(() => { + history.replace({ pathname: location.pathname, search: "" }) + }, [history, location.pathname]) + + return { + getParam, + setParam, + removeParam, + clearParams + } +} diff --git a/src/modules/explorer/pages/Config/index.tsx b/src/modules/explorer/pages/Config/index.tsx index 00f46d83..bffa900c 100644 --- a/src/modules/explorer/pages/Config/index.tsx +++ b/src/modules/explorer/pages/Config/index.tsx @@ -8,7 +8,6 @@ import { useDAOID } from "../DAO/router" import { useDropAllExpired } from "../../../../services/contracts/baseDAO/hooks/useDropAllExpired" import { SmallButton } from "../../../common/SmallButton" -import { ContentContainer } from "../../components/ContentContainer" import { InfoIcon } from "../../components/styled/InfoIcon" import { CopyAddress } from "modules/common/CopyAddress" import { HeroTitle } from "modules/explorer/components/HeroTitle" @@ -21,6 +20,7 @@ import { DaoInfoTables } from "./components/DAOInfoTable" import { ProposalStatus } from "services/services/dao/mappers/proposal/types" import { ProposalCreator } from "modules/lite/explorer/pages/CreateProposal" import { ProposalCreatorModal } from "modules/lite/explorer/pages/CreateProposal/ProposalCreatorModal" +import { ContentContainer } from "components/ui/Table" interface Action { id: any diff --git a/src/modules/explorer/pages/DAO/index.tsx b/src/modules/explorer/pages/DAO/index.tsx index a2e975d9..a7d173eb 100644 --- a/src/modules/explorer/pages/DAO/index.tsx +++ b/src/modules/explorer/pages/DAO/index.tsx @@ -1,23 +1,19 @@ import React, { useMemo, useState } from "react" -import { Grid, styled, Typography, Button, useTheme, useMediaQuery, Avatar } from "@material-ui/core" +import BigNumber from "bignumber.js" +import { Grid, styled, Typography, useTheme, useMediaQuery, Avatar } from "@material-ui/core" -import { useFlush } from "services/contracts/baseDAO/hooks/useFlush" import { useDAO } from "services/services/dao/hooks/useDAO" -import { useProposals } from "services/services/dao/hooks/useProposals" import { useDAOID } from "./router" -import { ContentContainer } from "../../components/ContentContainer" -import { ProposalsList } from "../../components/ProposalsList" -import { ProposalStatus } from "services/services/dao/mappers/proposal/types" import { DAOStatsRow } from "../../components/DAOStatsRow" import { UsersTable } from "../../components/UsersTable" -import BigNumber from "bignumber.js" + import { SmallButton } from "../../../common/SmallButton" -import { usePolls } from "modules/lite/explorer/hooks/usePolls" -import dayjs from "dayjs" + import { DaoSettingModal } from "./components/Settings" import SettingsIcon from "@mui/icons-material/Settings" import { SettingsDialog } from "./components/SettingsDialog" +import { ContentContainer } from "components/ui/Table" export const StyledAvatar = styled(Avatar)({ height: 50, diff --git a/src/modules/explorer/pages/DAOList/index.tsx b/src/modules/explorer/pages/DAOList/index.tsx index 27d123ed..a7515aa4 100644 --- a/src/modules/explorer/pages/DAOList/index.tsx +++ b/src/modules/explorer/pages/DAOList/index.tsx @@ -113,28 +113,18 @@ const TabsContainer = styled(Grid)(({ theme }) => ({ gap: 16 })) -export const DAOList: React.FC = () => { +const UserDAOsList: React.FC<{ searchText: string }> = ({ searchText }) => { const { network, account } = useTezos() const { data: daos, isLoading } = useAllDAOs(network) const theme = useTheme() - const isMobileExtraSmall = useMediaQuery(theme.breakpoints.down("xs")) const isMobileSmall = useMediaQuery(theme.breakpoints.down("mobile")) - - const [searchText, setSearchText] = useState("") - const [selectedTab, setSelectedTab] = React.useState(0) - const [currentPage, setCurrentPage] = useState(0) - - const [offset, setOffset] = useState(0) - const pageCount = Math.ceil(daos ? daos.length / 16 : 0) - - const currentDAOs = useMemo(() => { + const myDAOs = useMemo(() => { if (daos) { const formattedDAOs = daos .map(dao => ({ id: dao.address, name: dao.name, - description: dao.description, symbol: dao.token.symbol, votingAddresses: dao.ledgers ? dao.ledgers.map(l => l.holder.address) : [], votingAddressesCount: @@ -142,9 +132,10 @@ export const DAOList: React.FC = () => { dao_type: { name: dao.dao_type.name }, + description: dao.description, allowPublicAccess: dao.dao_type.name === "lite" ? dao.allowPublicAccess : true })) - .sort((a, b) => b.votingAddressesCount - a.votingAddressesCount) + .sort((a, b) => b.votingAddresses.length - a.votingAddresses.length) if (searchText) { return formattedDAOs.filter( @@ -153,21 +144,56 @@ export const DAOList: React.FC = () => { (formattedDao.symbol && formattedDao.symbol.toLowerCase().includes(searchText.toLowerCase())) ) } - - const slice = formattedDAOs.slice(offset, offset + 16) - - return slice + return formattedDAOs.filter(dao => dao.votingAddresses.includes(account)) } return [] - }, [daos, searchText, offset]) + }, [daos, account, searchText]) - const myDAOs = useMemo(() => { + if (!account) return + + if (isLoading) + return ( + + + + ) + + if (myDAOs.length === 0) return You have not joined any DAO + + return ( + + {myDAOs.map((dao, i) => ( + + + + ))} + + ) +} + +export const DAOList: React.FC = () => { + const { network } = useTezos() + const { data: daos, isLoading } = useAllDAOs(network) + + const theme = useTheme() + const isMobileExtraSmall = useMediaQuery(theme.breakpoints.down("xs")) + const isMobileSmall = useMediaQuery(theme.breakpoints.down("mobile")) + + const [searchText, setSearchText] = useState("") + const [selectedTab, setSelectedTab] = React.useState(0) + const [currentPage, setCurrentPage] = useState(0) + + const [offset, setOffset] = useState(0) + const pageCount = Math.ceil(daos ? daos.length / 16 : 0) + + const currentDAOs = useMemo(() => { if (daos) { const formattedDAOs = daos .map(dao => ({ id: dao.address, name: dao.name, + description: dao.description, symbol: dao.token.symbol, votingAddresses: dao.ledgers ? dao.ledgers.map(l => l.holder.address) : [], votingAddressesCount: @@ -175,10 +201,9 @@ export const DAOList: React.FC = () => { dao_type: { name: dao.dao_type.name }, - description: dao.description, allowPublicAccess: dao.dao_type.name === "lite" ? dao.allowPublicAccess : true })) - .sort((a, b) => b.votingAddresses.length - a.votingAddresses.length) + .sort((a, b) => b.votingAddressesCount - a.votingAddressesCount) if (searchText) { return formattedDAOs.filter( @@ -187,11 +212,14 @@ export const DAOList: React.FC = () => { (formattedDao.symbol && formattedDao.symbol.toLowerCase().includes(searchText.toLowerCase())) ) } - return formattedDAOs.filter(dao => dao.votingAddresses.includes(account)) + + const slice = formattedDAOs.slice(offset, offset + 16) + + return slice } return [] - }, [daos, searchText, account]) + }, [daos, searchText, offset]) const filterDAOs = (filter: string) => { setSearchText(filter.trim()) @@ -310,19 +338,7 @@ export const DAOList: React.FC = () => { - - {!account ? ( - - ) : myDAOs.length > 0 ? ( - myDAOs.map((dao, i) => ( - - - - )) - ) : ( - You have not joined any DAO - )} - + diff --git a/src/modules/explorer/pages/Proposals/index.tsx b/src/modules/explorer/pages/Proposals/index.tsx index 1ba71a59..81091127 100644 --- a/src/modules/explorer/pages/Proposals/index.tsx +++ b/src/modules/explorer/pages/Proposals/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from "react" +import React, { useCallback, useEffect, useState } from "react" import { Button, Grid, Paper, styled, Theme, Typography, useMediaQuery, useTheme } from "@material-ui/core" import { useDAO } from "services/services/dao/hooks/useDAO" @@ -102,6 +102,7 @@ export const Proposals: React.FC = () => { const { data: proposals } = useProposals(daoId) const theme = useTheme() const isMobileSmall = useMediaQuery(theme.breakpoints.down("xs")) + const proposalTypeQuery = new URLSearchParams(window.location.search).get("type") const [openDialog, setOpenDialog] = useState(false) const { mutate } = useFlush() @@ -140,6 +141,12 @@ export const Proposals: React.FC = () => { setSelectedTab(newValue) } + useEffect(() => { + if (proposalTypeQuery === "add-function") { + setOpenDialog(true) + } + }, [proposalTypeQuery]) + return ( <> @@ -278,7 +285,7 @@ export const Proposals: React.FC = () => { - + )