Skip to content

Commit

Permalink
Merge pull request #1541 from cosmos/jbibla+fedekunze/1501-proposal-v…
Browse files Browse the repository at this point in the history
…oting

jbibla+fedekunze/1501 Modal Vote
  • Loading branch information
faboweb authored Nov 12, 2018
2 parents 2786be1 + 79b6a77 commit cdef23b
Show file tree
Hide file tree
Showing 18 changed files with 932 additions and 103 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* [\#1464](https://github.com/cosmos/voyager/issues/1464) Added governance transactions to tx history page @fedekunze
* [\1401](https://github.com/cosmos/voyager/issues/1401) Display governance proposals index. @fedekunze
* [\#1472](https://github.com/cosmos/voyager/issues/1472) Added mock functionality for redelegation @fedekunze + @faboweb
* [\#1501](https://github.com/cosmos/voyager/issues/1501) Vote on proposals through modal @fedekunze + @jbibla
* [\1502](https://github.com/cosmos/voyager/issues/1502) A page for each proposal. @jbibla

### Changed
Expand Down
155 changes: 155 additions & 0 deletions app/src/renderer/components/governance/ModalVote.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<template lang="pug">
.modal-vote#modal-vote(v-click-outside="close")
.modal-vote-header
img.icon(class='modal-vote-atom' src="~assets/images/cosmos-logo.png")
span.tm-modal-title Vote
.tm-modal-icon.tm-modal-close#closeBtn(@click="close()")
i.material-icons close

div
h2 Title: {{ proposalTitle }}
h3 Proposal ID: {{ `#` + proposalId }}

tm-form-group.modal-vote-form-group.options
tm-btn#vote-yes(
@click.native="vote('yes')"
:class="[option === `yes` ? 'active' : '']"
color="secondary"
value="Yes"
size="md")

tm-btn#vote-no(
@click.native="vote('no')"
:class="[option === `no` ? 'active' : '']"
color="secondary"
value="No"
size="md")

tm-btn#vote-veto(
@click.native="vote('no_with_veto')"
:class="[option === `no_with_veto` ? 'active' : '']"
color="secondary"
value="No With Veto"
size="md")

tm-btn#vote-abstain(
@click.native="vote('abstain')"
:class="[option === `abstain` ? 'active' : '']"
color="secondary"
value="Abstain"
size="md")

tm-form-group.modal-vote-form-group
.modal-vote-footer
tm-btn#cast-vote(
@click.native="onVote"
:disabled="$v.option.$invalid"
color="primary"
value="Vote"
size="lg")
</template>

<script>
import ClickOutside from "vue-click-outside"
import { required } from "vuelidate/lib/validators"
import Modal from "common/TmModal"
import { TmBtn, TmField, TmFormGroup, TmFormMsg } from "@tendermint/ui"
const isValid = option =>
option === `yes` ||
option === `no` ||
option === `no_with_veto` ||
option === `abstain`
export default {
name: `modal-vote`,
props: [`proposalId`, `proposalTitle`],
components: {
Modal,
TmBtn,
TmField,
TmFormGroup,
TmFormMsg
},
data: () => ({
option: ``
}),
validations() {
return {
option: {
required,
isValid
}
}
},
methods: {
close() {
this.$emit(`update:showModalVote`, false)
},
vote(option) {
if (this.option === option) {
this.option = ``
} else {
this.option = option
}
},
onVote() {
this.$emit(`castVote`, { option: this.option })
this.close()
}
},
directives: {
ClickOutside
}
}
</script>

<style lang="stylus">
@import '~variables'
.modal-vote
background var(--app-nav)
display flex
flex-direction column
height 50%
justify-content space-between
left 50%
padding 2rem
position fixed
top 50%
width 40%
z-index z(modal)
&-header
align-items center
display flex
&-atom
height 4rem
width 4rem
&-form-group
display block
padding 0
&-footer
display flex
justify-content flex-end
h3
margin 0
button
margin 0
min-width 50%
span
margin 0.25rem
&.active
span
background var(--tertiary)
.tm-btn__container
padding 0.5rem
</style>
43 changes: 40 additions & 3 deletions app/src/renderer/components/governance/PageProposal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ tm-page(data-title='Proposal')
span.validator-profile__status(v-bind:class="status.color" v-tooltip.top="status.message")
.validator-profile__header__name__title {{ proposal.title }}
.column.validator-profile__header__actions
tm-btn(v-if="status.button === 'vote'" value="Vote" color="primary")
tm-btn#vote-btn(v-if="status.button === 'vote'" value="Vote" color="primary" @click.native="onVote")
tm-btn(v-if="status.button === 'deposit'" value="Deposit" color="primary")
tm-btn(v-if="!status.button" disabled value="Deposit / Vote" color="primary")

Expand Down Expand Up @@ -44,6 +44,14 @@ tm-page(data-title='Proposal')
.column
.row
text-block(:content="proposal.description")

modal-vote(
v-if="showModalVote"
v-on:castVote="castVote"
:showModalVote.sync="showModalVote"
:proposalId="proposal.proposal_id"
:proposalTitle="proposal.title"
)
</template>

<script>
Expand All @@ -52,17 +60,22 @@ import { TmBtn, TmPage, TmToolBar } from "@tendermint/ui"
import TmBalance from "common/TmBalance"
import FieldVote from "common/TmFieldVote"
import TextBlock from "common/TextBlock"
import ModalVote from "./ModalVote"
export default {
name: `page-proposal`,
props: [`proposal`, `status`],
components: {
TmBalance,
TmBtn,
FieldVote,
ModalVote,
TmToolBar,
TmPage,
TextBlock
},
data: () => ({
showModalVote: false
}),
computed: {
proposalType() {
return this.proposal.proposal_type.toLowerCase()
Expand All @@ -71,9 +84,9 @@ export default {
return `#` + num.prettyInt(this.proposal.submit_block)
},
voteBlock() {
if (this.proposal.submit_block === this.proposal.voting_start_block) {
if (this.proposal.submit_block === this.proposal.voting_start_block)
return `the same block`
} else {
else {
return `block #` + num.prettyInt(this.proposal.voting_start_block)
}
},
Expand Down Expand Up @@ -101,6 +114,30 @@ export default {
this.proposal.tally_result.abstain / this.totalVotes
)
}
},
methods: {
onVote() {
this.showModalVote = true
},
async castVote({ option }) {
let proposalId = this.proposal.proposal_id
try {
await this.$store.dispatch(`submitVote`, { proposalId, option })
this.$store.commit(`notify`, {
title: `Successful vote!`,
body: `You have successfully voted ${option} on proposal #${
this.proposal.proposal_id
}`
})
} catch ({ message }) {
this.$store.commit(`notifyError`, {
title: `Error while voting on proposal #${this.proposal.proposal_id}`,
body: message
})
}
}
}
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion app/src/renderer/connectors/lcdClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const Client = (axios, localLcdURL, remoteLcdURL) => {
submitProposal: function(data) {
return req(`POST`, `/gov/proposals`, true)(data)
},
submitVote: function(proposalId, data) {
submitProposalVote: function(proposalId, data) {
return req(`POST`, `/gov/proposals/${proposalId}/votes`, true)(data)
},
submitDeposit: function(proposalId, data) {
Expand Down
Loading

0 comments on commit cdef23b

Please sign in to comment.