diff --git a/src/components/ProposalNextState.tsx b/src/components/ProposalNextState.tsx index b5eb20d3..ceb46aa2 100644 --- a/src/components/ProposalNextState.tsx +++ b/src/components/ProposalNextState.tsx @@ -2,6 +2,7 @@ import { Box, SxProps } from '@mui/system'; import React from 'react'; import InfoIcon from '../assets/icons/info.svg'; +import { useStore } from '../providers/ZustandStoreProvider'; import { ProposalNextState as State } from '../types'; import { IconBox } from './primitives/IconBox'; import { Timer } from './Timer'; @@ -26,6 +27,10 @@ export function ProposalNextState({ isForModal, isForHelpModal, }: ProposalEstimatedStatusProps) { + const updateProposalsListActiveData = useStore( + (store) => store.updateProposalsListActiveData, + ); + const statusTextStringArray = state.split(' '); statusTextStringArray.splice(state === State.Voting ? -3 : -1); const statusText = statusTextStringArray.join(' '); @@ -68,11 +73,11 @@ export function ProposalNextState({ in{' '} - // !isForHelpModal && - // getDetailedProposalsData({ ids: [proposalId], fullData: true }) // TODO update active proposals data - // } + onExpire={async () => { + if (!isForHelpModal) { + await updateProposalsListActiveData([proposalId]); + } + }} /> diff --git a/src/requests/utils/formatProposalData.ts b/src/requests/utils/formatProposalData.ts index f3679bea..c70b941a 100644 --- a/src/requests/utils/formatProposalData.ts +++ b/src/requests/utils/formatProposalData.ts @@ -213,7 +213,7 @@ export function getStatesForActiveProposal({ core.state === InitialProposalState.Cancelled || allPayloadsCanceled; const isExpired = core.state === InitialProposalState.Expired || allPayloadsExpired; - const isVotingActive = isVotingStarted && !isVotingEnded && !isCanceled; + const isVotingActive = isVotingStarted && !isCanceled; const isVotingFailed = isVotingEnded && (voting.proposalData.againstVotes >= voting.proposalData.forVotes || @@ -223,7 +223,6 @@ export function getStatesForActiveProposal({ voting.proposalData.forVotes < voting.proposalData.againstVotes + requiredDiff); const isProposalQueued = - isVotingStarted && isVotingEnded && isVotingClosed && voting.proposalData.sentToGovernance && @@ -426,7 +425,6 @@ export function getNextStateAndTimestampForActiveProposal({ !quorumReached; const isProposalWaitForQueued = - isVotingStarted && isVotingEnded && isVotingClosed && !isVotingDefeated && @@ -510,14 +508,17 @@ export function getPendingStateForActiveProposal({ !isVotingClosed ) { return ProposalPendingState.WaitForActivateVoting; - } else if (isVotingStarted && isVotingEnded && !isVotingClosed) { + } else if ( + isVotingEnded && + !isVotingClosed && + !voting.proposalData.sentToGovernance + ) { return ProposalPendingState.WaitForCloseVoting; } else if ( - isVotingStarted && isVotingEnded && - isVotingClosed && + !isVotingClosed && voting.proposalData.sentToGovernance && - core.queuingTime <= 0 + core.queuingTime <= 0n ) { return ProposalPendingState.WaitForQueueProposal; } else if ( diff --git a/src/store/proposalsSlice.ts b/src/store/proposalsSlice.ts index b9006574..ccfa3c79 100644 --- a/src/store/proposalsSlice.ts +++ b/src/store/proposalsSlice.ts @@ -1,4 +1,5 @@ import { StoreSlice } from '@bgd-labs/frontend-web3-utils'; +import { produce } from 'immer'; import { appConfig, isForIPFS } from '../configs/appConfig'; import { PAGE_SIZE } from '../configs/configs'; @@ -41,8 +42,8 @@ export interface IProposalsSlice { initializeProposalsCount: (count?: number) => Promise; proposalsListData: { - activeProposalsData: ActiveProposalOnTheList[]; - finishedProposalsData: ProposalOnTheList[]; + activeProposalsData: Record; + finishedProposalsData: Record; }; initializeProposalsListData: (proposalsListData: { activeProposalsData: ActiveProposalOnTheList[]; @@ -56,6 +57,8 @@ export interface IProposalsSlice { newProposalsInterval: number | undefined; startNewProposalsPolling: () => Promise; stopNewProposalsPolling: () => void; + + updateProposalsListActiveData: (activeIds: number[]) => Promise; } export const createProposalsSlice: StoreSlice< @@ -98,64 +101,26 @@ export const createProposalsSlice: StoreSlice< }, proposalsListData: { - activeProposalsData: [], - finishedProposalsData: [], + activeProposalsData: {}, + finishedProposalsData: {}, // TODO: user data }, initializeProposalsListData: (proposalsListData) => { - const currentData = get().proposalsListData; - const activeProposalsCurrent = currentData.activeProposalsData; - const finishedProposalsCurrent = currentData.finishedProposalsData; - - const activeProposalsData: ActiveProposalOnTheList[] = []; - for (let i = 0; i < proposalsListData.activeProposalsData.length; i++) { - let found = false; - for (let j = 0; j < activeProposalsCurrent.length; j++) { - if ( - proposalsListData.activeProposalsData[i].proposalId === - activeProposalsCurrent[j].proposalId - ) { - found = true; - break; - } - } - if (!found) { - activeProposalsData.push({ - ...proposalsListData.activeProposalsData[i], - }); - } - } - - const finishedProposalsData: ProposalOnTheList[] = []; - for (let i = 0; i < proposalsListData.finishedProposalsData.length; i++) { - let found = false; - for (let j = 0; j < finishedProposalsCurrent.length; j++) { - if ( - proposalsListData.finishedProposalsData[i].proposalId === - finishedProposalsCurrent[j].proposalId - ) { - found = true; - break; - } - } - if (!found) { - finishedProposalsData.push({ - ...proposalsListData.finishedProposalsData[i], - }); - } - } - - set({ - proposalsListData: { - activeProposalsData: [ - ...activeProposalsCurrent, - ...activeProposalsData, - ], - finishedProposalsData: [ - ...finishedProposalsCurrent, - ...finishedProposalsData, - ], - }, + proposalsListData.activeProposalsData.forEach((proposal) => { + set((state) => + produce(state, (draft) => { + draft.proposalsListData.activeProposalsData[proposal.proposalId] = + proposal; + }), + ); + }); + proposalsListData.finishedProposalsData.forEach((proposal) => { + set((state) => + produce(state, (draft) => { + draft.proposalsListData.finishedProposalsData[proposal.proposalId] = + proposal; + }), + ); }); }, @@ -166,27 +131,11 @@ export const createProposalsSlice: StoreSlice< const func = async () => { const configs = get().configs; - const activeIds = get().proposalsListData.activeProposalsData.map( - (proposal) => proposal.proposalId, - ); + const activeIds = Object.values( + get().proposalsListData.activeProposalsData, + ).map((proposal) => proposal.proposalId); if (configs && activeIds.length > 0) { - const input = { - ...configs.contractsConstants, - votingConfigs: configs.configs, - activeIds, - }; - // TODO: user data - const proposalsData = await (isForIPFS - ? fetchActiveProposalsDataForList({ - input: { - ...input, - clients: Object.values(get().appClients).map( - (client) => client.instance, - ), - }, - }) - : api.proposalsList.getActive.query(input)); - get().initializeProposalsListData(proposalsData); + await get().updateProposalsListActiveData(activeIds); } }; func(); @@ -227,23 +176,7 @@ export const createProposalsSlice: StoreSlice< 1, Number(totalProposalsCount) - currentProposalCount, ); - const input = { - ...configs.contractsConstants, - votingConfigs: configs.configs, - activeIds: newIdsForFirstScreen, - }; - // TODO: user data - const proposalsData = await (isForIPFS - ? fetchActiveProposalsDataForList({ - input: { - ...input, - clients: Object.values(get().appClients).map( - (client) => client.instance, - ), - }, - }) - : api.proposalsList.getActive.query(input)); - get().initializeProposalsListData(proposalsData); + await get().updateProposalsListActiveData(newIdsForFirstScreen); } }; func(); @@ -258,4 +191,27 @@ export const createProposalsSlice: StoreSlice< set({ newProposalsInterval: undefined }); } }, + + updateProposalsListActiveData: async (activeIds) => { + const configs = get().configs; + if (configs) { + const input = { + ...configs.contractsConstants, + votingConfigs: configs.configs, + activeIds, + }; + // TODO: user data + const proposalsData = await (isForIPFS + ? fetchActiveProposalsDataForList({ + input: { + ...input, + clients: Object.values(get().appClients).map( + (client) => client.instance, + ), + }, + }) + : api.proposalsList.getActive.query(input)); + get().initializeProposalsListData(proposalsData); + } + }, }); diff --git a/src/store/selectors/proposalsSelector.ts b/src/store/selectors/proposalsSelector.ts index 5cd91c6b..4f312428 100644 --- a/src/store/selectors/proposalsSelector.ts +++ b/src/store/selectors/proposalsSelector.ts @@ -11,18 +11,20 @@ export const selectProposalsForActivePage = ( ), activePage, ); - const fillteredActiveProposalsData = - store.proposalsListData.activeProposalsData.filter((proposal) => - ids.includes(proposal.proposalId), - ); - const fillteredFinishedProposalsData = - store.proposalsListData.finishedProposalsData.filter((proposal) => - ids.includes(proposal.proposalId), - ); + const fillteredActiveProposalsData = Object.values( + store.proposalsListData.activeProposalsData, + ).filter((proposal) => ids.includes(proposal.proposalId)); + const fillteredFinishedProposalsData = Object.values( + store.proposalsListData.finishedProposalsData, + ).filter((proposal) => ids.includes(proposal.proposalId)); return { - activeProposalsData: fillteredActiveProposalsData, - finishedProposalsData: fillteredFinishedProposalsData, + activeProposalsData: fillteredActiveProposalsData.sort( + (a, b) => b.proposalId - a.proposalId, + ), + finishedProposalsData: fillteredFinishedProposalsData.sort( + (a, b) => b.proposalId - a.proposalId, + ), }; } else { return {