From e0ada5745311527e7733c8f52f651adeb0baa91b Mon Sep 17 00:00:00 2001 From: leochen Date: Mon, 21 Oct 2024 15:53:22 +0800 Subject: [PATCH] Add multisig prompt on account management , #4466 (#4894) * Add multisig prompt, #4466 * Add null guard, #4466 * Modify null guard, #4466 * Modify prompt content, #4466 * Add them/it after Manage, #4466 * Remove useless component, #4466 --- .../overview/accountInfo/accountInfoPanel.js | 2 + .../components/multisigManagePrompt.js | 89 +++++++++++++++++++ packages/next-common/utils/constants.js | 1 + 3 files changed, 92 insertions(+) create mode 100644 packages/next-common/components/overview/accountInfo/components/multisigManagePrompt.js diff --git a/packages/next-common/components/overview/accountInfo/accountInfoPanel.js b/packages/next-common/components/overview/accountInfo/accountInfoPanel.js index 3cb056e72e..3e4d041ad4 100644 --- a/packages/next-common/components/overview/accountInfo/accountInfoPanel.js +++ b/packages/next-common/components/overview/accountInfo/accountInfoPanel.js @@ -17,6 +17,7 @@ import ManageAccountButton from "./components/manageAccountButton"; import AccountPanelScrollPrompt from "./components/accountPanelScrollPrompt"; import ExtensionUpdatePrompt from "./components/extensionUpdatePrompt"; import AssetHubManagePrompt from "./components/assetHubManagePrompt"; +import MultisigManagePrompt from "./components/multisigManagePrompt"; import { useAccountTransferPopup } from "./hook/useAccountTransferPopup"; import dynamic from "next/dynamic"; import { useState } from "react"; @@ -284,6 +285,7 @@ export function CommonAccountInfoPanel({ hideManageAccountLink }) { {!hideManageAccountLink && } + ); diff --git a/packages/next-common/components/overview/accountInfo/components/multisigManagePrompt.js b/packages/next-common/components/overview/accountInfo/components/multisigManagePrompt.js new file mode 100644 index 0000000000..67e4d8a9a8 --- /dev/null +++ b/packages/next-common/components/overview/accountInfo/components/multisigManagePrompt.js @@ -0,0 +1,89 @@ +import Prompt from "./prompt"; +import { PromptTypes } from "next-common/components/scrollPrompt"; +import { CACHE_KEY } from "next-common/utils/constants"; +import { useMemo, useEffect } from "react"; +import Link from "next/link"; +import { useChain } from "next-common/context/chain"; +import { + fetchMyMultisigsCount, + myMultisigsCountSelector, +} from "next-common/store/reducers/multisigSlice"; +import { useDispatch, useSelector } from "react-redux"; +import useRealAddress from "next-common/utils/hooks/useRealAddress"; +import getChainSettings from "next-common/utils/consts/settings"; +import { usePathname } from "next/navigation"; +import { myMultisigsSelector } from "next-common/store/reducers/multisigSlice"; + +const getNeedApprovalCount = (multisigs, address) => { + const needApprovalItems = multisigs?.filter((item) => { + return ( + item.state?.name === "Approving" && !item?.approvals.includes(address) + ); + }); + + return needApprovalItems?.length || 0; +}; + +function ManageLink({ manageContent }) { + const pathname = usePathname(); + if (pathname.startsWith("/account/multisigs")) { + return null; + } + + return ( + <> +  Manage {manageContent}  + + here + + + ); +} + +export default function MultisigManagePrompt() { + const dispatch = useDispatch(); + const chain = useChain(); + const realAddress = useRealAddress(); + const myMultisigsCount = useSelector(myMultisigsCountSelector) || 0; + const myMultisigs = useSelector(myMultisigsSelector); + const { items: multisigs = [], total = 0 } = myMultisigs || {}; + + const settings = getChainSettings(chain); + + const needApprovalCount = useMemo(() => { + if (total === 0) { + return 0; + } + + return getNeedApprovalCount(multisigs, realAddress); + }, [multisigs, total, realAddress]); + + useEffect(() => { + if (settings?.multisigApiPrefix) { + dispatch(fetchMyMultisigsCount(chain, realAddress)); + } + }, [dispatch, chain, realAddress, settings]); + + const promptContent = useMemo(() => { + if (!settings?.multisigApiPrefix || myMultisigsCount === 0) { + return null; + } + + const manageContent = myMultisigsCount > 1 ? "them" : "it"; + const transactionContent = myMultisigsCount > 1 ? "multisigs" : "multisig"; + + return ( + + You have {myMultisigsCount} active {transactionContent},   + {needApprovalCount} of   + {manageContent} need your approval. + + + ); + }, [myMultisigsCount, needApprovalCount, settings]); + + return promptContent; +} diff --git a/packages/next-common/utils/constants.js b/packages/next-common/utils/constants.js index 0b060f1147..50ad3daebe 100644 --- a/packages/next-common/utils/constants.js +++ b/packages/next-common/utils/constants.js @@ -121,6 +121,7 @@ export const CACHE_KEY = { "ambassador-demotion-expire-remind-visible", extensionUpdateMetadata: "extensionUpdateMetadata", assetHubPromptVisible: "asset-hub-management-prompt-visible", + multisigPromptVisible: "multisig-management-prompt-visible", }; export const CHAIN = process.env.NEXT_PUBLIC_CHAIN;