From 6fff644ee660cf388bbb54ae355fa27c43b60d74 Mon Sep 17 00:00:00 2001 From: Romeo Ledesma Date: Sat, 18 Jan 2025 00:36:15 +0800 Subject: [PATCH] fix: do not needlessly show the Change Vote button --- .../frame/Extensions/layouts/ColonyLayout.tsx | 39 ++-- .../v5/pages/ActivityPage/ActivityPage.tsx | 5 +- .../partials/AgreementCard/AgreementCard.tsx | 9 +- .../v5/common/ActionSidebar/ActionSidebar.tsx | 51 +++-- ...tActionData.ts => useGetActionFormData.ts} | 30 +-- .../ActionSidebar/hooks/useGetColonyAction.ts | 159 +++++++------- .../partials/ActionSidebarContent/types.ts | 5 +- .../ExitRecoveryStep/ExitRecoveryStep.tsx | 0 .../ExitRecoveryStep/consts.ts | 0 .../ExitRecoveryStep/index.ts | 0 .../FinalizeStep/FinalizeStep.tsx | 50 ++--- .../FinalizeStep/hooks.tsx | 59 +++-- .../FinalizeStep/index.ts | 0 .../Motions/MotionStep/FinalizeStep/types.ts | 16 ++ .../OutcomeStep/OutcomeStep.tsx | 0 .../OutcomeStep/hooks.ts | 0 .../OutcomeStep/index.ts | 0 .../partials/VoteStatuses/VoteStatuses.tsx | 0 .../partials/VoteStatuses/index.ts | 0 .../partials/VoteStatuses/types.ts | 0 .../OutcomeStep/types.ts | 0 .../RevealStep/RevealStep.tsx | 16 +- .../{steps => MotionStep}/RevealStep/hooks.ts | 30 +-- .../{steps => MotionStep}/RevealStep/index.ts | 0 .../RevealInformationItem.tsx | 0 .../partials/RevealInformationItem/index.ts | 0 .../partials/RevealInformationItem/types.ts | 0 .../partials/RevealInformationList.tsx | 0 .../RevealStep/partials/consts.ts | 0 .../RevealStep/partials/index.ts | 0 .../RevealStep/partials/types.ts | 0 .../Motions/MotionStep/RevealStep/types.ts | 6 + .../StakingStep/StakingStep.tsx | 13 +- .../StakingStep/hooks.tsx | 4 +- .../StakingStep/index.ts | 0 .../NotEnoughTokensInfo.tsx | 0 .../partials/NotEnoughTokensInfo/index.ts | 0 .../partials/StakesList/StakesList.tsx | 0 .../StakingStep/partials/StakesList/index.ts | 0 .../StakingStep/partials/StakesList/types.ts | 0 .../partials/StakingChart/StakingChart.tsx | 0 .../partials/StakingChart/index.ts | 0 .../partials/StakingChart/types.ts | 0 .../partials/StakingForm/StakingForm.tsx | 6 +- .../partials/StakingForm/helpers.ts | 8 +- .../StakingStep/partials/StakingForm/hooks.ts | 23 +- .../StakingStep/partials/StakingForm/index.ts | 0 .../StakingStep/partials/StakingForm/types.ts | 0 .../StakingStep/types.ts | 0 .../VotingStep/VotingStep.tsx | 44 ++-- .../VotingStep/hooks.tsx | 42 ++-- .../{steps => MotionStep}/VotingStep/index.ts | 0 .../DescriptionList/DescriptionList.tsx | 0 .../partials/DescriptionList/index.ts | 0 .../partials/DescriptionList/types.ts | 0 .../{steps => MotionStep}/VotingStep/types.ts | 9 - .../VotingStep/utils.tsx | 0 .../partials/Motions/MotionStep/index.ts | 15 ++ .../partials/Motions/Motions.tsx | 119 ++++------- .../MotionProvider/MotionProvider.tsx | 22 +- .../Motions/partials/MotionProvider/hooks.ts | 4 +- .../Motions/partials/MotionProvider/types.ts | 12 +- .../Motions/steps/FinalizeStep/types.ts | 21 -- .../Motions/steps/RevealStep/types.ts | 10 - .../ActionSidebar/partials/Motions/types.ts | 6 +- .../MultiSigSidebar/MultiSigSidebar.tsx | 21 +- .../partials/CancelButton/CancelButton.tsx | 5 +- .../FinalizeButton/FinalizeButton.tsx | 5 +- .../MultiSigWidget/MultiSigWidget.tsx | 20 +- .../ApprovalStep/ApprovalStep.tsx | 17 +- .../MultiSigStep/ApprovalStep/index.ts | 1 + .../FinalizeStep/FinalizeStep.tsx | 6 +- .../MultiSigStep/FinalizeStep/index.ts | 1 + .../partials/MultiSigStep/index.ts | 4 + .../RemoveVoteButton/RemoveVoteButton.tsx | 10 +- .../partials/VoteButton/VoteButton.tsx | 10 +- .../partials/MultiSigSidebar/types.ts | 5 + .../forms/CreateDecisionForm/hooks.ts | 19 -- .../CompletedAction/CompletedAction.tsx | 24 ++- .../ManageReputation/ManageReputation.tsx | 12 +- .../partials/MotionBox/MotionBox.tsx | 85 +++----- .../PaymentBuilderWidget.tsx | 4 +- .../partials/MultiSigFunding.tsx | 7 +- .../v5/common/CompletedAction/types.ts | 5 + .../v5/frame/ColonyHome/ColonyHome.tsx | 4 +- src/context/ActionContext/ActionContext.ts | 56 +++++ .../ActionContext/ActionContextProvider.tsx | 66 ++++++ src/graphql/generated.ts | 202 ++++++++++++++++-- src/graphql/mutations/annotation.graphql | 6 + src/graphql/queries/actions.graphql | 8 +- src/graphql/queries/motions.graphql | 6 + src/graphql/queries/multiSig.graphql | 17 ++ .../sagas/motions/createDecisionMotion.ts | 41 +--- src/redux/sagas/motions/rootMotion.ts | 1 + src/routes/ColonyRoute.tsx | 9 +- src/types/motions.ts | 19 -- src/utils/actions.ts | 5 +- src/utils/multiSig/index.ts | 7 +- src/utils/web3/index.ts | 3 +- 99 files changed, 832 insertions(+), 712 deletions(-) rename src/components/v5/common/ActionSidebar/hooks/{useGetActionData.ts => useGetActionFormData.ts} (95%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/ExitRecoveryStep/ExitRecoveryStep.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/ExitRecoveryStep/consts.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/ExitRecoveryStep/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/FinalizeStep/FinalizeStep.tsx (91%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/FinalizeStep/hooks.tsx (86%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/FinalizeStep/index.ts (100%) create mode 100644 src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/types.ts rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/OutcomeStep.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/hooks.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/partials/VoteStatuses/VoteStatuses.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/partials/VoteStatuses/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/partials/VoteStatuses/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/OutcomeStep/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/RevealStep.tsx (96%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/hooks.ts (82%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/RevealInformationItem/RevealInformationItem.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/RevealInformationItem/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/RevealInformationItem/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/RevealInformationList.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/consts.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/RevealStep/partials/types.ts (100%) create mode 100644 src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/types.ts rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/StakingStep.tsx (96%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/hooks.tsx (94%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/NotEnoughTokensInfo/NotEnoughTokensInfo.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/NotEnoughTokensInfo/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakesList/StakesList.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakesList/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakesList/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingChart/StakingChart.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingChart/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingChart/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingForm/StakingForm.tsx (98%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingForm/helpers.ts (92%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingForm/hooks.ts (89%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingForm/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/partials/StakingForm/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/StakingStep/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/VotingStep.tsx (91%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/hooks.tsx (87%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/partials/DescriptionList/DescriptionList.tsx (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/partials/DescriptionList/index.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/partials/DescriptionList/types.ts (100%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/types.ts (53%) rename src/components/v5/common/ActionSidebar/partials/Motions/{steps => MotionStep}/VotingStep/utils.tsx (100%) create mode 100644 src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/index.ts delete mode 100644 src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/types.ts delete mode 100644 src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/types.ts rename src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/{ => MultiSigStep}/ApprovalStep/ApprovalStep.tsx (95%) create mode 100644 src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/index.ts rename src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/{ => MultiSigStep}/FinalizeStep/FinalizeStep.tsx (97%) create mode 100644 src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/index.ts create mode 100644 src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/index.ts create mode 100644 src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts create mode 100644 src/components/v5/common/CompletedAction/types.ts create mode 100644 src/context/ActionContext/ActionContext.ts create mode 100644 src/context/ActionContext/ActionContextProvider.tsx create mode 100644 src/graphql/queries/multiSig.graphql diff --git a/src/components/frame/Extensions/layouts/ColonyLayout.tsx b/src/components/frame/Extensions/layouts/ColonyLayout.tsx index a07cd5e0fb8..554e763aa76 100644 --- a/src/components/frame/Extensions/layouts/ColonyLayout.tsx +++ b/src/components/frame/Extensions/layouts/ColonyLayout.tsx @@ -4,19 +4,20 @@ import clsx from 'clsx'; import { AnimatePresence } from 'framer-motion'; +//* Hide Initially */ +// import { defineMessages } from 'react-intl'; +// import { PaperPlaneTilt } from '@phosphor-icons/react'; import React, { type FC, type PropsWithChildren, useCallback, useEffect, } from 'react'; -import { useLocation, useSearchParams } from 'react-router-dom'; -//* Hide Initially */ -// import { defineMessages } from 'react-intl'; -// import { PaperPlaneTilt } from '@phosphor-icons/react'; +import { useLocation } from 'react-router-dom'; import { UserHubTab } from '~common/Extensions/UserHub/types.ts'; import UserHubButton from '~common/Extensions/UserHubButton/index.ts'; +import { useActionContext } from '~context/ActionContext/ActionContext.ts'; import { useActionSidebarContext } from '~context/ActionSidebarContext/ActionSidebarContext.ts'; import { useAppContext } from '~context/AppContext/AppContext.ts'; import { useColonyCreatedModalContext } from '~context/ColonyCreateModalContext/ColonyCreatedModalContext.ts'; @@ -26,7 +27,6 @@ import { useTablet } from '~hooks'; import useLocationKeyChange from '~hooks/useLocationKeyChange.ts'; import useLocationPathnameChange from '~hooks/useLocationPathnameChange.ts'; import usePrevious from '~hooks/usePrevious.ts'; -import { TX_SEARCH_PARAM } from '~routes/index.ts'; import { ACTION_TYPE_FIELD_NAME } from '~v5/common/ActionSidebar/consts.ts'; import ActionSidebar from '~v5/common/ActionSidebar/index.ts'; import ColonyCreatedModal from '~v5/common/Modals/ColonyCreatedModal/index.ts'; @@ -82,36 +82,40 @@ const ColonyLayout: FC = ({ children }) => { const { state: locationState } = useLocation(); const hasRecentlyCreatedColony = locationState?.hasRecentlyCreatedColony; - const [searchParams] = useSearchParams(); - const transactionId = searchParams?.get(TX_SEARCH_PARAM); - const previousTransactionId = usePrevious(transactionId); + const { transactionHash } = useActionContext(); + const previousTransactionHash = usePrevious(transactionHash); const handleLocationPathnameChange = useCallback(() => { - if (!!previousTransactionId && !transactionId && isActionSidebarOpen) { + if (!!previousTransactionHash && !transactionHash && isActionSidebarOpen) { toggleActionSidebarOff(); } }, [ - previousTransactionId, - transactionId, + previousTransactionHash, + transactionHash, isActionSidebarOpen, toggleActionSidebarOff, ]); const handleLocationHistoryChange = useCallback(() => { - if (!transactionId && !actionType && isActionSidebarOpen) { + if (!transactionHash && !actionType && isActionSidebarOpen) { toggleActionSidebarOff(); } - }, [transactionId, actionType, isActionSidebarOpen, toggleActionSidebarOff]); + }, [ + transactionHash, + actionType, + isActionSidebarOpen, + toggleActionSidebarOff, + ]); useLocationPathnameChange(handleLocationPathnameChange); useLocationKeyChange(handleLocationHistoryChange); useEffect(() => { - if (transactionId) { + if (transactionHash) { toggleActionSidebarOn(); } - }, [toggleActionSidebarOn, transactionId]); + }, [toggleActionSidebarOn, transactionHash]); useEffect(() => { if (hasRecentlyCreatedColony) { @@ -189,10 +193,7 @@ const ColonyLayout: FC = ({ children }) => { {isActionSidebarOpen && ( - + {isTablet ? getUserNavigation() : undefined} )} diff --git a/src/components/frame/v5/pages/ActivityPage/ActivityPage.tsx b/src/components/frame/v5/pages/ActivityPage/ActivityPage.tsx index 1ad560bcb7e..2048271f915 100644 --- a/src/components/frame/v5/pages/ActivityPage/ActivityPage.tsx +++ b/src/components/frame/v5/pages/ActivityPage/ActivityPage.tsx @@ -4,7 +4,7 @@ import FiltersContextProvider from '~common/ColonyActionsTable/FiltersContext/Fi import ColonyActionsTable from '~common/ColonyActionsTable/index.ts'; import { useSetPageHeadingTitle } from '~context/PageHeadingContext/PageHeadingContext.ts'; import { formatText } from '~utils/intl.ts'; -import useGetActionData from '~v5/common/ActionSidebar/hooks/useGetActionData.ts'; +import useGetActionFormData from '~v5/common/ActionSidebar/hooks/useGetActionFormData.ts'; import WidgetBoxList from '~v5/common/WidgetBoxList/index.ts'; import ContentWithTeamFilter from '~v5/frame/ContentWithTeamFilter/ContentWithTeamFilter.tsx'; @@ -20,7 +20,8 @@ const ActivityPage: FC = () => { const [selectedAction, setSelectedAction] = useState( undefined, ); - const { defaultValues } = useGetActionData(selectedAction || undefined); + + const { defaultValues } = useGetActionFormData(selectedAction); return ( diff --git a/src/components/frame/v5/pages/AgreementsPage/partials/AgreementCard/AgreementCard.tsx b/src/components/frame/v5/pages/AgreementsPage/partials/AgreementCard/AgreementCard.tsx index ee22e584266..fbd7e1538e6 100644 --- a/src/components/frame/v5/pages/AgreementsPage/partials/AgreementCard/AgreementCard.tsx +++ b/src/components/frame/v5/pages/AgreementsPage/partials/AgreementCard/AgreementCard.tsx @@ -1,6 +1,6 @@ import { FilePlus, ShareNetwork, WarningCircle } from '@phosphor-icons/react'; import clsx from 'clsx'; -import React, { type FC, useEffect } from 'react'; +import React, { type FC } from 'react'; import { defineMessages } from 'react-intl'; import { generatePath, useNavigate } from 'react-router-dom'; @@ -52,8 +52,6 @@ const AgreementCard: FC = ({ transactionId }) => { loadingAction, networkMotionState, motionState, - startPollingForAction, - stopPollingForAction, } = useGetColonyAction(transactionId); const { decisionData, motionData, showInActionsList } = action || {}; const { @@ -71,11 +69,6 @@ const AgreementCard: FC = ({ transactionId }) => { (domain) => domain?.nativeId === motionDomainId, ); - useEffect(() => { - startPollingForAction(); - return () => stopPollingForAction(); - }, [networkMotionState, startPollingForAction, stopPollingForAction]); - const isMotionActive = motionStakes && networkMotionState && diff --git a/src/components/v5/common/ActionSidebar/ActionSidebar.tsx b/src/components/v5/common/ActionSidebar/ActionSidebar.tsx index ecfc2eec716..1ad718640c8 100644 --- a/src/components/v5/common/ActionSidebar/ActionSidebar.tsx +++ b/src/components/v5/common/ActionSidebar/ActionSidebar.tsx @@ -16,6 +16,7 @@ import React, { } from 'react'; import { isFullScreen } from '~constants/index.ts'; +import { useActionContext } from '~context/ActionContext/ActionContext.ts'; import { useActionSidebarContext } from '~context/ActionSidebarContext/ActionSidebarContext.ts'; import { useMobile } from '~hooks/index.ts'; import useCopyToClipboard from '~hooks/useCopyToClipboard.ts'; @@ -31,7 +32,6 @@ import PillsBase from '../Pills/PillsBase.tsx'; import { ACTION_TYPE_FIELD_NAME, actionSidebarAnimation } from './consts.ts'; import useCloseSidebarClick from './hooks/useCloseSidebarClick.ts'; -import useGetActionData from './hooks/useGetActionData.ts'; import useGetGroupedActionComponent from './hooks/useGetGroupedActionComponent.tsx'; import { ActionNotFound } from './partials/ActionNotFound.tsx'; import ActionSidebarContent from './partials/ActionSidebarContent/ActionSidebarContent.tsx'; @@ -46,21 +46,21 @@ const displayName = 'v5.common.ActionSidebar'; const ActionSidebar: FC> = ({ children, - transactionId, className, }) => { const { + transactionHash, action, - isInvalidTransactionHash, + isValidTransactionHash, loadingAction, isMotion, isMultiSig, motionState, expenditure, loadingExpenditure, - startPollingForAction, - stopPollingForAction, - } = useGetActionData(transactionId); + startActionPoll, + stopActionPoll, + } = useActionContext(); const { actionSidebarToggle: [ @@ -92,14 +92,14 @@ const ActionSidebar: FC> = ({ // If the action has not been found for 20 seconds, then assume transaction doesn't exist. if (loadingAction) { timeout.current = setTimeout(() => { - stopPollingForAction(); + stopActionPoll(); }, 20000); } return () => { clearTimeout(timeout.current); }; - }, [loadingAction, stopPollingForAction]); + }, [loadingAction, stopActionPoll]); const { formRef, closeSidebarClick } = useCloseSidebarClick(); @@ -112,10 +112,9 @@ const ActionSidebar: FC> = ({ useDisableBodyScroll(isActionSidebarOpen); - const isLoading = - transactionId !== undefined && (loadingAction || loadingExpenditure); + const isLoading = !!transactionHash && (loadingAction || loadingExpenditure); - const actionNotFound = transactionId && !action; + const actionNotFound = transactionHash && !action; const getSidebarContent = () => { if (action) { @@ -125,9 +124,9 @@ const ActionSidebar: FC> = ({ if (actionNotFound) { return ( ); } @@ -138,7 +137,7 @@ const ActionSidebar: FC> = ({ return ( > = ({ }; const getShareButton = () => - !!transactionId && ( + !!transactionHash && ( > = ({ 'md:max-w-full': isSidebarFullscreen, 'md:max-w-[43.375rem]': !isSidebarFullscreen && !isMotion, 'md:max-w-[67.3125rem]': - (!isSidebarFullscreen && !!transactionId && !actionNotFound) || - (!isSidebarFullscreen && !!transactionId && isLoading), + (!isSidebarFullscreen && !!transactionHash && !actionNotFound) || + (!isSidebarFullscreen && !!transactionHash && isLoading), }, )} ref={registerContainerRef} @@ -227,7 +226,7 @@ const ActionSidebar: FC> = ({ {actionGroupType && ( )} {!isMobile && ( @@ -279,15 +278,13 @@ const ActionSidebar: FC> = ({
{children}
- {isLoading && } -
- {getSidebarContent()} -
- + {isLoading ? ( + + ) : ( +
+ {getSidebarContent()} +
+ )} { - const { - action, - isInvalidTransactionHash, - loadingAction, - networkMotionState, - motionState, - startPollingForAction, - stopPollingForAction, - } = useGetColonyAction(transactionId); +const useGetActionFormData = (transactionId: string | undefined) => { + const { action, expenditure } = useGetColonyAction(transactionId); - const { expenditure, loadingExpenditure } = useGetExpenditureData( - action?.expenditureId, - ); const allTokens = useGetAllTokens(); + const defaultValues = useMemo(() => { if (!action) { return undefined; @@ -406,19 +395,8 @@ const useGetActionData = (transactionId: string | undefined) => { }, [action, expenditure, allTokens]); return { - action, defaultValues, - isInvalidTransactionHash, - loadingAction, - isMotion: !!action?.isMotion, - isMultiSig: !!action?.isMultiSig, - networkMotionState, - motionState, - expenditure, - loadingExpenditure, - startPollingForAction, - stopPollingForAction, }; }; -export default useGetActionData; +export default useGetActionFormData; diff --git a/src/components/v5/common/ActionSidebar/hooks/useGetColonyAction.ts b/src/components/v5/common/ActionSidebar/hooks/useGetColonyAction.ts index 95a05cace17..88f102c8a76 100644 --- a/src/components/v5/common/ActionSidebar/hooks/useGetColonyAction.ts +++ b/src/components/v5/common/ActionSidebar/hooks/useGetColonyAction.ts @@ -1,20 +1,25 @@ import { MotionState as NetworkMotionState } from '@colony/colony-js'; -import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; -import { useUserTokenBalanceContext } from '~context/UserTokenBalanceContext/UserTokenBalanceContext.ts'; -import { FAILED_LOADING_DURATION as POLLING_TIMEOUT } from '~frame/LoadingTemplate/index.ts'; import { - ColonyActionType, useGetColonyActionQuery, useGetMotionStateQuery, + useOnCreateAnnotationSubscription, + useOnCreateMultiSigUserSignatureSubscription, + useOnDeleteMultiSigUserSignatureSubscription, + useOnUpdateColonyMotionSubscription, + useOnUpdateColonyMultiSigSubscription, } from '~gql'; import useEnabledExtensions from '~hooks/useEnabledExtensions.ts'; +import { type OptionalValue } from '~types'; import { MotionState, getMotionState } from '~utils/colonyMotions.ts'; import { getMultiSigState } from '~utils/multiSig/index.ts'; import { getSafePollingInterval } from '~utils/queries.ts'; import { isTransactionFormat } from '~utils/web3/index.ts'; +import { useGetExpenditureData } from './useGetExpenditureData.ts'; + export type RefetchMotionState = ReturnType< typeof useGetMotionStateQuery >['refetch']; @@ -23,20 +28,19 @@ export type RefetchAction = ReturnType< typeof useGetColonyActionQuery >['refetch']; -const useGetColonyAction = (transactionHash?: string) => { +const pollInterval = getSafePollingInterval(); + +const useGetColonyAction = (transactionHash: OptionalValue) => { const { colony: { colonyAddress }, - refetchColony, } = useColonyContext(); - const { refetchTokenBalances } = useUserTokenBalanceContext(); - const isInvalidTx = !isTransactionFormat(transactionHash); - /* Unfortunately, we need to track polling state ourselves: https://github.com/apollographql/apollo-client/issues/9081#issuecomment-975722271 */ - const [isPolling, setIsPolling] = useState(!isInvalidTx); + const isValidTx = isTransactionFormat(transactionHash); - const pollTimerRef = useRef(null); + /* Unfortunately, we need to track polling state ourselves: https://github.com/apollographql/apollo-client/issues/9081#issuecomment-975722271 */ + const [isPolling, setIsPolling] = useState(isValidTx); - const pollInterval = getSafePollingInterval(); + const [hasPendingAnnotation, setHasPendingAnnotation] = useState(false); const { data: actionData, @@ -45,15 +49,18 @@ const useGetColonyAction = (transactionHash?: string) => { stopPolling, refetch: refetchAction, } = useGetColonyActionQuery({ - skip: isInvalidTx, + skip: !isValidTx, variables: { transactionHash: transactionHash ?? '', }, - pollInterval, }); const action = actionData?.getColonyAction; + const { expenditure, loadingExpenditure } = useGetExpenditureData( + action?.expenditureId, + ); + const { loading: loadingExtensions, votingReputationExtensionData, @@ -66,78 +73,22 @@ const useGetColonyAction = (transactionHash?: string) => { const multiSigExtensionIsUninstalled = !loadingExtensions && !multiSigExtensionData; - const clearPollingCancellationTimer = () => { - if (pollTimerRef.current) { - clearTimeout(pollTimerRef.current); - - pollTimerRef.current = null; - } - }; - - const startPollingForAction = useCallback(() => { + const startActionPoll = useCallback(() => { startPolling(pollInterval); setIsPolling(true); - refetchAction(); - }, [pollInterval, startPolling, refetchAction]); + }, [startPolling]); - const stopPollingForAction = useCallback(() => { + const stopActionPoll = useCallback(() => { stopPolling(); setIsPolling(false); }, [stopPolling]); - useEffect(() => { - const shouldPoll = !isInvalidTx && !action; - - setIsPolling(shouldPoll); - - if (!shouldPoll) { - if (action) { - if (action.type === ColonyActionType.Payment) { - refetchTokenBalances(); - } - - refetchColony(); - } - - return; - } - - clearPollingCancellationTimer(); - - pollTimerRef.current = setTimeout(stopPollingForAction, POLLING_TIMEOUT); - - startPollingForAction(); - }, [ - action, - pollInterval, - refetchColony, - refetchTokenBalances, - isInvalidTx, - startPollingForAction, - stopPollingForAction, - ]); - - useEffect(() => { - return () => { - // The purpose of this is to isolate the concern of - // cleaning up the timeout scheduled for stopping the polling, - // and also to stop polling action polling altogether when the node unmounts. - // This effect should receive an empty array dependency to ensure that - // it only ever calls the return statement when its node unmounts, - // and not when any other state gets updated. - clearPollingCancellationTimer(); - - stopPollingForAction(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const { data: motionStateData, loading: loadingMotionState, refetch: refetchMotionState, } = useGetMotionStateQuery({ - skip: !action?.motionData || isInvalidTx, + skip: !action?.motionData || !isValidTx, variables: { input: { colonyAddress, @@ -186,29 +137,73 @@ const useGetColonyAction = (transactionHash?: string) => { votingReputationExtensionIsUninstalled, ]); - /* Ensures motion state is kept in sync with motion data */ + const updateAction = async () => { + const previousActionData = actionData?.getColonyAction; + + const newActionData = (await refetchAction()).data.getColonyAction; + + if (JSON.stringify(previousActionData) !== JSON.stringify(newActionData)) { + await refetchMotionState(); + } + }; + + useOnUpdateColonyMotionSubscription({ + onData: updateAction, + }); + + useOnUpdateColonyMultiSigSubscription({ + onData: updateAction, + }); + + useOnCreateMultiSigUserSignatureSubscription({ + onData: updateAction, + }); + + useOnDeleteMultiSigUserSignatureSubscription({ + onData: updateAction, + }); + + useOnCreateAnnotationSubscription({ + onData: () => setHasPendingAnnotation(true), + }); + useEffect(() => { - if (action?.motionData) { - refetchMotionState(); + if (hasPendingAnnotation && !action?.annotation) { + startActionPoll(); + } else { + setHasPendingAnnotation(false); + stopActionPoll(); } - }, [action?.motionData, refetchMotionState]); + + return stopActionPoll; + }, [ + action, + action?.annotation, + hasPendingAnnotation, + startActionPoll, + stopActionPoll, + ]); return { - isInvalidTransactionHash: isInvalidTx, + isValidTransactionHash: isValidTx, + isInvalidTransactionHash: !isValidTx, isUnknownTransaction: - !isInvalidTx && action?.colony?.colonyAddress !== colonyAddress, + isValidTx && action?.colony?.colonyAddress !== colonyAddress, loadingAction: loadingAction || + hasPendingAnnotation || (isPolling && !action) || loadingMotionState || loadingExtensions, action, - startPollingForAction, - stopPollingForAction, + startActionPoll, + stopActionPoll, networkMotionState, motionState, refetchMotionState, refetchAction, + expenditure, + loadingExpenditure, }; }; diff --git a/src/components/v5/common/ActionSidebar/partials/ActionSidebarContent/types.ts b/src/components/v5/common/ActionSidebar/partials/ActionSidebarContent/types.ts index 397a5a14eea..064aa52df7a 100644 --- a/src/components/v5/common/ActionSidebar/partials/ActionSidebarContent/types.ts +++ b/src/components/v5/common/ActionSidebar/partials/ActionSidebarContent/types.ts @@ -1,19 +1,18 @@ import { type FieldError, type UseFormReturn } from 'react-hook-form'; +import { type IActionContext } from '~context/ActionContext/ActionContext.ts'; import { type ActionFormProps } from '~shared/Fields/Form/index.ts'; import { type ColonyAction } from '~types/graphql.ts'; import { type ActionFormBaseProps } from '~v5/common/ActionSidebar/types.ts'; export interface ActionSidebarFormContentProps extends ActionFormBaseProps { - isMotion?: boolean; - transactionId?: string; isExpenditure?: boolean; actionFormProps: Omit; customError?: null | Pick; } export interface ActionSidebarContentProps { - transactionId?: string; + transactionHash: IActionContext['transactionHash']; formRef: React.RefObject>; defaultValues: ActionFormProps['defaultValues']; isMotion?: boolean; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/ExitRecoveryStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/ExitRecoveryStep.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/ExitRecoveryStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/ExitRecoveryStep.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/consts.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/consts.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/consts.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/consts.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/ExitRecoveryStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/ExitRecoveryStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/FinalizeStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/FinalizeStep.tsx similarity index 91% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/FinalizeStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/FinalizeStep.tsx index d655c9a152b..f044a85f26b 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/FinalizeStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/FinalizeStep.tsx @@ -12,7 +12,6 @@ import { ActionTypes } from '~redux/index.ts'; import { ActionForm } from '~shared/Fields/index.ts'; import { MotionState } from '~utils/colonyMotions.ts'; import { formatText } from '~utils/intl.ts'; -import { getSafePollingInterval } from '~utils/queries.ts'; import { useFinalizeSuccessCallback } from '~v5/common/ActionSidebar/partials/hooks.ts'; import { handleMotionCompleted } from '~v5/common/ActionSidebar/utils.ts'; import PillsBase from '~v5/common/Pills/index.ts'; @@ -38,20 +37,24 @@ const MSG = defineMessages({ }); const FinalizeStep: FC = ({ - actionData, - startPollingAction, - stopPollingAction, + action, + motionData, motionState, }) => { const { onFinalizeSuccessCallback } = useFinalizeSuccessCallback(); + const { canInteract } = useAppContext(); + const [isPolling, setIsPolling] = useState(false); + const { refetchColony } = useColonyContext(); + const { isFinalizable, transform: finalizePayload, hasEnoughFundsToFinalize, - } = useFinalizeStep(actionData); + } = useFinalizeStep({ action, motionData }); + const { items, isClaimed, @@ -60,36 +63,34 @@ const FinalizeStep: FC = ({ handleClaimSuccess, claimPayload, canClaimStakes, - } = useClaimConfig(actionData, startPollingAction); + } = useClaimConfig({ action, motionData }); + + const { type: actionType } = action; + + const { + isFinalized: isMotionFinalized, + motionStateHistory: { + hasFailedNotFinalizable: isMotionFailedNotFinalizable, + }, + transactionHash: motionTransactionHash, + } = motionData; const { setActionsTableTriggers } = useColonyTriggersContext(); - const isMotionFinalized = actionData.motionData.isFinalized; const previousIsMotionFinalized = usePrevious(isMotionFinalized); - const isMotionFailedNotFinalizable = - actionData.motionData.motionStateHistory.hasFailedNotFinalizable; const isMotionAgreement = - actionData.type === ColonyActionType.CreateDecisionMotion; + actionType === ColonyActionType.CreateDecisionMotion; + const isMotionClaimable = isMotionFinalized || isMotionFailedNotFinalizable || (isMotionAgreement && !isClaimed); const handleSuccess = () => { - startPollingAction(getSafePollingInterval()); setIsPolling(true); - onFinalizeSuccessCallback(actionData); + onFinalizeSuccessCallback(action); }; - /* Stop polling when mounted / dismounted */ - useEffect(() => { - if (isClaimed) { - stopPollingAction(); - setIsPolling(false); - } - return stopPollingAction; - }, [isClaimed, stopPollingAction]); - /* Update colony object when motion gets finalized or is agreement. */ useEffect(() => { if ( @@ -102,15 +103,16 @@ const FinalizeStep: FC = ({ ...triggers, shouldRefetchMotionStates: true, })); - handleMotionCompleted(actionData); + handleMotionCompleted(action); } }, [ isMotionAgreement, isMotionFinalized, previousIsMotionFinalized, - actionData, + motionData, refetchColony, setActionsTableTriggers, + action, ]); /* @@ -164,7 +166,7 @@ const FinalizeStep: FC = ({ ...(!hasEnoughFundsToFinalize ? [ { - key: `${actionData.motionData.transactionHash}-not-enough-balance`, + key: `${motionTransactionHash}-not-enough-balance`, content: (

{formatText(MSG.finalizeError)}

), diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/hooks.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/hooks.tsx similarity index 86% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/hooks.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/hooks.tsx index 6ea74b4fec1..13036a1ad38 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/hooks.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/hooks.tsx @@ -12,26 +12,22 @@ import useExtensionData from '~hooks/useExtensionData.ts'; import { type ClaimMotionRewardsPayload } from '~redux/sagas/motions/claimMotionRewards.ts'; import { type MotionFinalizePayload } from '~redux/types/actions/motion.ts'; import Numeral from '~shared/Numeral/index.ts'; -import { type MotionAction } from '~types/motions.ts'; import { getMotionAssociatedActionId, mapPayload } from '~utils/actions.ts'; import { getIsMotionOlderThanAWeek } from '~utils/dates.ts'; import { isInstalledExtensionData } from '~utils/extensions.ts'; import { formatText } from '~utils/intl.ts'; -import { getSafePollingInterval } from '~utils/queries.ts'; import { getBalanceForTokenAndDomain } from '~utils/tokens.ts'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; import { type DescriptionListItem } from '../VotingStep/partials/DescriptionList/types.ts'; -import { WinningsItems } from './types.ts'; +import { type FinalizeStepProps, WinningsItems } from './types.ts'; + +export const useFinalizeStep = ({ action, motionData }: FinalizeStepProps) => { + const { type, amount, fromDomain, tokenAddress, createdAt } = action; + + const { motionId, motionStateHistory } = motionData; -export const useFinalizeStep = (actionData: MotionAction) => { - const { - motionData: { motionId, motionStateHistory }, - type, - amount, - fromDomain, - tokenAddress, - } = actionData; const { colony: { colonyAddress, balances }, } = useColonyContext(); @@ -39,7 +35,7 @@ export const useFinalizeStep = (actionData: MotionAction) => { const { currentBlockTime } = useCurrentBlockTime(); const isMotionOlderThanWeek = currentBlockTime - ? getIsMotionOlderThanAWeek(actionData.createdAt, currentBlockTime * 1000) + ? getIsMotionOlderThanAWeek(createdAt, currentBlockTime * 1000) : false; const domainBalance = getBalanceForTokenAndDomain( @@ -64,7 +60,7 @@ export const useFinalizeStep = (actionData: MotionAction) => { const isFinalizable = hasEnoughFundsToFinalize && !motionStateHistory.hasFailedNotFinalizable; - const associatedActionId = getMotionAssociatedActionId(actionData); + const associatedActionId = getMotionAssociatedActionId(action); const transform = useMemo( () => @@ -93,25 +89,29 @@ export const useFinalizeStep = (actionData: MotionAction) => { }; }; -export const useClaimConfig = ( - actionData: MotionAction, - startPollingAction: (pollingInterval: number) => void, -) => { +export const useClaimConfig = ({ + action, + motionData, +}: ICompletedMotionAction) => { const { - motionData: { - isFinalized: isMotionFinalized, - stakerRewards, - usersStakes, - voterRewards, - remainingStakes, - }, - transactionHash, - } = actionData; + isFinalized: isMotionFinalized, + stakerRewards, + usersStakes, + voterRewards, + remainingStakes, + motionStateHistory, + } = motionData; + + const { transactionHash, type: actionType } = action; + const { user } = useAppContext(); + const { colony: { colonyAddress, nativeToken }, } = useColonyContext(); + const { extensionData } = useExtensionData(Extension.VotingReputation); + const { pollLockedTokenBalance } = useUserTokenBalanceContext(); const [isClaimed, setIsClaimed] = useState(false); @@ -120,7 +120,7 @@ export const useClaimConfig = ( const nativeTokenDecimals = nativeToken.decimals; const nativeTokenSymbol = ` ${nativeToken.symbol}`; const isMotionFailedNotFinalizable = - actionData.motionData.motionStateHistory.hasFailedNotFinalizable; + motionStateHistory.hasFailedNotFinalizable; const userStake = usersStakes.find(({ address }) => address === userAddress); const stakerReward = stakerRewards.find( @@ -180,11 +180,10 @@ export const useClaimConfig = ( const canClaimStakes = userTotalStake ? !userTotalStake.isZero() : false; const handleClaimSuccess = () => { setIsClaimed(true); - startPollingAction(getSafePollingInterval()); pollLockedTokenBalance(); }; - const associatedActionId = getMotionAssociatedActionId(actionData); + const associatedActionId = getMotionAssociatedActionId(action); const claimPayload = useMemo( () => @@ -211,7 +210,7 @@ export const useClaimConfig = ( const getDescriptionItems = (): DescriptionListItem[] => { const isMotionAgreement = - actionData.type === ColonyActionType.CreateDecisionMotion; + actionType === ColonyActionType.CreateDecisionMotion; if ( !isMotionFailedNotFinalizable && diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/types.ts new file mode 100644 index 00000000000..a7ad13339d8 --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/FinalizeStep/types.ts @@ -0,0 +1,16 @@ +import { type MotionState } from '~utils/colonyMotions.ts'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; + +export interface FinalizeStepProps extends ICompletedMotionAction { + motionState?: MotionState; +} + +export enum FinalizeStepSections { + Finalize = 'finalizeStep', +} + +export enum WinningsItems { + Staked = 'staked', + Winnings = 'winnings', + Total = 'total', +} diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/OutcomeStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/OutcomeStep.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/OutcomeStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/OutcomeStep.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/hooks.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/hooks.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/hooks.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/hooks.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/VoteStatuses.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/VoteStatuses.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/VoteStatuses.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/VoteStatuses.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/partials/VoteStatuses/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/partials/VoteStatuses/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/OutcomeStep/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/OutcomeStep/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/RevealStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/RevealStep.tsx similarity index 96% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/RevealStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/RevealStep.tsx index ce4b057877b..a5650665fb9 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/RevealStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/RevealStep.tsx @@ -25,14 +25,8 @@ import { type RevealStepProps } from './types.ts'; const displayName = 'v5.common.ActionSidebar.partials.motions.MotionSimplePayment.steps.RevealStep'; -const RevealStep: FC = ({ - actionData, - motionState, - startPollingAction, - stopPollingAction, - transactionId, - rootHash, -}) => { +const RevealStep: FC = ({ action, motionState }) => { + const { transactionHash, rootHash } = action; const { canInteract } = useAppContext(); const [isInformationAccordionOpen, { toggle: toggleInformationAccordion }] = useToggle(); @@ -48,10 +42,8 @@ const RevealStep: FC = ({ revealProgress, totalVoters, } = useRevealStep({ - actionData, - startPollingAction, - stopPollingAction, - transactionId, + action, + transactionHash, rootHash, }); diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/hooks.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/hooks.ts similarity index 82% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/hooks.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/hooks.ts index 0ee5b0a1465..9f3f9046690 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/hooks.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/hooks.ts @@ -7,16 +7,12 @@ import { useGetVoterRewardsQuery } from '~gql'; import { type RevealMotionPayload } from '~redux/sagas/motions/revealVoteMotion.ts'; import { type OnSuccess } from '~shared/Fields/index.ts'; import { type VoterRecord } from '~types/graphql.ts'; -import { type MotionAction } from '~types/motions.ts'; import { getMotionAssociatedActionId, mapPayload } from '~utils/actions.ts'; -import { getSafePollingInterval } from '~utils/queries.ts'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; import { getLocalStorageVoteValue } from '../VotingStep/utils.tsx'; -const useRevealWidgetUpdate = ( - voterRecord: VoterRecord[], - stopPollingAction: () => void, -) => { +const useRevealWidgetUpdate = (voterRecord: VoterRecord[]) => { const { user } = useAppContext(); const currentVotingRecord = voterRecord.find( ({ address }) => address === user?.walletAddress, @@ -37,7 +33,6 @@ const useRevealWidgetUpdate = ( /* Vote has been updated in db, stop polling */ if (vote !== prevVote) { - stopPollingAction(); setPrevVote(vote); } @@ -45,19 +40,15 @@ const useRevealWidgetUpdate = ( }; export const useRevealStep = ({ - actionData, - startPollingAction, - stopPollingAction, - transactionId, + action, + transactionHash, rootHash, }: { - actionData: MotionAction | undefined | null; - startPollingAction: (pollingInterval: number) => void; - stopPollingAction: () => void; - transactionId: string; + action: ICompletedMotionAction['action']; + transactionHash: string; rootHash: string | undefined; }) => { - const { motionData } = actionData || {}; + const { motionData } = action; const { nativeMotionDomainId, voterRecord, motionId } = motionData || {}; const { user } = useAppContext(); const { @@ -80,9 +71,9 @@ export const useRevealStep = ({ const { reward: voterReward } = data?.getVoterRewards || {}; const { vote, hasUserVoted, userVoteRevealed, setUserVoteRevealed } = - useRevealWidgetUpdate(voterRecord || [], stopPollingAction); + useRevealWidgetUpdate(voterRecord || []); - const associatedActionId = getMotionAssociatedActionId(actionData); + const associatedActionId = getMotionAssociatedActionId(action); const transform = useMemo( () => @@ -99,7 +90,6 @@ export const useRevealStep = ({ const handleSuccess: OnSuccess> = (_, { reset }) => { reset(); - startPollingAction(getSafePollingInterval()); setUserVoteRevealed(true); }; @@ -108,7 +98,7 @@ export const useRevealStep = ({ hasRevealed: voter.vote !== null, })); const userVote = - hasUserVoted && (vote || getLocalStorageVoteValue(transactionId)); + hasUserVoted && (vote || getLocalStorageVoteValue(transactionHash)); const revealProgress = useMemo( () => (voterRecord || []).reduce( diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/RevealInformationItem.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/RevealInformationItem.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/RevealInformationItem.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/RevealInformationItem.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationItem/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationItem/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationList.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationList.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/RevealInformationList.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/RevealInformationList.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/consts.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/consts.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/consts.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/consts.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/partials/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/partials/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/types.ts new file mode 100644 index 00000000000..fe593c737cc --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/RevealStep/types.ts @@ -0,0 +1,6 @@ +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; + +export interface RevealStepProps + extends Pick { + motionState?: number; +} diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/StakingStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/StakingStep.tsx similarity index 96% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/StakingStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/StakingStep.tsx index 87252ceac4d..61a886ec5c2 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/StakingStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/StakingStep.tsx @@ -26,7 +26,7 @@ const displayName = const StakingStep: FC = ({ className, isActive }) => { const { canInteract } = useAppContext(); - const { motionAction } = useMotionContext(); + const { action, motionData } = useMotionContext(); const [isAccordionOpen, { toggle: toggleAccordion }] = useToggle(); const { enoughReputationToStakeMinimum, @@ -35,8 +35,13 @@ const StakingStep: FC = ({ className, isActive }) => { userActivatedTokens, userInactivatedTokens, } = useStakingStep(); - const { motionData, colony, token } = motionAction; - const { usersStakes, motionStakes, requiredStake } = motionData; + const { colony, token } = action; + const { + usersStakes, + motionStakes, + requiredStake, + motionDomain: { metadata }, + } = motionData; const { nativeToken } = colony; const { nativeTokenDecimals, nativeTokenSymbol } = nativeToken; @@ -57,7 +62,7 @@ const StakingStep: FC = ({ className, isActive }) => { (message) => message?.name === SystemMessages.MotionVotingPhase, ); - const teamName = motionAction.motionData.motionDomain.metadata?.name; + const teamName = metadata?.name; const cardTitleMessageId = (() => { if (isFullyStaked) { diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/hooks.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/hooks.tsx similarity index 94% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/hooks.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/hooks.tsx index 980350cb41a..216199396a2 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/hooks.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/hooks.tsx @@ -6,10 +6,10 @@ import useEnoughTokensForStaking from '~hooks/useEnoughTokensForStaking.ts'; import { useMotionContext } from '~v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/hooks.ts'; export const useStakingStep = () => { - const { motionAction } = useMotionContext(); + const { action, motionData } = useMotionContext(); const { user, userLoading, walletConnecting } = useAppContext(); - const { colony, motionData, rootHash } = motionAction; + const { rootHash, colony } = action; const { nativeToken, colonyAddress } = colony; const { tokenAddress } = nativeToken; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/NotEnoughTokensInfo/NotEnoughTokensInfo.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/NotEnoughTokensInfo/NotEnoughTokensInfo.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/NotEnoughTokensInfo/NotEnoughTokensInfo.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/NotEnoughTokensInfo/NotEnoughTokensInfo.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/NotEnoughTokensInfo/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/NotEnoughTokensInfo/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/NotEnoughTokensInfo/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/NotEnoughTokensInfo/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/StakesList.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/StakesList.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/StakesList.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/StakesList.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakesList/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakesList/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/StakingChart.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/StakingChart.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/StakingChart.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/StakingChart.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingChart/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingChart/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/StakingForm.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/StakingForm.tsx similarity index 98% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/StakingForm.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/StakingForm.tsx index 039e77d2359..4c45fb5fe7b 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/StakingForm.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/StakingForm.tsx @@ -33,10 +33,12 @@ const StakingForm: FC = ({ userInactivatedTokens, disableForm, }) => { - const { motionAction } = useMotionContext(); + const { + action: { colony }, + motionData, + } = useMotionContext(); const { isDarkMode } = usePageThemeContext(); - const { colony, motionData } = motionAction || {}; const { nativeToken } = colony || {}; const { nativeTokenDecimals, nativeTokenSymbol: tokenSymbol = '' } = nativeToken || {}; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/helpers.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/helpers.ts similarity index 92% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/helpers.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/helpers.ts index 796fabdf293..1443e72b458 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/helpers.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/helpers.ts @@ -48,16 +48,10 @@ export const getStakingTransformFn = ({ }); export const getHandleStakeSuccessFn = - ( - setIsRefetching: SetStateFn, - startPollingMotion: (pollingInterval: number) => void, - pollLockedTokenBalance: () => void, - ) => + (setIsRefetching: SetStateFn, pollLockedTokenBalance: () => void) => (_, { reset }) => { reset(); setIsRefetching(true); - /* On stake success, initiate db polling so ui updates */ - startPollingMotion(1000); pollLockedTokenBalance(); }; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/hooks.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/hooks.ts similarity index 89% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/hooks.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/hooks.ts index 7358681c8fd..ffc1d2feba6 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/hooks.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/hooks.ts @@ -34,12 +34,16 @@ export const useStakingForm = () => { const { user } = useAppContext(); const { pollLockedTokenBalance, tokenBalanceData } = useUserTokenBalanceContext(); - const { motionAction, setIsRefetching, startPollingAction, isRefetching } = + const { action, motionData, setIsRefetching, isRefetching } = useMotionContext(); - const { colony, motionData } = motionAction || {}; - const { nativeToken } = colony || {}; - const { nativeTokenDecimals, tokenAddress } = nativeToken || {}; + const { + colony: { + colonyAddress, + nativeToken: { nativeTokenDecimals, tokenAddress }, + }, + transactionHash, + } = action; const tokenDecimals = getTokenDecimalsWithFallback(nativeTokenDecimals); const { motionId, remainingStakes } = motionData; @@ -48,7 +52,7 @@ export const useStakingForm = () => { tokenBalanceData?.activeBalance ?? 0, ).add(tokenBalanceData?.inactiveBalance ?? 0); - const associatedActionId = getMotionAssociatedActionId(motionAction); + const associatedActionId = getMotionAssociatedActionId(action); const validationSchema: ObjectSchema = object() .shape({ @@ -117,9 +121,9 @@ export const useStakingForm = () => { const transform = useMemo( () => getStakingTransformFn({ - actionId: motionAction.transactionHash, + actionId: transactionHash, userAddress: user?.walletAddress ?? '', - colonyAddress: colony?.colonyAddress ?? '', + colonyAddress: colonyAddress ?? '', motionId, nativeTokenDecimals: tokenDecimals, tokenAddress, @@ -127,9 +131,9 @@ export const useStakingForm = () => { associatedActionId, }), [ - motionAction.transactionHash, + transactionHash, user?.walletAddress, - colony?.colonyAddress, + colonyAddress, motionId, tokenDecimals, tokenAddress, @@ -140,7 +144,6 @@ export const useStakingForm = () => { const handleSuccess = getHandleStakeSuccessFn( setIsRefetching, - startPollingAction, pollLockedTokenBalance, ); diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/partials/StakingForm/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/partials/StakingForm/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/StakingStep/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/VotingStep.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/VotingStep.tsx similarity index 91% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/VotingStep.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/VotingStep.tsx index cca05eea010..334b6a0fbe6 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/VotingStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/VotingStep.tsx @@ -1,6 +1,6 @@ import { ThumbsDown, ThumbsUp } from '@phosphor-icons/react'; import clsx from 'clsx'; -import React, { type FC } from 'react'; +import React, { useMemo, type FC } from 'react'; import { defineMessages } from 'react-intl'; import { useAppContext } from '~context/AppContext/AppContext.ts'; @@ -9,6 +9,7 @@ import { ActionTypes } from '~redux/index.ts'; import { ActionForm } from '~shared/Fields/index.ts'; import { MotionVote } from '~utils/colonyMotions.ts'; import { formatText } from '~utils/intl.ts'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; import FormButtonRadioButtons from '~v5/common/Fields/RadioButtons/ButtonRadioButtons/FormButtonRadioButtons.tsx'; import MotionVoteBadge from '~v5/common/Pills/MotionVoteBadge/index.ts'; import Button, { ActionButton } from '~v5/shared/Button/index.ts'; @@ -20,11 +21,7 @@ import StatusText from '~v5/shared/StatusText/StatusText.tsx'; import { useVotingStep } from './hooks.tsx'; import DescriptionList from './partials/DescriptionList/index.ts'; -import { - type VotingStepProps, - VotingStepSections, - type VotingFormValues, -} from './types.ts'; +import { VotingStepSections, type VotingFormValues } from './types.ts'; const displayName = 'v5.common.ActionSidebar.partials.motions.MotionSimplePayment.steps.VotingStep'; @@ -40,12 +37,7 @@ const MSG = defineMessages({ }, }); -const VotingStep: FC = ({ - actionData, - startPollingAction, - stopPollingAction, - transactionId, -}) => { +const VotingStep: FC = ({ action, motionData }) => { const { currentReputationPercent, currentUserVote, @@ -58,21 +50,33 @@ const VotingStep: FC = ({ handleChangeVoteSuccess, getChangeVotePayload, } = useVotingStep({ - actionData, - startPollingAction, - stopPollingAction, - transactionId, + action, + motionData, }); const { isDarkMode } = usePageThemeContext(); + const { + usersStakes, + voterRecord, + motionStateHistory: { inRevealPhase }, + } = motionData; + const { wallet, user } = useAppContext(); - const isRevealPhase = actionData.motionData.motionStateHistory.inRevealPhase; - const canVote = !!wallet && !!user && !isRevealPhase; + + const canVote = !!wallet && !!user && !inRevealPhase; const isSupportVote = currentUserVote === MotionVote.Yay; const isOpposeVote = currentUserVote === MotionVote.Nay; + const canChangeVote = useMemo( + () => + usersStakes.length > 1 && + voterRecord.length < usersStakes.length && + voterRecord.find((voter) => voter.address === wallet?.address), + [usersStakes.length, voterRecord, wallet?.address], + ); + return ( = ({ - {!isRevealPhase && ( + {!inRevealPhase && canChangeVote && (

{formatText({ @@ -221,7 +225,7 @@ const VotingStep: FC = ({ )} - {canVote && hasUserVoted && ( + {canChangeVote && canVote && hasUserVoted && (
void, -) => { +const useVotingWidgetUpdate = (voterRecord: VoterRecord[]) => { const { user } = useAppContext(); const currentVotingRecord = voterRecord.find( ({ address }) => address === user?.walletAddress, @@ -54,32 +51,22 @@ const useVotingWidgetUpdate = ( // if user's vote count increased, db has been updated, stop polling useEffect(() => { if (currentVotingRecord?.voteCount !== prevRecord?.voteCount) { - stopPollingAction(); setPrevRecord(currentVotingRecord); } - }, [currentVotingRecord, prevRecord, stopPollingAction]); - - useEffect(() => stopPollingAction, [stopPollingAction]); + }, [currentVotingRecord, prevRecord]); return { hasUserVoted, setHasUserVoted }; }; export const useVotingStep = ({ - actionData, - startPollingAction, - stopPollingAction, - transactionId, -}: { - actionData: MotionAction; - startPollingAction: () => void; - stopPollingAction: () => void; - transactionId: string; -}) => { + action, + motionData, +}: ICompletedMotionAction) => { const { colony: { colonyAddress, nativeToken }, } = useColonyContext(); const { wallet, user } = useAppContext(); - const { motionData, rootHash } = actionData; + const { rootHash, transactionHash } = action; const { motionId, voterRecord, @@ -87,10 +74,7 @@ export const useVotingStep = ({ repSubmitted, skillRep, } = motionData; - const { hasUserVoted, setHasUserVoted } = useVotingWidgetUpdate( - voterRecord, - stopPollingAction, - ); + const { hasUserVoted, setHasUserVoted } = useVotingWidgetUpdate(voterRecord); const { extensionData } = useExtensionData(Extension.VotingReputation); @@ -121,10 +105,10 @@ export const useVotingStep = ({ const { max: maxReward, min: minReward } = data?.getVoterRewards || {}; const [currentUserVote, setCurrentUserVote] = useState( - getLocalStorageVoteValue(transactionId), + getLocalStorageVoteValue(transactionHash), ); - const associatedActionId = getMotionAssociatedActionId(actionData); + const associatedActionId = getMotionAssociatedActionId(action); const transform = useMemo( () => @@ -152,11 +136,10 @@ export const useVotingStep = ({ }; const handleSuccess: OnSuccess = ({ vote }, { reset }) => { - setLocalStorageVoteValue(transactionId, vote); + setLocalStorageVoteValue(transactionHash, vote); setCurrentUserVote(vote); setHasUserVoted(true); reset(); - startPollingAction(); }; const validationSchema = object() @@ -167,10 +150,9 @@ export const useVotingStep = ({ const handleChangeVoteSuccess = () => { const changedVote = getChangedVote(); - setLocalStorageVoteValue(transactionId, changedVote); + setLocalStorageVoteValue(transactionHash, changedVote); setCurrentUserVote(changedVote); setHasUserVoted(true); - startPollingAction(); }; const getChangeVotePayload = (): MotionVotePayload => { diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/DescriptionList.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/DescriptionList.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/DescriptionList.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/DescriptionList.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/index.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/index.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/index.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/types.ts similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/partials/DescriptionList/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/partials/DescriptionList/types.ts diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/types.ts similarity index 53% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/types.ts rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/types.ts index 19e1fc5f312..545a5cebbdd 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/types.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/types.ts @@ -1,12 +1,3 @@ -import { type MotionAction } from '~types/motions.ts'; - -export interface VotingStepProps { - startPollingAction: () => void; - stopPollingAction: () => void; - actionData: MotionAction; - transactionId: string; -} - export interface VotingFormValues { vote: number; } diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/utils.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/utils.tsx similarity index 100% rename from src/components/v5/common/ActionSidebar/partials/Motions/steps/VotingStep/utils.tsx rename to src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/VotingStep/utils.tsx diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/index.ts b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/index.ts new file mode 100644 index 00000000000..c165acc2782 --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/Motions/MotionStep/index.ts @@ -0,0 +1,15 @@ +import ExitRecovery from './ExitRecoveryStep/index.ts'; +import Finalize from './FinalizeStep/index.ts'; +import Outcome from './OutcomeStep/index.ts'; +import Reveal from './RevealStep/index.ts'; +import Staking from './StakingStep/index.ts'; +import Voting from './VotingStep/index.ts'; + +export const MotionStep = { + Finalize, + ExitRecovery, + Outcome, + Reveal, + Staking, + Voting, +}; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/Motions.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/Motions.tsx index 9fa03be833a..112f916cd01 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/Motions.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/Motions.tsx @@ -8,24 +8,23 @@ import clsx from 'clsx'; import { BigNumber } from 'ethers'; import React, { type FC, useEffect, useMemo, useState } from 'react'; +import { useActionContext } from '~context/ActionContext/ActionContext.ts'; import { useAppContext } from '~context/AppContext/AppContext.ts'; import useEnabledExtensions from '~hooks/useEnabledExtensions.ts'; import { SpinnerLoader } from '~shared/Preloaders/index.ts'; -import { type MotionAction } from '~types/motions.ts'; import { MotionState } from '~utils/colonyMotions.ts'; import { formatText } from '~utils/intl.ts'; -import useGetColonyAction from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts'; import UninstalledMessage from '~v5/common/UninstalledMessage/index.ts'; import Stepper from '~v5/shared/Stepper/index.ts'; +import { MotionStep } from './MotionStep/index.ts'; import MotionCountDownTimer from './partials/MotionCountDownTimer/index.ts'; import MotionProvider from './partials/MotionProvider/MotionProvider.tsx'; -import FinalizeStep from './steps/FinalizeStep/index.ts'; -import OutcomeStep from './steps/OutcomeStep/index.ts'; -import RevealStep from './steps/RevealStep/index.ts'; -import StakingStep from './steps/StakingStep/index.ts'; -import VotingStep from './steps/VotingStep/index.ts'; -import { type MotionsProps, type Steps, CustomStep } from './types.ts'; +import { + type Steps, + CustomStep, + type ICompletedMotionAction, +} from './types.ts'; import { getFinalizeStepTooltipText, getOutcomeStepTooltipText, @@ -36,18 +35,11 @@ import { const displayName = 'v5.common.ActionSidebar.partials.Motions'; -const Motions: FC = ({ transactionId }) => { +const Motions: FC = ({ action, motionData }) => { + const { motionState, refetchMotionState, networkMotionState, loadingAction } = + useActionContext(); + const { canInteract } = useAppContext(); - const { - action, - networkMotionState, - motionState, - refetchMotionState, - loadingAction, - startPollingForAction, - stopPollingForAction, - refetchAction, - } = useGetColonyAction(transactionId); const { loading: loadingExtensions, votingReputationExtensionData } = useEnabledExtensions(); @@ -55,8 +47,12 @@ const Motions: FC = ({ transactionId }) => { const isVotingReputationExtensionUninstalled = !loadingExtensions && !votingReputationExtensionData; - const { motionData, rootHash } = action || {}; - const { motionId = '', motionStakes, motionStateHistory } = motionData || {}; + const { + motionId = '', + motionStakes, + motionStateHistory, + remainingStakes, + } = motionData; const [activeStepKey, setActiveStepKey] = useState(networkMotionState); @@ -70,20 +66,12 @@ const Motions: FC = ({ transactionId }) => { const motionOutcomeAvailable = motionFinished && endedAt; useEffect(() => { - startPollingForAction(); - setActiveStepKey(networkMotionState); if (motionFinished) { setActiveStepKey(CustomStep.Finalize); } - return () => stopPollingForAction(); - }, [ - motionFinished, - networkMotionState, - startPollingForAction, - stopPollingForAction, - ]); + }, [motionFinished, networkMotionState]); const { percentage } = motionStakes || {}; const { nay, yay } = percentage || {}; @@ -97,7 +85,7 @@ const Motions: FC = ({ transactionId }) => { const motionStakedAndFinalizable = motionFinished && - motionData?.remainingStakes + remainingStakes .reduce((totalStakes, stake) => totalStakes.add(stake), BigNumber.from(0)) .gt(0); @@ -113,7 +101,7 @@ const Motions: FC = ({ transactionId }) => { { key: NetworkMotionState.Staking, content: ( - ), @@ -142,14 +130,7 @@ const Motions: FC = ({ transactionId }) => { }, { key: NetworkMotionState.Submit, - content: ( - - ), + content: , heading: { label: formatText({ id: 'motion.voting.label' }) || '', decor: @@ -176,14 +157,7 @@ const Motions: FC = ({ transactionId }) => { { key: NetworkMotionState.Reveal, content: ( - + ), heading: { label: formatText({ id: 'motion.reveal.label' }) || '', @@ -240,7 +214,7 @@ const Motions: FC = ({ transactionId }) => { }, { key: CustomStep.VotedMotionOutcome, - content: , + content: , heading: { icon: motionOutcomeAvailable ? (hasPassed && ThumbsUp) || ThumbsDown @@ -275,12 +249,10 @@ const Motions: FC = ({ transactionId }) => { }, { key: CustomStep.Finalize, - content: motionState && ( - ), @@ -299,30 +271,25 @@ const Motions: FC = ({ transactionId }) => { }, ]; }, [ + action, + activeStepKey, + canInteract, + hasPassed, + isFullyStaked, + isVotingReputationExtensionUninstalled, loadingAction, loadingExtensions, - isVotingReputationExtensionUninstalled, - activeStepKey, - motionStakes, - motionState, - motionId, - refetchMotionState, - networkMotionState, motionData, - action, - startPollingForAction, - stopPollingForAction, - transactionId, - isFullyStaked, + motionId, + motionOutcomeAvailable, motionStakedAndFinalizable, - rootHash, - motionStateHistory?.hasPassed, + motionStakes, + motionState, motionStateHistory?.hasFailed, motionStateHistory?.hasFailedNotFinalizable, - hasPassed, - refetchAction, - canInteract, - motionOutcomeAvailable, + motionStateHistory?.hasPassed, + networkMotionState, + refetchMotionState, ]); if ( @@ -335,11 +302,7 @@ const Motions: FC = ({ transactionId }) => { return loadingAction || loadingExtensions ? ( ) : ( - + activeStepKey={activeStepKey} setActiveStepKey={setActiveStepKey} diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/MotionProvider.tsx b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/MotionProvider.tsx index 1aa4f723ade..e44975b8163 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/MotionProvider.tsx +++ b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/MotionProvider.tsx @@ -1,30 +1,26 @@ import React, { type FC, type PropsWithChildren, useMemo } from 'react'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; + import { useStakingWidgetUpdate } from './hooks.ts'; import { MotionContext } from './MotionContext.ts'; -import { type MotionProviderProps } from './types.ts'; -const MotionProvider: FC> = ({ +const MotionProvider: FC> = ({ children, - motionAction, - startPollingAction, - stopPollingAction, + motionData, + action, }) => { - const { motionData } = motionAction; const { motionStakes } = motionData; - const [isRefetching, setIsRefetching] = useStakingWidgetUpdate( - motionStakes, - stopPollingAction, - ); + const [isRefetching, setIsRefetching] = useStakingWidgetUpdate(motionStakes); const stakingWidgetValues = useMemo( () => ({ - motionAction, - startPollingAction, + motionData, isRefetching, setIsRefetching, + action, }), - [motionAction, startPollingAction, isRefetching, setIsRefetching], + [action, isRefetching, motionData, setIsRefetching], ); return ( diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/hooks.ts b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/hooks.ts index 4d0b939c64f..9ff08a0c436 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/hooks.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/hooks.ts @@ -24,7 +24,6 @@ export const useMotionContext = () => { export const useStakingWidgetUpdate = ( motionStakes: MotionStakes, - stopPollingAction: () => void, ): [boolean, SetStateFn] => { const [isRefetching, setIsRefetching] = useState(false); const [prevStakes, setPrevMotionStakes] = useState(motionStakes); @@ -45,7 +44,6 @@ export const useStakingWidgetUpdate = ( setIsRefetching(false); setPrevMotionStakes(motionStakes); - stopPollingAction(); if (!motionJustPassedThreshold) { return; @@ -57,7 +55,7 @@ export const useStakingWidgetUpdate = ( include: [SearchActionsDocument], }); } - }, [motionStakes, prevStakes, setIsRefetching, stopPollingAction, client]); + }, [motionStakes, prevStakes, setIsRefetching, client]); return [isRefetching, setIsRefetching]; }; diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/types.ts index 342de330a4e..2757c5b16aa 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/types.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/types.ts @@ -1,15 +1,7 @@ import { type SetStateFn } from '~types/index.ts'; -import { type MotionAction } from '~types/motions.ts'; +import { type ICompletedMotionAction } from '~v5/common/ActionSidebar/partials/Motions/types.ts'; -export interface MotionContextValues { - motionAction: MotionAction; +export interface MotionContextValues extends ICompletedMotionAction { isRefetching: boolean; setIsRefetching: SetStateFn; - startPollingAction: (pollingInterval: number) => void; -} - -export interface MotionProviderProps { - motionAction: MotionAction; - startPollingAction: (pollingInterval: number) => void; - stopPollingAction: () => void; } diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/types.ts deleted file mode 100644 index 473720e469a..00000000000 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { type MotionAction } from '~types/motions.ts'; -import { type MotionState } from '~utils/colonyMotions.ts'; -import { type RefetchAction } from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts'; - -export interface FinalizeStepProps { - startPollingAction: (pollingInterval: number) => void; - stopPollingAction: () => void; - refetchAction: RefetchAction; - actionData: MotionAction; - motionState?: MotionState; -} - -export enum FinalizeStepSections { - Finalize = 'finalizeStep', -} - -export enum WinningsItems { - Staked = 'staked', - Winnings = 'winnings', - Total = 'total', -} diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/types.ts deleted file mode 100644 index ae6eba38496..00000000000 --- a/src/components/v5/common/ActionSidebar/partials/Motions/steps/RevealStep/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { type MotionAction } from '~types/motions.ts'; - -export interface RevealStepProps { - startPollingAction: (pollingInterval: number) => void; - stopPollingAction: () => void; - actionData: MotionAction | undefined | null; - rootHash: string | undefined; - transactionId: string; - motionState?: number; -} diff --git a/src/components/v5/common/ActionSidebar/partials/Motions/types.ts b/src/components/v5/common/ActionSidebar/partials/Motions/types.ts index d559f1f2ce0..ee20571ced8 100644 --- a/src/components/v5/common/ActionSidebar/partials/Motions/types.ts +++ b/src/components/v5/common/ActionSidebar/partials/Motions/types.ts @@ -1,7 +1,9 @@ import { type MotionState } from '@colony/colony-js'; -export interface MotionsProps { - transactionId: string; +import { type ICompletedAction } from '~v5/common/CompletedAction/types.ts'; + +export interface ICompletedMotionAction extends ICompletedAction { + motionData: NonNullable; } export enum CustomStep { diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/MultiSigSidebar.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/MultiSigSidebar.tsx index 7d3c199791d..336b240e12f 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/MultiSigSidebar.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/MultiSigSidebar.tsx @@ -1,11 +1,9 @@ import { Extension } from '@colony/colony-js'; -import { type FC } from 'react'; import React from 'react'; +import { useActionContext } from '~context/ActionContext/ActionContext.ts'; import useExtensionData from '~hooks/useExtensionData.ts'; import { isInstalledExtensionData } from '~utils/extensions.ts'; -import { isMultiSig } from '~utils/multiSig/index.ts'; -import useGetColonyAction from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts'; import UninstalledMessage from '~v5/common/UninstalledMessage/index.ts'; import ActionSidebarWidgetLoadingSkeleton from '../ActionSidebarWidgetLoadingSkeleton/ActionSidebarWidgetLoadingSkeleton.tsx'; @@ -13,12 +11,9 @@ import ActionSidebarWidgetLoadingSkeleton from '../ActionSidebarWidgetLoadingSke import MultiSigWidget from './partials/MultiSigWidget/MultiSigWidget.tsx'; const displayName = 'v5.common.ActionSidebar.partials.MultiSig'; -interface MultiSigSidebarProps { - transactionId: string; -} -const MultiSigSidebar: FC = ({ transactionId }) => { - const { action, loadingAction } = useGetColonyAction(transactionId); +const MultiSigSidebar = () => { + const { action, multiSigData, loadingAction } = useActionContext(); const { extensionData, loading: loadingExtension } = useExtensionData( Extension.MultisigPermissions, @@ -26,7 +21,7 @@ const MultiSigSidebar: FC = ({ transactionId }) => { const isLoading = loadingAction || loadingExtension || !action; - if (action && !isMultiSig(action)) { + if (!multiSigData) { console.warn('Not a multisig action'); return null; @@ -44,9 +39,11 @@ const MultiSigSidebar: FC = ({ transactionId }) => { } return ( -
- -
+ ); }; diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/CancelButton/CancelButton.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/CancelButton/CancelButton.tsx index 6d8127a238a..a91ab3f5db3 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/CancelButton/CancelButton.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/CancelButton/CancelButton.tsx @@ -4,17 +4,16 @@ import { defineMessages } from 'react-intl'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { ActionTypes } from '~redux/actionTypes.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { getMotionAssociatedActionId } from '~utils/actions.ts'; import { formatText } from '~utils/intl.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import ActionButton from '~v5/shared/Button/ActionButton.tsx'; import { LoadingBehavior, type ButtonProps } from '~v5/shared/Button/types.ts'; const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.CancelButton'; -interface CancelButtonProps { - action: MultiSigAction; +interface CancelButtonProps extends ICompletedMultiSigAction { multiSigId: string; handleLoadingChange: (isLoading: boolean) => void; isLoading: boolean; diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/FinalizeButton/FinalizeButton.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/FinalizeButton/FinalizeButton.tsx index efeb134b030..b9f460adafd 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/FinalizeButton/FinalizeButton.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/FinalizeButton/FinalizeButton.tsx @@ -6,22 +6,21 @@ import { defineMessages } from 'react-intl'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { ActionTypes } from '~redux/actionTypes.ts'; import { ActionForm } from '~shared/Fields/index.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { getMotionAssociatedActionId, mapPayload } from '~utils/actions.ts'; import { formatText } from '~utils/intl.ts'; import { useFinalizeSuccessCallback } from '~v5/common/ActionSidebar/partials/hooks.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import Button from '~v5/shared/Button/Button.tsx'; import IconButton from '~v5/shared/Button/IconButton.tsx'; const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.FinalizeButton'; -interface FinalizeButtonProps { +interface FinalizeButtonProps extends ICompletedMultiSigAction { multiSigId: string; isPending: boolean; setIsPending: (isPending: boolean) => void; isMotionOlderThanAWeek: boolean; - action: MultiSigAction; } const MSG = defineMessages({ diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/MultiSigWidget.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/MultiSigWidget.tsx index 5e196551125..053f50a45f3 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/MultiSigWidget.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/MultiSigWidget.tsx @@ -4,16 +4,15 @@ import React from 'react'; import { defineMessages } from 'react-intl'; import { useDomainThreshold } from '~hooks/multiSig/useDomainThreshold.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { notMaybe } from '~utils/arrays/index.ts'; import { formatText } from '~utils/intl.ts'; import { getRolesNeededForMultiSigAction } from '~utils/multiSig/index.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import MotionWidgetSkeleton from '~v5/shared/MotionWidgetSkeleton/MotionWidgetSkeleton.tsx'; import NotificationBanner from '~v5/shared/NotificationBanner/NotificationBanner.tsx'; import Stepper from '~v5/shared/Stepper/Stepper.tsx'; -import ApprovalStep from './partials/ApprovalStep/ApprovalStep.tsx'; -import FinalizeStep from './partials/FinalizeStep/FinalizeStep.tsx'; +import { MultiSigStep } from './partials/MultiSigStep/index.ts'; import { MultiSigState } from './types.ts'; import { getDomainIdForActionType, @@ -24,8 +23,7 @@ import { const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.MultiSigWidget'; -interface MultiSigWidgetProps { - action: MultiSigAction; +export interface MultiSigWidgetProps extends ICompletedMultiSigAction { variant: 'stepper' | 'standalone'; onMultiSigRejected?: () => void; } @@ -48,9 +46,10 @@ const MSG = defineMessages({ const MultiSigWidget: FC = ({ action, variant, + multiSigData, onMultiSigRejected, }) => { - const { type: actionType, multiSigData } = action; + const { type: actionType } = action; // this is only because managing permissions in a subdomain requires signees in the parent domain const requiredRoles = useMemo(() => { @@ -90,12 +89,13 @@ const MultiSigWidget: FC = ({ { key: MultiSigState.Approval, content: ( - ), heading: { @@ -105,11 +105,11 @@ const MultiSigWidget: FC = ({ { key: MultiSigState.Finalize, content: ( - ), heading: { diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/ApprovalStep/ApprovalStep.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/ApprovalStep.tsx similarity index 95% rename from src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/ApprovalStep/ApprovalStep.tsx rename to src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/ApprovalStep.tsx index 8c5060221eb..1d34dc064cc 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/ApprovalStep/ApprovalStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/ApprovalStep.tsx @@ -11,12 +11,13 @@ import useCurrentBlockTime from '~hooks/useCurrentBlockTime.ts'; import usePrevious from '~hooks/usePrevious.ts'; import Tooltip from '~shared/Extensions/Tooltip/Tooltip.tsx'; import SpinnerLoader from '~shared/Preloaders/SpinnerLoader.tsx'; -import { type MultiSigAction } from '~types/motions.ts'; import { type Threshold } from '~types/multiSig.ts'; import { notMaybe } from '~utils/arrays/index.ts'; import { formatText } from '~utils/intl.ts'; import { getDomainIdsForEligibleSignees } from '~utils/multiSig/index.ts'; import CancelButton from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/CancelButton/CancelButton.tsx'; +import MultiSigPills from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigPills/MultiSigPills.tsx'; +import ThresholdPassedBanner from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/ThresholdPassedBanner/ThresholdPassedBanner.tsx'; import { getAllUserSignatures, getDomainIdForActionType, @@ -30,23 +31,20 @@ import { import RemoveVoteButton from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/RemoveVoteButton/RemoveVoteButton.tsx'; import Signees from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/Signees/Signees.tsx'; import VoteButton from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/VoteButton/VoteButton.tsx'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import MenuWithStatusText from '~v5/shared/MenuWithStatusText/MenuWithStatusText.tsx'; import ProgressBar from '~v5/shared/ProgressBar/ProgressBar.tsx'; import { StatusTypes } from '~v5/shared/StatusText/consts.ts'; import StatusText from '~v5/shared/StatusText/StatusText.tsx'; -import MultiSigPills from '../MultiSigPills/MultiSigPills.tsx'; -import ThresholdPassedBanner from '../ThresholdPassedBanner/ThresholdPassedBanner.tsx'; - const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.MultiSigWidget.partials.ApprovalStep'; -interface ApprovalStepProps { +interface ApprovalStepProps extends ICompletedMultiSigAction { thresholdPerRole: Threshold; requiredRoles: ColonyRole[]; initiatorAddress: string; onMultiSigRejected?: () => void; - action: MultiSigAction; } const MSG = defineMessages({ @@ -117,8 +115,9 @@ const ApprovalStep: FC = ({ requiredRoles, onMultiSigRejected, action, + multiSigData, }) => { - const { multiSigData, type: actionType } = action; + const { type: actionType } = action; const { createdAt } = multiSigData; const { user } = useAppContext(); @@ -377,12 +376,14 @@ const ApprovalStep: FC = ({ setIsRemovingVote(isLoading); }} action={action} + multiSigData={multiSigData} /> ) : (
{ @@ -396,6 +397,7 @@ const ApprovalStep: FC = ({ {isOwner || isMotionOlderThanWeek ? ( { @@ -408,6 +410,7 @@ const ApprovalStep: FC = ({ ) : ( { diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/index.ts b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/index.ts new file mode 100644 index 00000000000..2647c34b40a --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/ApprovalStep/index.ts @@ -0,0 +1 @@ +export { default } from './ApprovalStep.tsx'; diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/FinalizeStep/FinalizeStep.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/FinalizeStep.tsx similarity index 97% rename from src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/FinalizeStep/FinalizeStep.tsx rename to src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/FinalizeStep.tsx index 35ddbb06cf4..1ee90a8a4a1 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/FinalizeStep/FinalizeStep.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/FinalizeStep.tsx @@ -5,7 +5,6 @@ import { FormattedDate, defineMessages } from 'react-intl'; import { type ColonyMultiSigFragment } from '~gql'; import useCurrentBlockTime from '~hooks/useCurrentBlockTime.ts'; import usePrevious from '~hooks/usePrevious.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { type Threshold } from '~types/multiSig.ts'; import { notMaybe } from '~utils/arrays/index.ts'; import { formatText } from '~utils/intl.ts'; @@ -17,6 +16,7 @@ import { getSignaturesPerRole, hasWeekPassed, } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/utils.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import { handleMotionCompleted } from '~v5/common/ActionSidebar/utils.ts'; import MenuWithStatusText from '~v5/shared/MenuWithStatusText/MenuWithStatusText.tsx'; import { StatusTypes } from '~v5/shared/StatusText/consts.ts'; @@ -137,11 +137,10 @@ const formatDate = (value: string | undefined) => { ); }; -interface FinalizeStepProps { +interface FinalizeStepProps extends ICompletedMultiSigAction { multiSigData: ColonyMultiSigFragment; initiatorAddress: string; thresholdPerRole: Threshold; - action: MultiSigAction; } const FinalizeStep: FC = ({ @@ -257,6 +256,7 @@ const FinalizeStep: FC = ({ setIsPending={setIsFinalizePending} multiSigId={multiSigData.nativeMultiSigId} action={action} + multiSigData={multiSigData} /> )}
diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/index.ts b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/index.ts new file mode 100644 index 00000000000..7e8efb921a9 --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/FinalizeStep/index.ts @@ -0,0 +1 @@ +export { default } from './FinalizeStep.tsx'; diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/index.ts b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/index.ts new file mode 100644 index 00000000000..30ceb9c841c --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/partials/MultiSigStep/index.ts @@ -0,0 +1,4 @@ +import Approval from './ApprovalStep/ApprovalStep.tsx'; +import Finalize from './FinalizeStep/FinalizeStep.tsx'; + +export const MultiSigStep = { Approval, Finalize }; diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/RemoveVoteButton/RemoveVoteButton.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/RemoveVoteButton/RemoveVoteButton.tsx index 52d1aa1e80b..193cd2652fa 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/RemoveVoteButton/RemoveVoteButton.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/RemoveVoteButton/RemoveVoteButton.tsx @@ -7,22 +7,21 @@ import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { MultiSigVote } from '~gql'; import { ActionTypes } from '~redux/actionTypes.ts'; import { type VoteOnMultiSigActionPayload } from '~redux/sagas/multiSig/voteOnMultiSig.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { getMotionAssociatedActionId } from '~utils/actions.ts'; import { extractColonyRoles } from '~utils/colonyRoles.ts'; import { extractColonyDomains } from '~utils/domains.ts'; import { formatText } from '~utils/intl.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import ActionButton from '~v5/shared/Button/ActionButton.tsx'; import { LoadingBehavior } from '~v5/shared/Button/types.ts'; const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.RemoveVoteButton'; -interface RemoveVoteButtonProps { +interface RemoveVoteButtonProps extends ICompletedMultiSigAction { requiredRoles: ColonyRole[]; handleLoadingChange: (isLoading: boolean) => void; isLoading: boolean; - action: MultiSigAction; } const MSG = defineMessages({ @@ -37,16 +36,13 @@ const RemoveVoteButton: FC = ({ handleLoadingChange, isLoading, action, + multiSigData: { nativeMultiSigId, nativeMultiSigDomainId }, }) => { const { colony } = useColonyContext(); const getRemoveVotePayload = (): VoteOnMultiSigActionPayload => { handleLoadingChange(true); - const { - multiSigData: { nativeMultiSigId, nativeMultiSigDomainId }, - } = action; - const associatedActionId = getMotionAssociatedActionId(action); return { diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/VoteButton/VoteButton.tsx b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/VoteButton/VoteButton.tsx index 72ab672e4cc..cbc576e4f92 100644 --- a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/VoteButton/VoteButton.tsx +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/partials/VoteButton/VoteButton.tsx @@ -7,19 +7,18 @@ import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { MultiSigVote } from '~gql'; import { ActionTypes } from '~redux/actionTypes.ts'; import { type VoteOnMultiSigActionPayload } from '~redux/sagas/multiSig/voteOnMultiSig.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { getMotionAssociatedActionId } from '~utils/actions.ts'; import { extractColonyRoles } from '~utils/colonyRoles.ts'; import { extractColonyDomains } from '~utils/domains.ts'; import { formatText } from '~utils/intl.ts'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import ActionButton from '~v5/shared/Button/ActionButton.tsx'; import { LoadingBehavior, type ButtonProps } from '~v5/shared/Button/types.ts'; const displayName = 'v5.common.ActionSidebar.partials.MultiSig.partials.VoteButton'; -interface VoteButtonProps { - action: MultiSigAction; +interface VoteButtonProps extends ICompletedMultiSigAction { requiredRoles: ColonyRole[]; voteType: Exclude; handleLoadingChange: (isLoading: boolean) => void; @@ -45,6 +44,7 @@ const VoteButton: FC = ({ handleLoadingChange, isLoading, action, + multiSigData: { nativeMultiSigId, nativeMultiSigDomainId }, }) => { const { colony } = useColonyContext(); @@ -56,10 +56,6 @@ const VoteButton: FC = ({ const getVotePayload = (): VoteOnMultiSigActionPayload => { handleLoadingChange(true); - const { - multiSigData: { nativeMultiSigId, nativeMultiSigDomainId }, - } = action; - const associatedActionId = getMotionAssociatedActionId(action); return { diff --git a/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts new file mode 100644 index 00000000000..6d282a3c31f --- /dev/null +++ b/src/components/v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts @@ -0,0 +1,5 @@ +import { type ICompletedAction } from '~v5/common/CompletedAction/types.ts'; + +export interface ICompletedMultiSigAction extends ICompletedAction { + multiSigData: NonNullable; +} diff --git a/src/components/v5/common/ActionSidebar/partials/forms/CreateDecisionForm/hooks.ts b/src/components/v5/common/ActionSidebar/partials/forms/CreateDecisionForm/hooks.ts index 7fc81593eaa..8d24a99fdec 100644 --- a/src/components/v5/common/ActionSidebar/partials/forms/CreateDecisionForm/hooks.ts +++ b/src/components/v5/common/ActionSidebar/partials/forms/CreateDecisionForm/hooks.ts @@ -1,14 +1,11 @@ import { Id } from '@colony/colony-js'; import { useCallback, useMemo } from 'react'; -import { useDispatch } from 'react-redux'; import { useAppContext } from '~context/AppContext/AppContext.ts'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { useDraftAgreement } from '~hooks/useDraftAgreement.ts'; -import { createDecisionAction } from '~redux/actionCreators/index.ts'; import { ActionTypes } from '~redux/index.ts'; import { mapPayload, pipe } from '~utils/actions.ts'; -import { type DecisionDraft } from '~utils/decisions.ts'; import { sanitizeHTML } from '~utils/strings.ts'; import useActionFormBaseHook from '~v5/common/ActionSidebar/hooks/useActionFormBaseHook.ts'; import { type ActionFormBaseProps } from '~v5/common/ActionSidebar/types.ts'; @@ -23,17 +20,9 @@ export const useCreateDecision = ( } = useColonyContext(); const { user } = useAppContext(); const walletAddress = user?.walletAddress || ''; - const dispatch = useDispatch(); const { getIsDraftAgreement } = useDraftAgreement(); - const handleSaveAgreementInLocalStorage = useCallback( - (values: DecisionDraft) => { - dispatch(createDecisionAction({ ...values, colonyAddress })); - }, - [colonyAddress, dispatch], - ); - useActionFormBaseHook({ actionType: ActionTypes.MOTION_CREATE_DECISION, validationSchema, @@ -51,14 +40,6 @@ export const useCreateDecision = ( mapPayload((payload: CreateDecisionFormValues) => { const safeDescription = sanitizeHTML(payload.description || ''); - handleSaveAgreementInLocalStorage({ - colonyAddress, - title: payload.title, - motionDomainId: Number(payload.createdIn), - description: safeDescription, - walletAddress, - }); - return { colonyAddress, colonyName, diff --git a/src/components/v5/common/CompletedAction/CompletedAction.tsx b/src/components/v5/common/CompletedAction/CompletedAction.tsx index 5901a4e742b..ad03a152ea6 100644 --- a/src/components/v5/common/CompletedAction/CompletedAction.tsx +++ b/src/components/v5/common/CompletedAction/CompletedAction.tsx @@ -4,7 +4,6 @@ import React from 'react'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { ColonyActionType } from '~gql'; import { ExtendedColonyActionType } from '~types/actions.ts'; -import { type ColonyAction } from '~types/graphql.ts'; import { getExtendedActionType } from '~utils/colonyActions.ts'; import PermissionSidebar from '../ActionSidebar/partials/ActionSidebarContent/partials/PermissionSidebar.tsx'; @@ -29,14 +28,11 @@ import TransferFunds from './partials/TransferFunds/index.ts'; import UnlockToken from './partials/UnlockToken/index.ts'; import UpgradeColonyObjective from './partials/UpgradeColonyObjective/index.ts'; import UpgradeColonyVersion from './partials/UpgradeColonyVersion/index.ts'; - -interface CompletedActionProps { - action: ColonyAction; -} +import { type ICompletedAction } from './types.ts'; const displayName = 'v5.common.CompletedAction'; -const CompletedAction = ({ action }: CompletedActionProps) => { +const CompletedAction = ({ action }: ICompletedAction) => { const { colony } = useColonyContext(); const actionType = getExtendedActionType(action, colony.metadata); @@ -127,8 +123,10 @@ const CompletedAction = ({ action }: CompletedActionProps) => { }; const getSidebarWidgetContent = () => { - if (action.isMultiSig) { - return ; + const { isMultiSig } = action; + + if (isMultiSig) { + return ; } switch (actionType) { @@ -151,9 +149,15 @@ const CompletedAction = ({ action }: CompletedActionProps) => { case ColonyActionType.ReleaseStagedPaymentsMotion: case ColonyActionType.MakeArbitraryTransactionsMotion: case ColonyActionType.EditExpenditureMotion: - case ColonyActionType.FundExpenditureMotion: + case ColonyActionType.FundExpenditureMotion: { + const { motionData } = action; + // @NOTE: Enabling expenditure-related motions above temporarily (action UI will be missing) - return ; + return motionData ? ( + + ) : null; + } + // @todo: reorganize folder structure after all of the advanced payments will be ready case ColonyActionType.CreateExpenditure: case ExtendedColonyActionType.StagedPayment: diff --git a/src/components/v5/common/CompletedAction/partials/ManageReputation/ManageReputation.tsx b/src/components/v5/common/CompletedAction/partials/ManageReputation/ManageReputation.tsx index 9086b76f70c..45d464f5b11 100644 --- a/src/components/v5/common/CompletedAction/partials/ManageReputation/ManageReputation.tsx +++ b/src/components/v5/common/CompletedAction/partials/ManageReputation/ManageReputation.tsx @@ -5,6 +5,7 @@ import React, { type FC } from 'react'; import { ADDRESS_ZERO, DEFAULT_TOKEN_DECIMALS } from '~constants'; import { Action } from '~constants/actions.ts'; +import { useActionContext } from '~context/ActionContext/ActionContext.ts'; import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts'; import { ColonyActionType } from '~gql'; import Numeral from '~shared/Numeral/Numeral.tsx'; @@ -24,7 +25,6 @@ import { TEAM_FIELD_NAME, AMOUNT_FIELD_NAME, } from '~v5/common/ActionSidebar/consts.ts'; -import useGetActionData from '~v5/common/ActionSidebar/hooks/useGetActionData.ts'; import { ModificationOption } from '~v5/common/ActionSidebar/partials/forms/ManageReputationForm/consts.ts'; import { useDecisionMethod } from '~v5/common/CompletedAction/hooks.ts'; import UserInfoPopover from '~v5/shared/UserInfoPopover/UserInfoPopover.tsx'; @@ -54,8 +54,11 @@ const displayName = 'v5.common.CompletedAction.partials.ManageReputation'; const ManageReputation: FC = ({ action }) => { const decisionMethod = useDecisionMethod(action); - const { colony } = useColonyContext(); - const { nativeToken } = colony; + + const { + colony: { nativeToken }, + } = useColonyContext(); + const { isMultiSig, isMotion, @@ -70,7 +73,8 @@ const ManageReputation: FC = ({ action }) => { multiSigData, } = action; - const { networkMotionState } = useGetActionData(transactionHash); + const { networkMotionState } = useActionContext(); + const motionFinished = networkMotionState === NetworkMotionState.Finalizable || networkMotionState === NetworkMotionState.Finalized || diff --git a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/MotionBox/MotionBox.tsx b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/MotionBox/MotionBox.tsx index 7b7714818e5..92ad7a15e1c 100644 --- a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/MotionBox/MotionBox.tsx +++ b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/MotionBox/MotionBox.tsx @@ -2,31 +2,21 @@ import { MotionState as NetworkMotionState } from '@colony/colony-js'; import React, { type FC, useEffect, useState, useMemo } from 'react'; import { useAppContext } from '~context/AppContext/AppContext.ts'; -import { type MotionAction } from '~types/motions.ts'; import { MotionState } from '~utils/colonyMotions.ts'; import useGetColonyAction from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts'; +import { MotionStep } from '~v5/common/ActionSidebar/partials/Motions/MotionStep/index.ts'; +import StakingStep from '~v5/common/ActionSidebar/partials/Motions/MotionStep/StakingStep/index.ts'; import MotionProvider from '~v5/common/ActionSidebar/partials/Motions/partials/MotionProvider/index.ts'; -import FinalizeStep from '~v5/common/ActionSidebar/partials/Motions/steps/FinalizeStep/FinalizeStep.tsx'; -import RevealStep from '~v5/common/ActionSidebar/partials/Motions/steps/RevealStep/RevealStep.tsx'; -import StakingStep from '~v5/common/ActionSidebar/partials/Motions/steps/StakingStep/index.ts'; -import VotingStep from '~v5/common/ActionSidebar/partials/Motions/steps/VotingStep/VotingStep.tsx'; import MotionWidgetSkeleton from '~v5/shared/MotionWidgetSkeleton/MotionWidgetSkeleton.tsx'; import { type Steps, CustomStep, type MotionBoxProps } from './types.ts'; const MotionBox: FC = ({ transactionId }) => { const { canInteract } = useAppContext(); - const { - action, - networkMotionState, - motionState, - loadingAction, - startPollingForAction, - stopPollingForAction, - refetchAction, - } = useGetColonyAction(transactionId); + const { action, networkMotionState, motionState, loadingAction } = + useGetColonyAction(transactionId); - const { motionData, rootHash } = action || {}; + const { motionData } = action || {}; const { motionStakes } = motionData || {}; @@ -38,18 +28,11 @@ const MotionBox: FC = ({ transactionId }) => { networkMotionState === NetworkMotionState.Failed; useEffect(() => { - startPollingForAction(); setActiveStepKey(networkMotionState); if (motionFinished) { setActiveStepKey(CustomStep.Finalize); } - return () => stopPollingForAction(); - }, [ - motionFinished, - networkMotionState, - startPollingForAction, - stopPollingForAction, - ]); + }, [motionFinished, networkMotionState]); const items = useMemo(() => { return [ @@ -64,41 +47,29 @@ const MotionBox: FC = ({ transactionId }) => { }, { key: NetworkMotionState.Submit, - content: ( - - ), + content: + action && motionData ? ( + + ) : null, isVisible: motionState === MotionState.Voting && motionStakes, }, { key: NetworkMotionState.Reveal, - content: ( - - ), + content: action ? ( + + ) : null, isVisible: activeStepKey === NetworkMotionState.Reveal && motionStakes, }, { key: CustomStep.Finalize, - content: motionState && ( - - ), + content: + action && motionData && motionState ? ( + + ) : null, isVisible: activeStepKey === CustomStep.Finalize && motionStakes && canInteract, }, @@ -107,22 +78,14 @@ const MotionBox: FC = ({ transactionId }) => { action, activeStepKey, canInteract, + motionData, motionStakes, motionState, networkMotionState, - refetchAction, - rootHash, - startPollingForAction, - stopPollingForAction, - transactionId, ]); - return !loadingAction ? ( - + return !loadingAction && action && motionData ? ( + {items.map(({ key, content, isVisible }) => ( {isVisible && content} ))} diff --git a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/PaymentBuilderWidget.tsx b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/PaymentBuilderWidget.tsx index d724447b0b2..fd23ee1cf78 100644 --- a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/PaymentBuilderWidget.tsx +++ b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/PaymentBuilderWidget.tsx @@ -22,7 +22,6 @@ import { getExpenditureCreatingActionId, } from '~utils/expenditures.ts'; import { formatText } from '~utils/intl.ts'; -import { isMultiSig } from '~utils/multiSig/index.ts'; import { CacheQueryKeys, getSafePollingInterval, @@ -326,10 +325,11 @@ const PaymentBuilderWidget: FC = ({ action }) => { return ; } - if (isMultiSig(fundingAction)) { + if (fundingAction && fundingAction.multiSigData) { return ( { setExpectedStepKey(null); }} diff --git a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/partials/MultiSigFunding.tsx b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/partials/MultiSigFunding.tsx index 521d6860dd8..d05b825b26b 100644 --- a/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/partials/MultiSigFunding.tsx +++ b/src/components/v5/common/CompletedAction/partials/PaymentBuilder/partials/PaymentBuilderWidget/partials/MultiSigFunding.tsx @@ -2,22 +2,22 @@ import { Extension } from '@colony/colony-js'; import React, { type FC } from 'react'; import useExtensionData from '~hooks/useExtensionData.ts'; -import { type MultiSigAction } from '~types/motions.ts'; import { isInstalledExtensionData } from '~utils/extensions.ts'; import MultiSigWidget from '~v5/common/ActionSidebar/partials/MultiSigSidebar/partials/MultiSigWidget/MultiSigWidget.tsx'; +import { type ICompletedMultiSigAction } from '~v5/common/ActionSidebar/partials/MultiSigSidebar/types.ts'; import UninstalledMessage from '~v5/common/UninstalledMessage/UninstalledMessage.tsx'; import MotionWidgetSkeleton from '~v5/shared/MotionWidgetSkeleton/MotionWidgetSkeleton.tsx'; const displayName = 'v5.common.CompletedAction.partials.PaymentBuilderWidget.partials.MultiSigFunding'; -interface MultiSigFundingProps { - action: MultiSigAction; +interface MultiSigFundingProps extends ICompletedMultiSigAction { onMultiSigRejected?: () => void; } const MultiSigFunding: FC = ({ action, + multiSigData, onMultiSigRejected, }) => { const { extensionData, loading } = useExtensionData( @@ -38,6 +38,7 @@ const MultiSigFunding: FC = ({ return ( diff --git a/src/components/v5/common/CompletedAction/types.ts b/src/components/v5/common/CompletedAction/types.ts new file mode 100644 index 00000000000..2736181924b --- /dev/null +++ b/src/components/v5/common/CompletedAction/types.ts @@ -0,0 +1,5 @@ +import { type IActionContext } from '~context/ActionContext/ActionContext.ts'; + +export interface ICompletedAction { + action: NonNullable; +} diff --git a/src/components/v5/frame/ColonyHome/ColonyHome.tsx b/src/components/v5/frame/ColonyHome/ColonyHome.tsx index 178ddab293d..ae282b86234 100644 --- a/src/components/v5/frame/ColonyHome/ColonyHome.tsx +++ b/src/components/v5/frame/ColonyHome/ColonyHome.tsx @@ -9,7 +9,7 @@ import { COLONY_ACTIVITY_ROUTE, } from '~routes/index.ts'; import { formatText } from '~utils/intl.ts'; -import useGetActionData from '~v5/common/ActionSidebar/hooks/useGetActionData.ts'; +import useGetActionFormData from '~v5/common/ActionSidebar/hooks/useGetActionFormData.ts'; import Link from '~v5/shared/Link/index.ts'; import TeamFilter from '~v5/shared/TeamFilter/TeamFilter.tsx'; @@ -25,7 +25,7 @@ const ColonyHome = () => { const [selectedAction, setSelectedAction] = useState( undefined, ); - const { defaultValues } = useGetActionData(selectedAction || undefined); + const { defaultValues } = useGetActionFormData(selectedAction); return (
; + loadingAction: boolean; + motionData: ColonyAction['motionData']; + multiSigData: ColonyAction['multiSigData']; + expenditure: OptionalValue; + loadingExpenditure: boolean; + motionState: MotionState | undefined; + refetchMotionState: () => void; + isValidTransactionHash: boolean; + networkMotionState: NetworkMotionState; + startActionPoll: () => void; + stopActionPoll: () => void; + isMotion: boolean; + isMultiSig: boolean; + isExpenditure: boolean; +} + +export const ActionContext = createContext({ + transactionHash: null, + action: null, + loadingAction: false, + motionData: null, + multiSigData: null, + expenditure: null, + loadingExpenditure: false, + motionState: undefined, + refetchMotionState: () => {}, + isValidTransactionHash: false, + networkMotionState: NetworkMotionState.Null, + startActionPoll: () => {}, + stopActionPoll: () => {}, + isMotion: false, + isMultiSig: false, + isExpenditure: false, +}); + +export const useActionContext = () => { + const actionContext = useContext(ActionContext); + + if (!actionContext) { + throw new Error( + 'This hook must be used within the "ActionContext" provider', + ); + } + + return actionContext; +}; diff --git a/src/context/ActionContext/ActionContextProvider.tsx b/src/context/ActionContext/ActionContextProvider.tsx new file mode 100644 index 00000000000..6108804b7c8 --- /dev/null +++ b/src/context/ActionContext/ActionContextProvider.tsx @@ -0,0 +1,66 @@ +import React, { type PropsWithChildren, useMemo } from 'react'; +import { useSearchParams } from 'react-router-dom'; + +import { TX_SEARCH_PARAM } from '~routes'; +import useGetColonyAction from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts'; + +import { ActionContext, type IActionContext } from './ActionContext.ts'; + +const ActionContextProvider: React.FC = ({ children }) => { + const [searchParams] = useSearchParams(); + + const transactionHash = searchParams?.get(TX_SEARCH_PARAM); + + const { + action, + loadingAction, + motionState, + refetchMotionState, + isValidTransactionHash, + networkMotionState, + startActionPoll, + stopActionPoll, + expenditure, + loadingExpenditure, + } = useGetColonyAction(transactionHash); + + const value = useMemo( + () => ({ + transactionHash, + action, + loadingAction, + expenditure, + motionData: action?.motionData, + multiSigData: action?.multiSigData, + loadingExpenditure, + motionState, + refetchMotionState, + isValidTransactionHash, + networkMotionState, + startActionPoll, + stopActionPoll, + isMotion: !!action?.motionData, + isMultiSig: !!action?.multiSigData, + isExpenditure: !!action?.expenditure, + }), + [ + action, + expenditure, + isValidTransactionHash, + loadingAction, + loadingExpenditure, + motionState, + networkMotionState, + refetchMotionState, + startActionPoll, + stopActionPoll, + transactionHash, + ], + ); + + return ( + {children} + ); +}; + +export default ActionContextProvider; diff --git a/src/graphql/generated.ts b/src/graphql/generated.ts index 81898394053..b937a963314 100644 --- a/src/graphql/generated.ts +++ b/src/graphql/generated.ts @@ -10397,6 +10397,11 @@ export type CreateAnnotationMutationVariables = Exact<{ export type CreateAnnotationMutation = { __typename?: 'Mutation', createAnnotation?: { __typename?: 'Annotation', id: string } | null }; +export type OnCreateAnnotationSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type OnCreateAnnotationSubscription = { __typename?: 'Subscription', onCreateAnnotation?: { __typename?: 'Annotation', createdAt: string, message: string } | null }; + export type CreateKycLinksMutationVariables = Exact<{ fullName: Scalars['String']; email: Scalars['String']; @@ -10655,10 +10660,10 @@ export type OnCreateColonyActionMetadataSubscriptionVariables = Exact<{ [key: st export type OnCreateColonyActionMetadataSubscription = { __typename?: 'Subscription', onCreateColonyActionMetadata?: { __typename?: 'ColonyActionMetadata', updatedAt: string } | null }; -export type OnUpdateColonyMotionSubscriptionVariables = Exact<{ [key: string]: never; }>; +export type OnUpdateColonyActionMetadataSubscriptionVariables = Exact<{ [key: string]: never; }>; -export type OnUpdateColonyMotionSubscription = { __typename?: 'Subscription', onUpdateColonyAction?: { __typename?: 'ColonyAction', motionData?: { __typename?: 'ColonyMotion', remainingStakes: Array, userMinStake: string, requiredStake: string, nativeMotionDomainId: string, isFinalized: boolean, skillRep: string, repSubmitted: string, hasObjection: boolean, isDecision: boolean, transactionHash: string, createdAt: string, createdBy: string, expenditureSlotIds?: Array | null, databaseMotionId: string, motionId: string, motionStakes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } }, usersStakes: Array<{ __typename?: 'UserMotionStakes', address: string, stakes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } } }>, motionDomain: { __typename?: 'Domain', id: string, nativeId: number, isRoot: boolean, nativeFundingPotId: number, nativeSkillId: string, reputation?: string | null, reputationPercentage?: string | null, metadata?: { __typename?: 'DomainMetadata', name: string, color: DomainColor, description?: string | null, id: string, changelog?: Array<{ __typename?: 'DomainMetadataChangelog', transactionHash: string, oldName: string, newName: string, oldColor: DomainColor, newColor: DomainColor, oldDescription?: string | null, newDescription?: string | null }> | null } | null }, stakerRewards: Array<{ __typename?: 'StakerRewards', address: string, isClaimed: boolean, rewards: { __typename?: 'MotionStakeValues', yay: string, nay: string } }>, voterRewards?: { __typename?: 'ModelVoterRewardsHistoryConnection', items: Array<{ __typename?: 'VoterRewardsHistory', userAddress: string, amount: string, user: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } } | null> } | null, voterRecord: Array<{ __typename?: 'VoterRecord', address: string, voteCount: string, vote?: number | null }>, revealedVotes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } }, motionStateHistory: { __typename?: 'MotionStateHistory', hasVoted: boolean, hasPassed: boolean, hasFailed: boolean, hasFailedNotFinalizable: boolean, inRevealPhase: boolean, yaySideFullyStakedAt?: string | null, naySideFullyStakedAt?: string | null, allVotesSubmittedAt?: string | null, allVotesRevealedAt?: string | null, endedAt?: string | null, finalizedAt?: string | null }, messages?: { __typename?: 'ModelMotionMessageConnection', items: Array<{ __typename?: 'MotionMessage', initiatorAddress: string, name: string, messageKey: string, vote?: string | null, amount?: string | null, createdAt: string, initiatorUser?: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } | null } | null> } | null, objectionAnnotation?: { __typename?: 'Annotation', createdAt: string, message: string } | null, action?: { __typename?: 'ColonyAction', type: ColonyActionType } | null } | null } | null }; +export type OnUpdateColonyActionMetadataSubscription = { __typename?: 'Subscription', onUpdateColonyActionMetadata?: { __typename?: 'ColonyActionMetadata', id: string } | null }; export type GetDomainBalanceQueryVariables = Exact<{ input: DomainBalanceArguments; @@ -10926,6 +10931,26 @@ export type GetMotionTimeoutPeriodsQueryVariables = Exact<{ export type GetMotionTimeoutPeriodsQuery = { __typename?: 'Query', getMotionTimeoutPeriods?: { __typename?: 'GetMotionTimeoutPeriodsReturn', timeLeftToStake: string, timeLeftToVote: string, timeLeftToReveal: string, timeLeftToEscalate: string } | null }; +export type OnUpdateColonyMotionSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type OnUpdateColonyMotionSubscription = { __typename?: 'Subscription', onUpdateColonyMotion?: { __typename?: 'ColonyMotion', remainingStakes: Array, userMinStake: string, requiredStake: string, nativeMotionDomainId: string, isFinalized: boolean, skillRep: string, repSubmitted: string, hasObjection: boolean, isDecision: boolean, transactionHash: string, createdAt: string, createdBy: string, expenditureSlotIds?: Array | null, databaseMotionId: string, motionId: string, motionStakes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } }, usersStakes: Array<{ __typename?: 'UserMotionStakes', address: string, stakes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } } }>, motionDomain: { __typename?: 'Domain', id: string, nativeId: number, isRoot: boolean, nativeFundingPotId: number, nativeSkillId: string, reputation?: string | null, reputationPercentage?: string | null, metadata?: { __typename?: 'DomainMetadata', name: string, color: DomainColor, description?: string | null, id: string, changelog?: Array<{ __typename?: 'DomainMetadataChangelog', transactionHash: string, oldName: string, newName: string, oldColor: DomainColor, newColor: DomainColor, oldDescription?: string | null, newDescription?: string | null }> | null } | null }, stakerRewards: Array<{ __typename?: 'StakerRewards', address: string, isClaimed: boolean, rewards: { __typename?: 'MotionStakeValues', yay: string, nay: string } }>, voterRewards?: { __typename?: 'ModelVoterRewardsHistoryConnection', items: Array<{ __typename?: 'VoterRewardsHistory', userAddress: string, amount: string, user: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } } | null> } | null, voterRecord: Array<{ __typename?: 'VoterRecord', address: string, voteCount: string, vote?: number | null }>, revealedVotes: { __typename?: 'MotionStakes', raw: { __typename?: 'MotionStakeValues', yay: string, nay: string }, percentage: { __typename?: 'MotionStakeValues', yay: string, nay: string } }, motionStateHistory: { __typename?: 'MotionStateHistory', hasVoted: boolean, hasPassed: boolean, hasFailed: boolean, hasFailedNotFinalizable: boolean, inRevealPhase: boolean, yaySideFullyStakedAt?: string | null, naySideFullyStakedAt?: string | null, allVotesSubmittedAt?: string | null, allVotesRevealedAt?: string | null, endedAt?: string | null, finalizedAt?: string | null }, messages?: { __typename?: 'ModelMotionMessageConnection', items: Array<{ __typename?: 'MotionMessage', initiatorAddress: string, name: string, messageKey: string, vote?: string | null, amount?: string | null, createdAt: string, initiatorUser?: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } | null } | null> } | null, objectionAnnotation?: { __typename?: 'Annotation', createdAt: string, message: string } | null, action?: { __typename?: 'ColonyAction', type: ColonyActionType } | null } | null }; + +export type OnUpdateColonyMultiSigSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type OnUpdateColonyMultiSigSubscription = { __typename?: 'Subscription', onUpdateColonyMultiSig?: { __typename?: 'ColonyMultiSig', id: string, nativeMultiSigId: string, createdAt: string, multiSigDomainId: string, nativeMultiSigDomainId: string, requiredPermissions: number, transactionHash: string, isExecuted: boolean, hasActionCompleted: boolean, isRejected: boolean, isDecision: boolean, executedAt?: string | null, executedBy?: string | null, rejectedAt?: string | null, rejectedBy?: string | null, multiSigDomain: { __typename?: 'Domain', id: string, nativeId: number, isRoot: boolean, nativeFundingPotId: number, nativeSkillId: string, reputation?: string | null, reputationPercentage?: string | null, metadata?: { __typename?: 'DomainMetadata', name: string, color: DomainColor, description?: string | null, id: string, changelog?: Array<{ __typename?: 'DomainMetadataChangelog', transactionHash: string, oldName: string, newName: string, oldColor: DomainColor, newColor: DomainColor, oldDescription?: string | null, newDescription?: string | null }> | null } | null }, signatures?: { __typename?: 'ModelMultiSigUserSignatureConnection', items: Array<{ __typename?: 'MultiSigUserSignature', id: string, role: number, userAddress: string, multiSigId: string, vote: MultiSigVote, createdAt: string, updatedAt: string, user: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } } | null> } | null, executedByUser?: { __typename?: 'User', walletAddress: string, profile?: { __typename?: 'Profile', displayName?: string | null, displayNameChanged?: string | null, avatar?: string | null, thumbnail?: string | null } | null } | null, rejectedByUser?: { __typename?: 'User', walletAddress: string, profile?: { __typename?: 'Profile', displayName?: string | null, displayNameChanged?: string | null, avatar?: string | null, thumbnail?: string | null } | null } | null } | null }; + +export type OnCreateMultiSigUserSignatureSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type OnCreateMultiSigUserSignatureSubscription = { __typename?: 'Subscription', onCreateMultiSigUserSignature?: { __typename?: 'MultiSigUserSignature', id: string, role: number, userAddress: string, multiSigId: string, vote: MultiSigVote, createdAt: string, updatedAt: string, user: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } } | null }; + +export type OnDeleteMultiSigUserSignatureSubscriptionVariables = Exact<{ [key: string]: never; }>; + + +export type OnDeleteMultiSigUserSignatureSubscription = { __typename?: 'Subscription', onDeleteMultiSigUserSignature?: { __typename?: 'MultiSigUserSignature', id: string, role: number, userAddress: string, multiSigId: string, vote: MultiSigVote, createdAt: string, updatedAt: string, user: { __typename?: 'User', bridgeCustomerId?: string | null, walletAddress: string, profile?: { __typename?: 'Profile', avatar?: string | null, bio?: string | null, displayName?: string | null, displayNameChanged?: string | null, email?: string | null, location?: string | null, thumbnail?: string | null, website?: string | null, preferredCurrency?: SupportedCurrencies | null, isAutoOfframpEnabled?: boolean | null, meta?: { __typename?: 'ProfileMetadata', metatransactionsEnabled?: boolean | null, decentralizedModeEnabled?: boolean | null, customRpc?: string | null } | null } | null, privateBetaInviteCode?: { __typename?: 'PrivateBetaInviteCode', id: string, shareableInvites?: number | null } | null, notificationsData?: { __typename?: 'NotificationsData', magicbellUserId: string, notificationsDisabled: boolean, mutedColonyAddresses: Array, paymentNotificationsDisabled: boolean, mentionNotificationsDisabled: boolean, adminNotificationsDisabled: boolean } | null } } | null }; + export type GetCurrentNetworkInverseFeeQueryVariables = Exact<{ [key: string]: never; }>; @@ -12340,6 +12365,35 @@ export function useCreateAnnotationMutation(baseOptions?: Apollo.MutationHookOpt export type CreateAnnotationMutationHookResult = ReturnType; export type CreateAnnotationMutationResult = Apollo.MutationResult; export type CreateAnnotationMutationOptions = Apollo.BaseMutationOptions; +export const OnCreateAnnotationDocument = gql` + subscription OnCreateAnnotation { + onCreateAnnotation { + ...Annotation + } +} + ${AnnotationFragmentDoc}`; + +/** + * __useOnCreateAnnotationSubscription__ + * + * To run a query within a React component, call `useOnCreateAnnotationSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnCreateAnnotationSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useOnCreateAnnotationSubscription({ + * variables: { + * }, + * }); + */ +export function useOnCreateAnnotationSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(OnCreateAnnotationDocument, options); + } +export type OnCreateAnnotationSubscriptionHookResult = ReturnType; +export type OnCreateAnnotationSubscriptionResult = Apollo.SubscriptionResult; export const CreateKycLinksDocument = gql` mutation CreateKYCLinks($fullName: String!, $email: String!) { bridgeXYZMutation( @@ -13600,37 +13654,35 @@ export function useOnCreateColonyActionMetadataSubscription(baseOptions?: Apollo } export type OnCreateColonyActionMetadataSubscriptionHookResult = ReturnType; export type OnCreateColonyActionMetadataSubscriptionResult = Apollo.SubscriptionResult; -export const OnUpdateColonyMotionDocument = gql` - subscription OnUpdateColonyMotion { - onUpdateColonyAction { - motionData { - ...ColonyMotion - } +export const OnUpdateColonyActionMetadataDocument = gql` + subscription OnUpdateColonyActionMetadata { + onUpdateColonyActionMetadata { + id } } - ${ColonyMotionFragmentDoc}`; + `; /** - * __useOnUpdateColonyMotionSubscription__ + * __useOnUpdateColonyActionMetadataSubscription__ * - * To run a query within a React component, call `useOnUpdateColonyMotionSubscription` and pass it any options that fit your needs. - * When your component renders, `useOnUpdateColonyMotionSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useOnUpdateColonyActionMetadataSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnUpdateColonyActionMetadataSubscription` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useOnUpdateColonyMotionSubscription({ + * const { data, loading, error } = useOnUpdateColonyActionMetadataSubscription({ * variables: { * }, * }); */ -export function useOnUpdateColonyMotionSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { +export function useOnUpdateColonyActionMetadataSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useSubscription(OnUpdateColonyMotionDocument, options); + return Apollo.useSubscription(OnUpdateColonyActionMetadataDocument, options); } -export type OnUpdateColonyMotionSubscriptionHookResult = ReturnType; -export type OnUpdateColonyMotionSubscriptionResult = Apollo.SubscriptionResult; +export type OnUpdateColonyActionMetadataSubscriptionHookResult = ReturnType; +export type OnUpdateColonyActionMetadataSubscriptionResult = Apollo.SubscriptionResult; export const GetDomainBalanceDocument = gql` query GetDomainBalance($input: DomainBalanceArguments!) { getDomainBalance(input: $input) { @@ -15099,6 +15151,122 @@ export function useGetMotionTimeoutPeriodsLazyQuery(baseOptions?: Apollo.LazyQue export type GetMotionTimeoutPeriodsQueryHookResult = ReturnType; export type GetMotionTimeoutPeriodsLazyQueryHookResult = ReturnType; export type GetMotionTimeoutPeriodsQueryResult = Apollo.QueryResult; +export const OnUpdateColonyMotionDocument = gql` + subscription OnUpdateColonyMotion { + onUpdateColonyMotion { + ...ColonyMotion + } +} + ${ColonyMotionFragmentDoc}`; + +/** + * __useOnUpdateColonyMotionSubscription__ + * + * To run a query within a React component, call `useOnUpdateColonyMotionSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnUpdateColonyMotionSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useOnUpdateColonyMotionSubscription({ + * variables: { + * }, + * }); + */ +export function useOnUpdateColonyMotionSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(OnUpdateColonyMotionDocument, options); + } +export type OnUpdateColonyMotionSubscriptionHookResult = ReturnType; +export type OnUpdateColonyMotionSubscriptionResult = Apollo.SubscriptionResult; +export const OnUpdateColonyMultiSigDocument = gql` + subscription OnUpdateColonyMultiSig { + onUpdateColonyMultiSig { + ...ColonyMultiSig + } +} + ${ColonyMultiSigFragmentDoc}`; + +/** + * __useOnUpdateColonyMultiSigSubscription__ + * + * To run a query within a React component, call `useOnUpdateColonyMultiSigSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnUpdateColonyMultiSigSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useOnUpdateColonyMultiSigSubscription({ + * variables: { + * }, + * }); + */ +export function useOnUpdateColonyMultiSigSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(OnUpdateColonyMultiSigDocument, options); + } +export type OnUpdateColonyMultiSigSubscriptionHookResult = ReturnType; +export type OnUpdateColonyMultiSigSubscriptionResult = Apollo.SubscriptionResult; +export const OnCreateMultiSigUserSignatureDocument = gql` + subscription OnCreateMultiSigUserSignature { + onCreateMultiSigUserSignature { + ...MultiSigUserSignature + } +} + ${MultiSigUserSignatureFragmentDoc}`; + +/** + * __useOnCreateMultiSigUserSignatureSubscription__ + * + * To run a query within a React component, call `useOnCreateMultiSigUserSignatureSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnCreateMultiSigUserSignatureSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useOnCreateMultiSigUserSignatureSubscription({ + * variables: { + * }, + * }); + */ +export function useOnCreateMultiSigUserSignatureSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(OnCreateMultiSigUserSignatureDocument, options); + } +export type OnCreateMultiSigUserSignatureSubscriptionHookResult = ReturnType; +export type OnCreateMultiSigUserSignatureSubscriptionResult = Apollo.SubscriptionResult; +export const OnDeleteMultiSigUserSignatureDocument = gql` + subscription OnDeleteMultiSigUserSignature { + onDeleteMultiSigUserSignature { + ...MultiSigUserSignature + } +} + ${MultiSigUserSignatureFragmentDoc}`; + +/** + * __useOnDeleteMultiSigUserSignatureSubscription__ + * + * To run a query within a React component, call `useOnDeleteMultiSigUserSignatureSubscription` and pass it any options that fit your needs. + * When your component renders, `useOnDeleteMultiSigUserSignatureSubscription` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the subscription, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useOnDeleteMultiSigUserSignatureSubscription({ + * variables: { + * }, + * }); + */ +export function useOnDeleteMultiSigUserSignatureSubscription(baseOptions?: Apollo.SubscriptionHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useSubscription(OnDeleteMultiSigUserSignatureDocument, options); + } +export type OnDeleteMultiSigUserSignatureSubscriptionHookResult = ReturnType; +export type OnDeleteMultiSigUserSignatureSubscriptionResult = Apollo.SubscriptionResult; export const GetCurrentNetworkInverseFeeDocument = gql` query GetCurrentNetworkInverseFee { listCurrentNetworkInverseFees(limit: 1) { diff --git a/src/graphql/mutations/annotation.graphql b/src/graphql/mutations/annotation.graphql index 94c1f6b52b3..889ea3c4f9a 100644 --- a/src/graphql/mutations/annotation.graphql +++ b/src/graphql/mutations/annotation.graphql @@ -3,3 +3,9 @@ mutation CreateAnnotation($input: CreateAnnotationInput!) { id } } + +subscription OnCreateAnnotation { + onCreateAnnotation { + ...Annotation + } +} diff --git a/src/graphql/queries/actions.graphql b/src/graphql/queries/actions.graphql index 0270159a58b..22c79a35eb5 100644 --- a/src/graphql/queries/actions.graphql +++ b/src/graphql/queries/actions.graphql @@ -94,10 +94,8 @@ subscription OnCreateColonyActionMetadata { } } -subscription OnUpdateColonyMotion { - onUpdateColonyAction { - motionData { - ...ColonyMotion - } +subscription OnUpdateColonyActionMetadata { + onUpdateColonyActionMetadata { + id } } diff --git a/src/graphql/queries/motions.graphql b/src/graphql/queries/motions.graphql index 4b9e5f2a3d7..9ca1874067a 100644 --- a/src/graphql/queries/motions.graphql +++ b/src/graphql/queries/motions.graphql @@ -26,3 +26,9 @@ query GetMotionTimeoutPeriods($input: GetMotionTimeoutPeriodsInput!) { timeLeftToEscalate } } + +subscription OnUpdateColonyMotion { + onUpdateColonyMotion { + ...ColonyMotion + } +} diff --git a/src/graphql/queries/multiSig.graphql b/src/graphql/queries/multiSig.graphql new file mode 100644 index 00000000000..33cac88188a --- /dev/null +++ b/src/graphql/queries/multiSig.graphql @@ -0,0 +1,17 @@ +subscription OnUpdateColonyMultiSig { + onUpdateColonyMultiSig { + ...ColonyMultiSig + } +} + +subscription OnCreateMultiSigUserSignature { + onCreateMultiSigUserSignature { + ...MultiSigUserSignature + } +} + +subscription OnDeleteMultiSigUserSignature { + onDeleteMultiSigUserSignature { + ...MultiSigUserSignature + } +} diff --git a/src/redux/sagas/motions/createDecisionMotion.ts b/src/redux/sagas/motions/createDecisionMotion.ts index 4883658f57e..580f53ac0b1 100644 --- a/src/redux/sagas/motions/createDecisionMotion.ts +++ b/src/redux/sagas/motions/createDecisionMotion.ts @@ -23,7 +23,11 @@ import { getTxChannel, } from '../transactions/index.ts'; import { getColonyDecisionId } from '../utils/decisionMotion.ts'; -import { getColonyManager, initiateTransaction } from '../utils/index.ts'; +import { + createActionMetadataInDB, + getColonyManager, + initiateTransaction, +} from '../utils/index.ts'; function* createDecisionMotion({ payload: { @@ -79,11 +83,9 @@ function* createDecisionMotion({ // setup batch ids and channels const batchKey = TRANSACTION_METHODS.CreateMotion; - const { createMotion /* annotateMotion */ } = yield call( - createTransactionChannels, - metaId, - ['createMotion' /* 'annotateMotion' */], - ); + const { createMotion } = yield call(createTransactionChannels, metaId, [ + 'createMotion', + ]); // create transactions yield fork(createTransaction, createMotion.id, { @@ -108,21 +110,7 @@ function* createDecisionMotion({ ready: false, }); - // yield fork(createTransaction, annotateMotion.id, { - // context: ClientType.ColonyClient, - // methodName: 'annotateTransaction', - // identifier: colonyAddress, - // params: [], - // group: { - // key: batchKey, - // id: metaId, - // index: 1, - // }, - // ready: false, - // }); - yield takeFrom(createMotion.channel, ActionTypes.TRANSACTION_CREATED); - // yield takeFrom(annotateMotion.channel, ActionTypes.TRANSACTION_CREATED); yield initiateTransaction(createMotion.id); @@ -154,19 +142,8 @@ function* createDecisionMotion({ }), ); - // yield transactionSetPending(annotateMotion.id); - - // yield put( - // transactionAddParams(annotateMotion.id, [ - // txHash, - // JSON.stringify(decision), - // ]), - // ); - - // yield put(transactionReady(annotateMotion.id)); + yield createActionMetadataInDB(txHash, { customTitle: title }); - // yield waitForTxResult(annotateMotion.channel); - // setTxHash?.(txHash); yield put({ diff --git a/src/redux/sagas/motions/rootMotion.ts b/src/redux/sagas/motions/rootMotion.ts index 313ceaa233a..df95b30b6ec 100644 --- a/src/redux/sagas/motions/rootMotion.ts +++ b/src/redux/sagas/motions/rootMotion.ts @@ -176,6 +176,7 @@ function* createRootMotionSaga({ } yield takeFrom(createMotion.channel, ActionTypes.TRANSACTION_CREATED); + if (annotationMessage) { yield takeFrom( annotateRootMotion.channel, diff --git a/src/routes/ColonyRoute.tsx b/src/routes/ColonyRoute.tsx index b117c81f97a..912e31e2a0c 100644 --- a/src/routes/ColonyRoute.tsx +++ b/src/routes/ColonyRoute.tsx @@ -2,6 +2,7 @@ import React, { useEffect } from 'react'; import { defineMessages } from 'react-intl'; import { Navigate, Outlet, useParams } from 'react-router-dom'; +import ActionContextProvider from '~context/ActionContext/ActionContextProvider.tsx'; import ActionSidebarContextProvider from '~context/ActionSidebarContext/ActionSidebarContextProvider.tsx'; import { useAppContext } from '~context/AppContext/AppContext.ts'; import { useBreadcrumbsContext } from '~context/BreadcrumbsContext/BreadcrumbsContext.ts'; @@ -112,9 +113,11 @@ const ColonyRoute = () => { - - - + + + + + diff --git a/src/types/motions.ts b/src/types/motions.ts index 301c498caf5..57de2142258 100644 --- a/src/types/motions.ts +++ b/src/types/motions.ts @@ -1,23 +1,4 @@ -import { - type ColonyAction, - type ColonyMotion, - type ColonyMultiSig, -} from './graphql.ts'; - export enum StakeSide { Motion = 'MOTION', Objection = 'OBJECTION', } - -/** - * A "MotionAction" is a ColonyAction with MotionData defined (i.e. a motion). - */ - -export interface MotionAction extends Omit { - motionData: ColonyMotion; -} - -export type MultiSigAction = Omit< - ColonyAction, - 'multiSigData' | 'multiSigId' -> & { multiSigData: ColonyMultiSig; multiSigId: string }; diff --git a/src/utils/actions.ts b/src/utils/actions.ts index 9519f13d313..cdb9dc9624f 100644 --- a/src/utils/actions.ts +++ b/src/utils/actions.ts @@ -1,7 +1,8 @@ import pipe from 'lodash/fp/pipe'; import { type ActionTypes, type UniqueActionType } from '~redux/index.ts'; -import { type MotionAction, type MultiSigAction } from '~types/motions.ts'; +import { type OptionalValue } from '~types'; +import { type ColonyAction } from '~types/graphql.ts'; export type ActionTransformFnType = ( arg0: UniqueActionType, @@ -50,7 +51,7 @@ export const getFormAction = ( ) => `${action}_${actionType}`; export const getMotionAssociatedActionId = ( - action?: MotionAction | MultiSigAction | null, + action: OptionalValue, ) => { if (!action) return ''; diff --git a/src/utils/multiSig/index.ts b/src/utils/multiSig/index.ts index 5c9fc30f1a4..383baf904f7 100644 --- a/src/utils/multiSig/index.ts +++ b/src/utils/multiSig/index.ts @@ -2,8 +2,7 @@ import { Id, type ColonyRole } from '@colony/colony-js'; import { PERMISSIONS_NEEDED_FOR_ACTION } from '~constants/actions.ts'; import { ColonyActionType, type ColonyActionFragment } from '~gql'; -import { type Colony, type ColonyAction } from '~types/graphql.ts'; -import { type MultiSigAction } from '~types/motions.ts'; +import { type Colony } from '~types/graphql.ts'; import { MotionState } from '../colonyMotions.ts'; import { extractColonyRoles } from '../colonyRoles.ts'; @@ -121,10 +120,6 @@ export const getMultiSigPayload = ( isMultiSig: isMultiSigFlag, }); -export function isMultiSig(action: ColonyAction): action is MultiSigAction { - return !!action.multiSigData && !!action.multiSigId; -} - export const getDomainIdsForEligibleSignees = (domainId: number): number[] => { return domainId === Id.RootDomain ? [Id.RootDomain] diff --git a/src/utils/web3/index.ts b/src/utils/web3/index.ts index 8038ccc2c2f..48e574b3804 100644 --- a/src/utils/web3/index.ts +++ b/src/utils/web3/index.ts @@ -3,6 +3,7 @@ import BN from 'bn.js'; import { NETWORK_DATA } from '~constants/index.ts'; import { type TransactionError } from '~redux/immutable/Transaction.ts'; +import { type OptionalValue } from '~types'; import { ExtendedClientType } from '~types/transactions.ts'; export { @@ -41,7 +42,7 @@ export type Unit = | 'tether'; export const isTransactionFormat = ( - potentialTransactionHash?: string, + potentialTransactionHash?: OptionalValue, ): boolean => { const hexStringRegex = /^0x([A-Fa-f0-9]{64})$/; if (!potentialTransactionHash) {