Skip to content

Commit

Permalink
Add banner and DAO Info Bar item for active threshold.
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahSaso committed Oct 3, 2023
1 parent ccdba33 commit a157127
Show file tree
Hide file tree
Showing 15 changed files with 228 additions and 24 deletions.
3 changes: 3 additions & 0 deletions packages/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,9 @@
"counterpartyBalanceInsufficient": "The counterparty's balance of {{amount}} ${{tokenSymbol}} is insufficient. They may be unable to complete this swap.",
"daoAndSubDaosAlreadyOnV2": "This DAO (and all of its SubDAOs, if it has any) have already been upgraded.",
"daoFeatureUnsupported": "{{name}} does not support {{feature}} yet.",
"daoIsInactive_absolute_one": "This DAO is inactive. Proposals cannot be created until {{count}} token is staked.",
"daoIsInactive_absolute_other": "This DAO is inactive. Proposals cannot be created until {{count}} tokens are staked.",
"daoIsInactive_percent": "This DAO is inactive. Proposals cannot be created until {{percent}} of voting power is staked.",
"daoIsPaused": "You cannot create a proposal when the DAO is paused.",
"discordAuthFailed": "Discord authentication unexpectedly failed. Try again or reach out to us for assistance.",
"emptyFile": "File is empty.",
Expand Down
35 changes: 32 additions & 3 deletions packages/stateful/components/dao/DaoInfoBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AccountBalanceOutlined } from '@mui/icons-material'
import { AccountBalanceOutlined, LockOpenOutlined } from '@mui/icons-material'
import { useTranslation } from 'react-i18next'

import { daoTvlSelector } from '@dao-dao/state'
Expand All @@ -10,6 +10,10 @@ import {
useChain,
useDaoInfoContext,
} from '@dao-dao/stateless'
import {
convertMicroDenomToDenomWithDecimals,
formatPercentOf100,
} from '@dao-dao/utils'

