From 69b1ee9176a34211eb8877d97f06a602b676635d Mon Sep 17 00:00:00 2001 From: MananTank Date: Wed, 22 Jan 2025 23:48:14 +0000 Subject: [PATCH] [TOOL-3082] Dashboard: Replace NetworkSelectorButton with SingleNetworkSelector where switching chain in wallet is not required (#6031) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## PR-Codex overview This PR introduces enhancements to the `SingleNetworkSelector` component and its usage across various files. It adds new props for alignment and positioning, replaces existing network selector buttons, and integrates chain ID handling in several components. ### Detailed summary - Added `side`, `disableChainId`, and `align` props to `SingleNetworkSelector`. - Updated `SingleNetworkSelector` to conditionally render the chain ID badge. - Replaced `NetworkSelectorButton` with `SingleNetworkSelector` in multiple components. - Integrated `chainId` state management using `useState` in `BackendWalletsSection` and `ImportForm`. - Updated `BackendWalletsTable` and `BackendWalletBalanceCell` to accept `chainId` as a prop. - Changed the way active chains are retrieved with `useActiveChainAsDashboardChain` to `useV5DashboardChain`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` --- .../@/components/blocks/NetworkSelectors.tsx | 18 ++++++++++----- .../components/blocks/select-with-search.tsx | 13 ++++++----- .../components/backend-wallets-table.tsx | 16 ++++++++++---- .../overview/components/engine-overview.tsx | 18 ++++++++++++--- .../import-contract/modal.tsx | 22 +++++++++++++------ 5 files changed, 63 insertions(+), 24 deletions(-) diff --git a/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx b/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx index a8e8423554c..6c3043d70d6 100644 --- a/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx +++ b/apps/dashboard/src/@/components/blocks/NetworkSelectors.tsx @@ -90,6 +90,9 @@ export function SingleNetworkSelector(props: { popoverContentClassName?: string; // if specified - only these chains will be shown chainIds?: number[]; + side?: "left" | "right" | "top" | "bottom"; + disableChainId?: boolean; + align?: "center" | "start" | "end"; }) { const { allChains, idToChain } = useAllChainsData(); @@ -142,14 +145,17 @@ export function SingleNetworkSelector(props: { /> {chain.name} - - Chain ID - {chain.chainId} - + + {!props.disableChainId && ( + + Chain ID + {chain.chainId} + + )} ); }, - [idToChain], + [idToChain, props.disableChainId], ); const isLoadingChains = allChains.length === 0; @@ -168,6 +174,8 @@ export function SingleNetworkSelector(props: { className={props.className} popoverContentClassName={props.popoverContentClassName} disabled={isLoadingChains} + side={props.side} + align={props.align} /> ); } diff --git a/apps/dashboard/src/@/components/blocks/select-with-search.tsx b/apps/dashboard/src/@/components/blocks/select-with-search.tsx index 086491ef35b..15cf8031f2f 100644 --- a/apps/dashboard/src/@/components/blocks/select-with-search.tsx +++ b/apps/dashboard/src/@/components/blocks/select-with-search.tsx @@ -31,6 +31,8 @@ interface SelectWithSearchProps ) => boolean; renderOption?: (option: { value: string; label: string }) => React.ReactNode; popoverContentClassName?: string; + side?: "left" | "right" | "top" | "bottom"; + align?: "center" | "start" | "end"; } export const SelectWithSearch = React.forwardRef< @@ -107,7 +109,7 @@ export const SelectWithSearch = React.forwardRef< }, [searchValue]); return ( - + setIsPopoverOpen(false)} style={{ diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/backend-wallets-table.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/backend-wallets-table.tsx index 7cdeaa533a0..1942f0c3a02 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/backend-wallets-table.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/backend-wallets-table.tsx @@ -35,7 +35,10 @@ import { ChainIcon } from "components/icons/ChainIcon"; import { TWTable } from "components/shared/TWTable"; import { useTrack } from "hooks/analytics/useTrack"; import { EngineBackendWalletOptions } from "lib/engine"; -import { useActiveChainAsDashboardChain } from "lib/v5-adapter"; +import { + useActiveChainAsDashboardChain, + useV5DashboardChain, +} from "lib/v5-adapter"; import { DownloadIcon, PencilIcon, @@ -59,6 +62,7 @@ interface BackendWalletsTableProps { isPending: boolean; isFetched: boolean; authToken: string; + chainId: number; } interface BackendWalletDashboard extends BackendWallet { @@ -72,19 +76,21 @@ interface BackendWalletBalanceCellProps { instanceUrl: string; address: string; authToken: string; + chainId: number; } const BackendWalletBalanceCell: React.FC = ({ instanceUrl, address, authToken, + chainId, }) => { const { data: backendWalletBalance } = useEngineBackendWalletBalance({ instanceUrl: instanceUrl, address, authToken, }); - const chain = useActiveChainAsDashboardChain(); + const chain = useV5DashboardChain(chainId); if (!chain || !backendWalletBalance) { return; } @@ -100,7 +106,7 @@ const BackendWalletBalanceCell: React.FC = ({ ); - const explorer = chain?.explorers?.[0]; + const explorer = chain.blockExplorers?.[0]; if (!explorer) { return balanceComponent; } @@ -123,6 +129,7 @@ export const BackendWalletsTable: React.FC = ({ isPending, isFetched, authToken, + chainId, }) => { const editDisclosure = useDisclosure(); const receiveDisclosure = useDisclosure(); @@ -163,13 +170,14 @@ export const BackendWalletsTable: React.FC = ({ instanceUrl={instanceUrl} address={address} authToken={authToken} + chainId={chainId} /> ); }, id: "balance", }), ]; - }, [instanceUrl, authToken]); + }, [instanceUrl, authToken, chainId]); const [selectedBackendWallet, setSelectedBackendWallet] = useState(); diff --git a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/engine-overview.tsx b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/engine-overview.tsx index 6247c787c35..da887de1b62 100644 --- a/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/engine-overview.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/(team)/~/engine/(instance)/[engineId]/overview/components/engine-overview.tsx @@ -1,11 +1,13 @@ "use client"; +import { SingleNetworkSelector } from "@/components/blocks/NetworkSelectors"; import { type EngineInstance, useEngineBackendWallets, useEngineWalletConfig, } from "@3rdweb-sdk/react/hooks/useEngine"; -import { NetworkSelectorButton } from "components/selects/NetworkSelectorButton"; import Link from "next/link"; +import { useState } from "react"; +import { useActiveWalletChain } from "thirdweb/react"; import { BackendWalletsTable } from "./backend-wallets-table"; import { CreateBackendWalletButton } from "./create-backend-wallet-button"; import { ImportBackendWalletButton } from "./import-backend-wallet-button"; @@ -43,6 +45,10 @@ function BackendWalletsSection(props: { authToken: string; }) { const { instance, teamSlug, authToken } = props; + const activeWalletChain = useActiveWalletChain(); + const [_chainId, setChainId] = useState(); + const chainId = _chainId || activeWalletChain?.id || 1; + const backendWallets = useEngineBackendWallets({ instanceUrl: instance.url, authToken, @@ -105,9 +111,14 @@ function BackendWalletsSection(props: {
Show balance for - {/* TODO - Replace with simple network selector - there's no need for user to switch chain */}
- +
@@ -120,6 +131,7 @@ function BackendWalletsSection(props: { isPending={backendWallets.isPending} isFetched={backendWallets.isFetched} authToken={authToken} + chainId={chainId} /> ); diff --git a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx index 496118c9591..aa419a912ea 100644 --- a/apps/dashboard/src/components/contract-components/import-contract/modal.tsx +++ b/apps/dashboard/src/components/contract-components/import-contract/modal.tsx @@ -1,4 +1,6 @@ "use client"; + +import { SingleNetworkSelector } from "@/components/blocks/NetworkSelectors"; import { Spinner } from "@/components/ui/Spinner/Spinner"; import { Button } from "@/components/ui/button"; import { @@ -24,7 +26,6 @@ import { useAllContractList, } from "@3rdweb-sdk/react/hooks/useRegistry"; import { zodResolver } from "@hookform/resolvers/zod"; -import { NetworkSelectorButton } from "components/selects/NetworkSelectorButton"; import { useChainSlug } from "hooks/chains/chainSlug"; import { PlusIcon } from "lucide-react"; import { useState } from "react"; @@ -82,17 +83,22 @@ const importFormSchema = z.object({ message: "Invalid contract address", }, ), + chainId: z.coerce.number(), }); function ImportForm() { const router = useDashboardRouter(); - const chainId = useActiveWalletChain()?.id; - const chainSlug = useChainSlug(chainId || 1); + const activeChainId = useActiveWalletChain()?.id; const [isRedirecting, setIsRedirecting] = useState(false); const form = useForm({ resolver: zodResolver(importFormSchema), + values: { + contractAddress: "", + chainId: activeChainId || 1, + }, }); + const chainSlug = useChainSlug(form.watch("chainId")); const addToDashboard = useAddContractMutation(); const address = useActiveAccount()?.address; const registry = useAllContractList(address); @@ -107,9 +113,7 @@ function ImportForm() {
{ - if (!chainId) { - throw new Error("No chain ID"); - } + const { chainId } = data; let contractAddress: string; try { @@ -199,7 +203,11 @@ function ImportForm() {
- + form.setValue("chainId", v)} + side="top" + />