forked from tornadocash/classic-ui
196 lines
5.0 KiB
Vue
196 lines
5.0 KiB
Vue
<template>
|
|
<div class="proposal">
|
|
<h1 class="title">{{ $t('createProposal') }}</h1>
|
|
|
|
<div class="columns is-multiline">
|
|
<div class="column is-6">
|
|
<b-field
|
|
:label="$t('proposalTitle')"
|
|
:message="isValidTitle ? '' : $t('proposal.error.title')"
|
|
:type="{ 'is-warning': !isValidTitle }"
|
|
>
|
|
<b-input v-model="validTitle" :placeholder="$t('title')"></b-input>
|
|
</b-field>
|
|
</div>
|
|
<div class="column is-6">
|
|
<b-field
|
|
:label="$t('proposalAddress')"
|
|
:type="{ 'is-warning': !hasValidAddress }"
|
|
:message="hasValidAddress ? '' : addressErrorMessage"
|
|
>
|
|
<b-input
|
|
v-model="address"
|
|
:placeholder="$t('proposalAddress')"
|
|
:size="!address ? '' : hasValidAddress ? '' : 'is-warning'"
|
|
></b-input>
|
|
</b-field>
|
|
</div>
|
|
<div class="column is-12">
|
|
<b-field
|
|
:message="isValidDescription ? '' : $t('proposal.error.description')"
|
|
:type="{ 'is-warning': !isValidDescription }"
|
|
:label="$t('proposalDescription')"
|
|
>
|
|
<b-input v-model="validDescription" maxlength="2000" type="textarea"></b-input>
|
|
</b-field>
|
|
</div>
|
|
</div>
|
|
<b-tooltip :label="`${$t('onlyOneProposalErr')}`" position="is-top" :active="cannotCreate" multilined>
|
|
<b-button
|
|
:disabled="cannotCreate"
|
|
type="is-primary"
|
|
:icon-left="isFetchingBalances ? '' : 'plus'"
|
|
outlined
|
|
:loading="isFetchingBalances"
|
|
@click="onCreateProposal"
|
|
>
|
|
{{ $t('createProposal') }}
|
|
</b-button>
|
|
</b-tooltip>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import { mapActions, mapState, mapGetters } from 'vuex'
|
|
import { debounce } from '@/utils'
|
|
|
|
const { isAddress } = require('web3-utils')
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
proposalAddress: '',
|
|
description: '',
|
|
title: '',
|
|
isValidAddress: true,
|
|
isValidContract: true,
|
|
isValidTitle: true,
|
|
isValidDescription: true
|
|
}
|
|
},
|
|
computed: {
|
|
...mapState('governance/gov', ['latestProposalId']),
|
|
...mapGetters('governance/gov', ['isFetchingBalances']),
|
|
address: {
|
|
get() {
|
|
return this.proposalAddress
|
|
},
|
|
set(address) {
|
|
this.setInitialState()
|
|
this.proposalAddress = address
|
|
|
|
debounce(this.validateAddress, address)
|
|
}
|
|
},
|
|
validTitle: {
|
|
get() {
|
|
return this.title
|
|
},
|
|
set(title) {
|
|
this.isValidTitle = true
|
|
this.title = title
|
|
}
|
|
},
|
|
addressErrorMessage() {
|
|
if (!this.isValidAddress) {
|
|
return this.$t('proposal.error.address')
|
|
}
|
|
|
|
if (!this.isValidContract) {
|
|
return this.$t('proposal.error.contract')
|
|
}
|
|
|
|
return this.$t('proposal.error.address')
|
|
},
|
|
validDescription: {
|
|
get() {
|
|
return this.description
|
|
},
|
|
set(description) {
|
|
this.isValidDescription = true
|
|
this.description = description
|
|
}
|
|
},
|
|
hasValidAddress() {
|
|
return this.isValidAddress && this.isValidContract
|
|
},
|
|
cannotCreate() {
|
|
return (
|
|
this.latestProposalId.value !== 0 &&
|
|
(this.latestProposalId.status === 'active' || this.latestProposalId.status === 'pending')
|
|
)
|
|
}
|
|
},
|
|
methods: {
|
|
...mapActions('governance/gov', ['createProposal']),
|
|
async addressIsContract(address) {
|
|
if (!address) {
|
|
return false
|
|
}
|
|
|
|
const code = await this.$provider.web3.eth.getCode(address)
|
|
|
|
return code !== '0x'
|
|
},
|
|
isAddress(address) {
|
|
const isCorrect = isAddress(address)
|
|
|
|
if (!isCorrect && address) {
|
|
this.isValidAddress = isCorrect
|
|
}
|
|
|
|
return isCorrect
|
|
},
|
|
async isContract(address) {
|
|
const isContract = await this.addressIsContract(address)
|
|
|
|
if (!isContract && address) {
|
|
this.isValidContract = isContract
|
|
}
|
|
|
|
return isContract
|
|
},
|
|
setInitialState() {
|
|
this.isValidAddress = true
|
|
this.isValidContract = true
|
|
},
|
|
async validateAddress(address) {
|
|
const isCorrect = this.isAddress(address)
|
|
|
|
if (!isCorrect) {
|
|
return false
|
|
}
|
|
|
|
const isContract = await this.isContract(address)
|
|
|
|
return isContract
|
|
},
|
|
async validationForms() {
|
|
this.isValidTitle = this.title
|
|
this.isValidDescription = this.description
|
|
this.isValidAddress = this.proposalAddress
|
|
|
|
const isCorrect = await this.validateAddress(this.proposalAddress)
|
|
|
|
return isCorrect && this.isValidAddress && this.isValidTitle && this.isValidDescription
|
|
},
|
|
async onCreateProposal() {
|
|
const isValidForms = await this.validationForms()
|
|
|
|
if (!isValidForms) {
|
|
return
|
|
}
|
|
|
|
this.$store.dispatch('loading/enable', { message: this.$t('preparingTransactionData') })
|
|
|
|
await this.createProposal({
|
|
proposalAddress: this.proposalAddress,
|
|
title: this.title,
|
|
description: this.description
|
|
})
|
|
this.$store.dispatch('loading/disable')
|
|
// this.$parent.close()
|
|
}
|
|
}
|
|
}
|
|
</script>
|