Skip to content

Commit

Permalink
feat: add submission threshold to grant proposal request (#1346)
Browse files Browse the repository at this point in the history
* feat: add submission threshold to grant proposal request

* fix: disable submit button if submission vp not met
  • Loading branch information
andyesp authored Oct 20, 2023
1 parent 818d78c commit 3678efa
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 9 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ GATSBY_SUBMISSION_THRESHOLD_GOVERNANCE=100
GATSBY_SUBMISSION_THRESHOLD_PITCH=100
GATSBY_SUBMISSION_THRESHOLD_TENDER=100
GATSBY_SUBMISSION_THRESHOLD_HIRING=100
GATSBY_SUBMISSION_THRESHOLD_GRANT=100

# Single Sign On
GATSBY_SSO_URL="https://id.decentraland.zone"
Expand Down
11 changes: 8 additions & 3 deletions src/back/routes/proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import isDAOCommittee from '../../entities/Committee/isDAOCommittee'
import { hasOpenSlots } from '../../entities/Committee/utils'
import { GrantRequest, getGrantRequestSchema } from '../../entities/Grant/types'
import {
SUBMISSION_THRESHOLD_DRAFT,
SUBMISSION_THRESHOLD_GOVERNANCE,
SUBMISSION_THRESHOLD_GRANT,
SUBMISSION_THRESHOLD_HIRING,
SUBMISSION_THRESHOLD_PITCH,
SUBMISSION_THRESHOLD_POLL,
SUBMISSION_THRESHOLD_TENDER,
Expand Down Expand Up @@ -194,7 +198,7 @@ export async function createProposalDraft(req: WithAuth) {
const configuration = validate<NewProposalDraft>(newProposalDraftValidator, req.body || {})

await validateLinkedProposal(configuration.linked_proposal_id, ProposalType.Poll)
await validateSubmissionThreshold(user, process.env.GATSBY_SUBMISSION_THRESHOLD_DRAFT)
await validateSubmissionThreshold(user, SUBMISSION_THRESHOLD_DRAFT)

return createProposal({
user,
Expand All @@ -215,7 +219,7 @@ export async function createProposalGovernance(req: WithAuth) {
const configuration = validate<NewProposalGovernance>(newProposalGovernanceValidator, req.body || {})

await validateLinkedProposal(configuration.linked_proposal_id, ProposalType.Draft)
await validateSubmissionThreshold(user, process.env.GATSBY_SUBMISSION_THRESHOLD_GOVERNANCE)
await validateSubmissionThreshold(user, SUBMISSION_THRESHOLD_GOVERNANCE)

return createProposal({
user,
Expand Down Expand Up @@ -309,7 +313,7 @@ const newProposalHiringValidator = schema.compile(newProposalHiringScheme)
export async function createProposalHiring(req: WithAuth) {
const user = req.auth!
const configuration = validate<NewProposalHiring>(newProposalHiringValidator, req.body || {})
await validateSubmissionThreshold(user, process.env.GATSBY_SUBMISSION_THRESHOLD_HIRING)
await validateSubmissionThreshold(user, SUBMISSION_THRESHOLD_HIRING)

if (configuration.type === HiringType.Add) {
const canHire = await hasOpenSlots(configuration.committee)
Expand Down Expand Up @@ -376,6 +380,7 @@ export async function createProposalGrant(req: WithAuth) {
const grantRequestSchema = getGrantRequestSchema(req.body.category)
const newProposalGrantValidator = schema.compile(grantRequestSchema)
const user = req.auth!
await validateSubmissionThreshold(user, SUBMISSION_THRESHOLD_GRANT)
const grantRequest = validate<GrantRequest>(newProposalGrantValidator, req.body || {})
const grantInCreation = await ProjectService.getGrantInCreation(grantRequest, user)
return createProposal(grantInCreation)
Expand Down
8 changes: 5 additions & 3 deletions src/entities/Proposal/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ export const VOTING_POWER_TO_PASS_TENDER =
export const VOTING_POWER_TO_PASS_BID =
process.env.GATSBY_VOTING_POWER_TO_PASS_BID || clientEnv('GATSBY_VOTING_POWER_TO_PASS_BID')
export const SUBMISSION_THRESHOLD_DRAFT =
process.env.SUBMISSION_THRESHOLD_DRAFT || clientEnv('GATSBY_SUBMISSION_THRESHOLD_DRAFT')
process.env.GATSBY_SUBMISSION_THRESHOLD_DRAFT || clientEnv('GATSBY_SUBMISSION_THRESHOLD_DRAFT')
export const SUBMISSION_THRESHOLD_GOVERNANCE =
process.env.SUBMISSION_THRESHOLD_GOVERNANCE || clientEnv('GATSBY_SUBMISSION_THRESHOLD_GOVERNANCE')
process.env.GATSBY_SUBMISSION_THRESHOLD_GOVERNANCE || clientEnv('GATSBY_SUBMISSION_THRESHOLD_GOVERNANCE')
export const SUBMISSION_THRESHOLD_POLL =
process.env.SUBMISSION_THRESHOLD_POLL || clientEnv('GATSBY_SUBMISSION_THRESHOLD_POLL')
process.env.GATSBY_SUBMISSION_THRESHOLD_POLL || clientEnv('GATSBY_SUBMISSION_THRESHOLD_POLL')
export const SUBMISSION_THRESHOLD_PITCH =
process.env.GATSBY_SUBMISSION_THRESHOLD_PITCH || clientEnv('GATSBY_SUBMISSION_THRESHOLD_PITCH')
export const SUBMISSION_THRESHOLD_TENDER =
process.env.GATSBY_SUBMISSION_THRESHOLD_TENDER || clientEnv('GATSBY_SUBMISSION_THRESHOLD_TENDER')
export const SUBMISSION_THRESHOLD_HIRING =
process.env.GATSBY_SUBMISSION_THRESHOLD_HIRING || clientEnv('GATSBY_SUBMISSION_THRESHOLD_HIRING')
export const SUBMISSION_THRESHOLD_GRANT =
process.env.GATSBY_SUBMISSION_THRESHOLD_GRANT || clientEnv('GATSBY_SUBMISSION_THRESHOLD_GRANT')
export const VOTING_POWER_TO_PASS_HIRING =
process.env.VOTING_POWER_TO_PASS_HIRING || clientEnv('GATSBY_VOTING_POWER_TO_PASS_HIRING')
3 changes: 2 additions & 1 deletion src/intl/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
"server_invalid_status": "Error fetching catalyst statuses"
},
"grant": {
"submission_vp_not_met": "This action requires at least {threshold} VP.",
"funding": {
"invalid": "*Funding is invalid*",
"too_low": "*Funding is too low.*\n\n*Minimum is 100 USD*",
Expand Down Expand Up @@ -1622,7 +1623,7 @@
},
"submit_grant": {
"title": "Request a Grant",
"description": "The Decentraland Grants program allocates MANA owned by the DAO to fund the creation of features or content beneficial to the Decentraland platform and its growth. Either individuals or teams may request grant funding through the DAO. Check the Decentraland’s [Content Policy](https://decentraland.org/content)) to make sure your project is covered.\n\nFor your convenience and in preparation for your Grant Request you can download a file with all the questions present in this form [here](https://docs.google.com/document/d/1PSkV756XOUuAPPFlSu0LgqVy0QZ-DueeDj7MwSGRphc/edit#heading=h.xnwultcdr0as).",
"description": "The Decentraland Grants program allocates MANA owned by the DAO to fund the creation of features or content beneficial to the Decentraland platform and its growth. Either individuals or teams may request grant funding through the DAO. Check the Decentraland’s [Content Policy](https://decentraland.org/content)) to make sure your project is covered.\n\nFor your convenience and in preparation for your Grant Request you can download a file with all the questions present in this form [here](https://docs.google.com/document/d/1PSkV756XOUuAPPFlSu0LgqVy0QZ-DueeDj7MwSGRphc/edit#heading=h.xnwultcdr0as).\n\nThis action requires at least {threshold} VP. [Buy MANA](https://account.decentraland.org/) to get VP, or [run for delegate](https://forum.decentraland.org/t/open-call-for-delegates-apply-now/5840/5).",
"cancel": "Cancel",
"category_selection": {
"description": "Choose a category that best suits your project",
Expand Down
4 changes: 4 additions & 0 deletions src/pages/submit/grant.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@
.GrantRequest__Error {
margin-top: 40px;
}

.GrantRequest__SubmissionVpNotMetText {
margin-bottom: 24px !important;
}
16 changes: 14 additions & 2 deletions src/pages/submit/grant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import camelCase from 'lodash/camelCase'

import { Governance } from '../../clients/Governance'
import Markdown from '../../components/Common/Typography/Markdown'
import Text from '../../components/Common/Typography/Text'
import ErrorMessage from '../../components/Error/ErrorMessage'
import GrantRequestCategorySection from '../../components/GrantRequest/GrantRequestCategorySection'
import GrantRequestDueDiligenceSection, {
Expand All @@ -32,12 +33,14 @@ import LoadingView from '../../components/Layout/LoadingView'
import LogIn from '../../components/Layout/LogIn'
import CategorySelector from '../../components/Projects/CategorySelector'
import { GrantRequest, GrantRequestCategoryAssessment, NewGrantCategory } from '../../entities/Grant/types'
import { SUBMISSION_THRESHOLD_GRANT } from '../../entities/Proposal/constants'
import { ProposalType } from '../../entities/Proposal/types'
import { asNumber, isGrantProposalSubmitEnabled, userModifiedForm } from '../../entities/Proposal/utils'
import { toNewGrantCategory } from '../../entities/QuarterCategoryBudget/utils'
import useFormatMessage from '../../hooks/useFormatMessage'
import usePreventNavigation from '../../hooks/usePreventNavigation'
import useProjectRequestSectionNumber from '../../hooks/useProjectRequestSectionNumber'
import useVotingPowerDistribution from '../../hooks/useVotingPowerDistribution'
import locations, { navigate } from '../../utils/locations'

import './grant.css'
Expand Down Expand Up @@ -129,6 +132,8 @@ export default function SubmitGrant() {
const preventNavigation = useRef(false)
const [submitError, setSubmitError] = useState<string | undefined>(undefined)
const { getSectionNumber } = useProjectRequestSectionNumber()
const { vpDistribution } = useVotingPowerDistribution(account)
const submissionVpNotMet = !!vpDistribution && vpDistribution.total < Number(SUBMISSION_THRESHOLD_GRANT)

useEffect(() => {
preventNavigation.current = userModifiedForm(grantRequest, initialState)
Expand Down Expand Up @@ -198,7 +203,7 @@ export default function SubmitGrant() {
}

const title = t('page.submit_grant.title') || ''
const description = t('page.submit_grant.description') || ''
const description = t('page.submit_grant.description', { threshold: SUBMISSION_THRESHOLD_GRANT }) || ''

if (!account) {
return <LogIn title={title} description={description} />
Expand Down Expand Up @@ -298,11 +303,18 @@ export default function SubmitGrant() {
/>

<Container className="ContentLayout__Container">
{submissionVpNotMet && (
<ContentSection className="ProjectRequestSection__Content">
<Text className="GrantRequest__SubmissionVpNotMetText" size="lg" color="primary">
{t('error.grant.submission_vp_not_met', { threshold: SUBMISSION_THRESHOLD_GRANT })}
</Text>
</ContentSection>
)}
<ContentSection className="ProjectRequestSection__Content">
<div>
<Button
primary
disabled={!allSectionsValid || isFormDisabled}
disabled={!allSectionsValid || isFormDisabled || submissionVpNotMet}
loading={isFormDisabled}
onClick={submit}
>
Expand Down

0 comments on commit 3678efa

Please sign in to comment.