import {
useCw20CommonGovernanceTokenInfoIfExists,
Expand All @@ -27,13 +31,14 @@ const InnerDaoInfoBar = () => {
const { t } = useTranslation()
const { chain_id: chainId } = useChain()
const {
hooks: { useDaoInfoBarItems },
hooks: { useDaoInfoBarItems, useCommonGovernanceTokenInfo },
} = useVotingModuleAdapter()
const votingModuleItems = useDaoInfoBarItems()
const { coreAddress } = useDaoInfoContext()
const { coreAddress, activeThreshold } = useDaoInfoContext()

const { denomOrAddress: cw20GovernanceTokenAddress } =
useCw20CommonGovernanceTokenInfoIfExists() ?? {}
const tokenInfo = useCommonGovernanceTokenInfo?.()

const treasuryUsdcValueLoading = useCachedLoading(
daoTvlSelector({
Expand Down Expand Up @@ -75,6 +80,30 @@ const InnerDaoInfoBar = () => {
/>
),
},
...(activeThreshold
? [
{
Icon: LockOpenOutlined,
label: t('title.activeThreshold'),
tooltip: t('info.activeThresholdDescription'),
value:
'percentage' in activeThreshold
? formatPercentOf100(
Number(activeThreshold.percentage.percent) * 100
)
: tokenInfo && (
<TokenAmountDisplay
amount={convertMicroDenomToDenomWithDecimals(
activeThreshold.absolute_count.count,
tokenInfo.decimals
)}
decimals={tokenInfo.decimals}
symbol={tokenInfo.symbol}
/>
),
},
]
: []),
// Voting module-specific items.
...votingModuleItems,
]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Default.args = {
},
loading: false,
isPaused: false,
isActive: true,
activeThreshold: null,
isMember: { loading: false, data: true },
depositUnsatisfied: false,
connected: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ import {
SuspenseLoaderProps,
} from '@dao-dao/types'
import { MultipleChoiceOptionType } from '@dao-dao/types/contracts/DaoProposalMultiple'
import { ActiveThreshold } from '@dao-dao/types/contracts/DaoVotingCw20Staked'
import {
MAX_NUM_PROPOSAL_CHOICES,
convertActionsToMessages,
formatDateTime,
formatPercentOf100,
formatTime,
processError,
validateRequired,
Expand Down Expand Up @@ -76,6 +78,8 @@ export interface NewProposalProps
createProposal: (newProposalData: NewProposalData) => Promise<void>
loading: boolean
isPaused: boolean
isActive: boolean
activeThreshold: ActiveThreshold | null
isMember: LoadingData<boolean>
anyoneCanPropose: boolean
depositUnsatisfied: boolean
Expand All @@ -91,6 +95,8 @@ export const NewProposal = ({
createProposal,
loading,
isPaused,
isActive,
activeThreshold,
isMember,
anyoneCanPropose,
depositUnsatisfied,
Expand Down Expand Up @@ -333,6 +339,23 @@ export const NewProposal = ({
? t('error.notEnoughForDeposit')
: isPaused
? t('error.daoIsPaused')
: !isActive && activeThreshold
? t('error.daoIsInactive', {
context:
'percentage' in activeThreshold
? 'percent'
: 'absolute',
percent:
'percentage' in activeThreshold
? formatPercentOf100(
Number(activeThreshold.percentage.percent) * 100
)
: undefined,
count:
'percentage' in activeThreshold
? undefined
: Number(activeThreshold.absolute_count.count),
})
: choices.length < 2
? t('error.tooFewChoices')
: choices.length > MAX_NUM_PROPOSAL_CHOICES
Expand All @@ -348,6 +371,7 @@ export const NewProposal = ({
(!anyoneCanPropose && !isMember.loading && !isMember.data) ||
depositUnsatisfied ||
isPaused ||
!isActive ||
choices.length < 2 ||
choices.length > MAX_NUM_PROPOSAL_CHOICES
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export const NewProposal = ({
name: daoName,
imageUrl: daoImageUrl,
coreAddress,
isActive,
activeThreshold,
} = useDaoInfoContext()
const { isWalletConnected, getStargateClient } = useWallet()

Expand Down Expand Up @@ -206,11 +208,13 @@ export const NewProposal = ({
<StatelessNewProposal
EntityDisplay={EntityDisplay}
SuspenseLoader={SuspenseLoader}
activeThreshold={activeThreshold}
anyoneCanPropose={anyoneCanPropose}
categories={categories}
connected={isWalletConnected}
createProposal={createProposal}
depositUnsatisfied={depositUnsatisfied}
isActive={isActive}
isMember={
membershipLoading
? { loading: true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Default.args = {
},
loading: false,
isPaused: false,
isActive: true,
activeThreshold: null,
isMember: { loading: false, data: true },
depositUnsatisfied: false,
connected: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ import {
StatefulEntityDisplayProps,
SuspenseLoaderProps,
} from '@dao-dao/types'
import { ActiveThreshold } from '@dao-dao/types/contracts/DaoVotingCw20Staked'
import {
convertActionsToMessages,
formatDateTime,
formatPercentOf100,
formatTime,
processError,
validateRequired,
Expand Down Expand Up @@ -70,6 +72,8 @@ export interface NewProposalProps
createProposal: (newProposalData: NewProposalData) => Promise<void>
loading: boolean
isPaused: boolean
isActive: boolean
activeThreshold: ActiveThreshold | null
isMember: LoadingData<boolean>
anyoneCanPropose: boolean
depositUnsatisfied: boolean
Expand All @@ -85,6 +89,8 @@ export const NewProposal = ({
createProposal,
loading,
isPaused,
isActive,
activeThreshold,
isMember,
anyoneCanPropose,
depositUnsatisfied,
Expand Down Expand Up @@ -280,6 +286,23 @@ export const NewProposal = ({
? t('error.notEnoughForDeposit')
: isPaused
? t('error.daoIsPaused')
: !isActive && activeThreshold
? t('error.daoIsInactive', {
context:
'percentage' in activeThreshold
? 'percent'
: 'absolute',
percent:
'percentage' in activeThreshold
? formatPercentOf100(
Number(activeThreshold.percentage.percent) * 100
)
: undefined,
count:
'percentage' in activeThreshold
? undefined
: Number(activeThreshold.absolute_count.count),
})
: undefined
}
>
Expand All @@ -288,7 +311,8 @@ export const NewProposal = ({
!connected ||
(!anyoneCanPropose && !isMember.loading && !isMember.data) ||
depositUnsatisfied ||
isPaused
isPaused ||
!isActive
}
loading={loading}
type="submit"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export const NewProposal = ({
name: daoName,
imageUrl: daoImageUrl,
coreAddress,
isActive,
activeThreshold,
} = useDaoInfoContext()
const { isWalletConnected, getStargateClient } = useWallet()

Expand Down Expand Up @@ -215,11 +217,13 @@ export const NewProposal = ({
<StatelessNewProposal
EntityDisplay={EntityDisplay}
SuspenseLoader={SuspenseLoader}
activeThreshold={activeThreshold}
anyoneCanPropose={anyoneCanPropose}
categories={categories}
connected={isWalletConnected}
createProposal={createProposal}
depositUnsatisfied={depositUnsatisfied}
isActive={isActive}
isMember={
membershipLoading
? { loading: true }
Expand Down
31 changes: 30 additions & 1 deletion packages/stateful/recoil/selectors/dao/misc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RecoilValueReadOnly, selectorFamily } from 'recoil'
import { RecoilValueReadOnly, selectorFamily, waitForAllSettled } from 'recoil'

import {
DaoCoreV2Selectors,
Expand Down Expand Up @@ -183,6 +183,33 @@ export const daoInfoSelector: (param: {
const votingModuleContractName =
votingModuleInfo?.info.contract || 'fallback'

// All voting modules use the same isActive query, so it's safe to just
// use one here.
const [isActiveResponse, activeThresholdResponse] = get(
waitForAllSettled([
DaoVotingCw20StakedSelectors.isActiveSelector({
contractAddress: dumpState.voting_module,
chainId,
params: [],
}),
DaoVotingCw20StakedSelectors.activeThresholdSelector({
contractAddress: dumpState.voting_module,
chainId,
params: [],
}),
])
)
// Some voting modules don't support the isActive query, so if the query
// fails, assume active.
const isActive =
isActiveResponse.state === 'hasError' ||
(isActiveResponse.state === 'hasValue' &&
isActiveResponse.contents.active)
const activeThreshold =
(activeThresholdResponse.state === 'hasValue' &&
activeThresholdResponse.contents.active_threshold) ||
null

const proposalModules = get(
daoCoreProposalModulesSelector({
coreAddress,
Expand Down Expand Up @@ -293,6 +320,8 @@ export const daoInfoSelector: (param: {
description: dumpState.config.description,
imageUrl: dumpState.config.image_url || null,
created,
isActive,
activeThreshold,
items,
polytoneProxies,
parentDao: parentDaoInfo
Expand Down
Loading

0 comments on commit a157127

Please sign in to comment.