add markdown. myvotes.
This commit is contained in:
parent
6b31a47969
commit
cfbb98c9f6
@ -40,6 +40,7 @@
|
|||||||
"leaflet": "1.6.0",
|
"leaflet": "1.6.0",
|
||||||
"ledger-cosmos-js": "2.1.8",
|
"ledger-cosmos-js": "2.1.8",
|
||||||
"long": "^5.2.0",
|
"long": "^5.2.0",
|
||||||
|
"marked": "^4.0.14",
|
||||||
"node-fetch": "^2.6.5",
|
"node-fetch": "^2.6.5",
|
||||||
"pako": "^1.0.11",
|
"pako": "^1.0.11",
|
||||||
"portal-vue": "2.1.7",
|
"portal-vue": "2.1.7",
|
||||||
|
@ -157,6 +157,15 @@
|
|||||||
/>
|
/>
|
||||||
<span class="align-middle ml-50">My Validators</span>
|
<span class="align-middle ml-50">My Validators</span>
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
|
|
||||||
|
<b-dropdown-item :to="`/wallet/votes`">
|
||||||
|
<feather-icon
|
||||||
|
icon="PocketIcon"
|
||||||
|
size="16"
|
||||||
|
/>
|
||||||
|
<span class="align-middle ml-50">My Votes</span>
|
||||||
|
</b-dropdown-item>
|
||||||
|
|
||||||
<b-dropdown-item :to="`/wallet/transactions`">
|
<b-dropdown-item :to="`/wallet/transactions`">
|
||||||
<feather-icon
|
<feather-icon
|
||||||
icon="LayersIcon"
|
icon="LayersIcon"
|
||||||
|
@ -90,7 +90,7 @@ export default class ChainFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getTxsBySender(sender, page = 1) {
|
async getTxsBySender(sender, page = 1) {
|
||||||
return this.get(`/txs?message.sender=${sender}&page=${page}&limit=20`)
|
return this.get(`/cosmos/tx/v1beta1/txs?events=message.sender='${sender}'&page=${page}&limit=20`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTxsByRecipient(recipient) {
|
async getTxsByRecipient(recipient) {
|
||||||
@ -98,7 +98,7 @@ export default class ChainFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getTxsByHeight(height) {
|
async getTxsByHeight(height) {
|
||||||
return this.get(`/txs?tx.height=${height}`)
|
return this.get(`/cosmos/tx/v1beta1/txs?events=tx.height=${height}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getValidatorDistribution(address) {
|
async getValidatorDistribution(address) {
|
||||||
@ -207,8 +207,8 @@ export default class ChainFetch {
|
|||||||
return this.get('/gov/parameters/voting').then(data => commonProcess(data))
|
return this.get('/gov/parameters/voting').then(data => commonProcess(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGovernanceTally(pid, total) {
|
async getGovernanceTally(pid, total, conf) {
|
||||||
return this.get(`/gov/proposals/${pid}/tally`).then(data => new ProposalTally().init(commonProcess(data), total))
|
return this.get(`/gov/proposals/${pid}/tally`, conf).then(data => new ProposalTally().init(commonProcess(data), total))
|
||||||
}
|
}
|
||||||
|
|
||||||
getGovernance(pid) {
|
getGovernance(pid) {
|
||||||
@ -246,19 +246,49 @@ export default class ChainFetch {
|
|||||||
pagination: {},
|
pagination: {},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if (this.config.chain_name === 'certik') {
|
if (this.config.chain_name === 'shentu') {
|
||||||
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}`)
|
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
|
||||||
}
|
}
|
||||||
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}`)
|
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGovernanceListByStatus(status) {
|
async getGovernanceListByStatus(status, chain = null) {
|
||||||
const url = this.config.chain_name === 'certik' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/v1beta1/proposals?pagination.limit=100&proposal_status=${status}`
|
const conf = chain || this.config
|
||||||
return this.get(url)
|
const url = conf.chain_name === 'shentu' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/v1beta1/proposals?pagination.limit=100&proposal_status=${status}`
|
||||||
|
return this.get(url, conf).then(data => {
|
||||||
|
let proposals = commonProcess(data)
|
||||||
|
if (Array.isArray(proposals.proposals)) {
|
||||||
|
proposals = proposals.proposals
|
||||||
|
}
|
||||||
|
const ret = []
|
||||||
|
if (proposals) {
|
||||||
|
proposals.forEach(e => {
|
||||||
|
const g = new Proposal().init(e, 0)
|
||||||
|
g.versionFixed(this.config.sdk_version)
|
||||||
|
ret.push(g)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
proposals: ret,
|
||||||
|
pagination: data.pagination,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGovernanceProposalVote(pid, voter, chain) {
|
||||||
|
const url = this.config.chain_name === 'shentu'
|
||||||
|
? `/shentu/gov/v1alpha1/proposals/${pid}/votes/${voter}`
|
||||||
|
: `/cosmos/gov/v1beta1/proposals/${pid}/votes/${voter}`
|
||||||
|
return this.get(url, chain).then(data => {
|
||||||
|
if (data.code === 3) {
|
||||||
|
throw new Error('not found')
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGovernanceList(next = '') {
|
async getGovernanceList(next = '') {
|
||||||
const url = this.config.chain_name === 'certik'
|
const url = this.config.chain_name === 'shentu'
|
||||||
? `/shentu/gov/v1alpha1/proposals?pagination.limit=50&pagination.reverse=true&pagination.key=${next}`
|
? `/shentu/gov/v1alpha1/proposals?pagination.limit=50&pagination.reverse=true&pagination.key=${next}`
|
||||||
: `/cosmos/gov/v1beta1/proposals?pagination.limit=50&pagination.reverse=true&pagination.key=${next}`
|
: `/cosmos/gov/v1beta1/proposals?pagination.limit=50&pagination.reverse=true&pagination.key=${next}`
|
||||||
return this.get(url).then(data => {
|
return this.get(url).then(data => {
|
||||||
|
@ -101,6 +101,22 @@ const router = new VueRouter({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/wallet/votes',
|
||||||
|
name: 'myVotes',
|
||||||
|
component: () => import('@/views/WalletVotes.vue'),
|
||||||
|
meta: {
|
||||||
|
pageTitle: 'My Votes',
|
||||||
|
breadcrumb: [
|
||||||
|
{
|
||||||
|
text: 'Wallet',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'My Votes',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
// chain modules
|
// chain modules
|
||||||
{
|
{
|
||||||
path: '/:chain/',
|
path: '/:chain/',
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
{{ p.title }}
|
{{ p.title }}
|
||||||
</router-link></b-card-title>
|
</router-link></b-card-title>
|
||||||
<b-card-body md="12">
|
<b-card-body md="12">
|
||||||
<div class="gov-wrapper d-flex flex-wrap">
|
<div class="gov-wrapper d-flex flex-nowrap">
|
||||||
<div class="gov">
|
<div class="gov">
|
||||||
<p class="card-text mb-25">
|
<p class="card-text mb-25">
|
||||||
Type
|
Type
|
||||||
@ -285,7 +285,7 @@ export default {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
section {
|
section {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
/* flex-wrap: nowrap; */
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
.card {
|
.card {
|
||||||
@ -294,7 +294,6 @@ section {
|
|||||||
.gov-wrapper {
|
.gov-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content:center;
|
justify-content:center;
|
||||||
align-items:flex-end;
|
|
||||||
}
|
}
|
||||||
.dark-layout .gov-wrapper .gov {
|
.dark-layout .gov-wrapper .gov {
|
||||||
background-color: #161d31;
|
background-color: #161d31;
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
</b-tr>
|
</b-tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</b-table-simple>
|
</b-table-simple>
|
||||||
<div style="white-space: pre-line">
|
<div>
|
||||||
<object-field-component
|
<object-field-component
|
||||||
:tablefield="proposal.contents"
|
:tablefield="proposal.contents"
|
||||||
:small="false"
|
:small="false"
|
||||||
@ -101,7 +101,7 @@
|
|||||||
</b-table-simple>
|
</b-table-simple>
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
<b-card-footer>
|
<b-card-footer>
|
||||||
<router-link :to="`../gov`">
|
<router-link :to="from">
|
||||||
<b-button
|
<b-button
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
>
|
>
|
||||||
@ -204,7 +204,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
</b-card>
|
</b-card>
|
||||||
<b-card no-body>
|
<b-card
|
||||||
|
v-if="proposal.total_deposit"
|
||||||
|
no-body
|
||||||
|
>
|
||||||
<b-card-header>
|
<b-card-header>
|
||||||
<b-card-title>
|
<b-card-title>
|
||||||
Deposits ({{ formatToken(proposal.total_deposit) }})
|
Deposits ({{ formatToken(proposal.total_deposit) }})
|
||||||
@ -212,8 +215,9 @@
|
|||||||
</b-card-header>
|
</b-card-header>
|
||||||
<b-card-body>
|
<b-card-body>
|
||||||
<b-table
|
<b-table
|
||||||
|
v-if="Array.isArray(deposits.deposits || deposits)"
|
||||||
stacked="sm"
|
stacked="sm"
|
||||||
:items="deposits.deposits?deposits.deposits:deposits"
|
:items="deposits.deposits || deposits"
|
||||||
:fields="deposit_fields"
|
:fields="deposit_fields"
|
||||||
striped
|
striped
|
||||||
>
|
>
|
||||||
@ -225,7 +229,7 @@
|
|||||||
</b-table>
|
</b-table>
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
<b-card-footer>
|
<b-card-footer>
|
||||||
<router-link :to="`../gov`">
|
<router-link :to="from">
|
||||||
<b-button
|
<b-button
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
>
|
>
|
||||||
@ -307,6 +311,7 @@ export default {
|
|||||||
deposits: [],
|
deposits: [],
|
||||||
votes: [],
|
votes: [],
|
||||||
operationModalType: '',
|
operationModalType: '',
|
||||||
|
from: '../gov',
|
||||||
votes_fields: [
|
votes_fields: [
|
||||||
{
|
{
|
||||||
key: 'voter',
|
key: 'voter',
|
||||||
@ -366,6 +371,9 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
const pid = this.$route.params.proposalid
|
const pid = this.$route.params.proposalid
|
||||||
|
if (this.$route.query.from) {
|
||||||
|
this.from = this.$route.query.from
|
||||||
|
}
|
||||||
|
|
||||||
this.$http.getLatestBlock().then(res => {
|
this.$http.getLatestBlock().then(res => {
|
||||||
this.latest = res
|
this.latest = res
|
||||||
@ -387,7 +395,7 @@ export default {
|
|||||||
})
|
})
|
||||||
this.$http.getGovernanceDeposits(pid).then(res => {
|
this.$http.getGovernanceDeposits(pid).then(res => {
|
||||||
this.deposits = res
|
this.deposits = res
|
||||||
})
|
}).catch(() => {})
|
||||||
this.$http.getGovernanceVotes(pid).then(res => {
|
this.$http.getGovernanceVotes(pid).then(res => {
|
||||||
this.votes = res
|
this.votes = res
|
||||||
this.next = res.pagination ? res.pagination.next_key : null
|
this.next = res.pagination ? res.pagination.next_key : null
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
</b-tabs>
|
</b-tabs>
|
||||||
</b-td>
|
</b-td>
|
||||||
<b-td v-else>
|
<b-td v-else>
|
||||||
{{ addNewLine(value) }}
|
<p v-html="addNewLine(value)" />
|
||||||
</b-td>
|
</b-td>
|
||||||
</b-tr>
|
</b-tr>
|
||||||
</b-tbody>
|
</b-tbody>
|
||||||
@ -71,6 +71,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { marked } from 'marked'
|
||||||
import {
|
import {
|
||||||
BTableSimple, BTr, BTd, BTabs, BTab, BTbody,
|
BTableSimple, BTr, BTd, BTabs, BTab, BTbody,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
@ -139,8 +140,8 @@ export default {
|
|||||||
if (percentage.test(value)) {
|
if (percentage.test(value)) {
|
||||||
return `${percent(value)}%`
|
return `${percent(value)}%`
|
||||||
}
|
}
|
||||||
if (typeof value === 'string' && value.indexOf('\\n') > -1) {
|
if (typeof value === 'string') {
|
||||||
return value.replaceAll('\\n', '\n')
|
return marked.parse(value.replaceAll('\\n', '\n'))
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
8
src/views/WalletUpgradeEvents.vue
Normal file
8
src/views/WalletUpgradeEvents.vue
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<template>
|
||||||
|
<div>xxx</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
361
src/views/WalletVotes.vue
Normal file
361
src/views/WalletVotes.vue
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
<template>
|
||||||
|
<b-tabs content-class="mt-1">
|
||||||
|
<!-- This tabs content will always be mounted -->
|
||||||
|
<b-tab
|
||||||
|
title="Ongoing Proposals"
|
||||||
|
pill
|
||||||
|
>
|
||||||
|
<b-row class="match-height">
|
||||||
|
<b-col
|
||||||
|
v-for="(p,i) in list"
|
||||||
|
:key="`${p.id}-${i}`"
|
||||||
|
lg="6"
|
||||||
|
md="12"
|
||||||
|
>
|
||||||
|
<b-card>
|
||||||
|
<b-card-title
|
||||||
|
class="mb-0"
|
||||||
|
>
|
||||||
|
<b-avatar
|
||||||
|
:src="p.chain.logo"
|
||||||
|
variant="light-primary"
|
||||||
|
size="22"
|
||||||
|
/>
|
||||||
|
<span class="text-uppercase"> {{ p.chain.chain_name }}</span>
|
||||||
|
#{{ p.id }}.
|
||||||
|
<b-badge
|
||||||
|
v-if="p.status == 1"
|
||||||
|
pill
|
||||||
|
variant="light-info"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Deposit
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="p.status == 2"
|
||||||
|
pill
|
||||||
|
variant="light-primary"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Voting
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="p.status == 3"
|
||||||
|
pill
|
||||||
|
variant="light-success"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Passed
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="p.status == 4"
|
||||||
|
pill
|
||||||
|
variant="light-danger"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Rejected
|
||||||
|
</b-badge>
|
||||||
|
<router-link
|
||||||
|
:to="`/${p.chain.chain_name}/gov/${p.id}?from=/wallet/votes`"
|
||||||
|
>
|
||||||
|
{{ p.title }}
|
||||||
|
</router-link></b-card-title>
|
||||||
|
<b-card-body md="12">
|
||||||
|
<div class="gov-wrapper d-flex">
|
||||||
|
<div class="gov">
|
||||||
|
<p class="card-text mb-25">
|
||||||
|
Type
|
||||||
|
</p>
|
||||||
|
<h6 class="mb-0">
|
||||||
|
{{ formatType(p.contents['@type']) }}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
<div class="gov">
|
||||||
|
<p class="card-text mb-25">
|
||||||
|
Start Date
|
||||||
|
</p>
|
||||||
|
<h6 class="mb-0">
|
||||||
|
{{ formatDate(p.voting_start_time) }}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
<div class="gov">
|
||||||
|
<p class="card-text mb-25">
|
||||||
|
End Date
|
||||||
|
</p>
|
||||||
|
<h6 class="mb-0">
|
||||||
|
{{ formatDate(p.voting_end_time) }}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
<div class="gov">
|
||||||
|
<p class="card-text mb-25">
|
||||||
|
Deposit
|
||||||
|
</p>
|
||||||
|
<h6 class="mb-0">
|
||||||
|
{{ formatToken(p.total_deposit) || '-' }}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</b-card-body>
|
||||||
|
|
||||||
|
<b-progress
|
||||||
|
:max="100"
|
||||||
|
height="2rem"
|
||||||
|
class="mb-2"
|
||||||
|
show-progress
|
||||||
|
>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-yes'+p.id"
|
||||||
|
variant="success"
|
||||||
|
:value="percent(p.tally.yes)"
|
||||||
|
show-progress
|
||||||
|
:label="`${percent(p.tally.yes).toFixed()}%`"
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-no'+p.id"
|
||||||
|
variant="warning"
|
||||||
|
:value="percent(p.tally.no)"
|
||||||
|
:label="`${percent(p.tally.no).toFixed()}%`"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-veto'+p.id"
|
||||||
|
variant="danger"
|
||||||
|
:value="percent(p.tally.veto)"
|
||||||
|
:label="`${percent(p.tally.veto).toFixed()}%`"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-abstain'+p.id"
|
||||||
|
variant="info"
|
||||||
|
:value="percent(p.tally.abstain)"
|
||||||
|
:label="`${percent(p.tally.abstain).toFixed()}%`"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
</b-progress>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-yes'+p.id"
|
||||||
|
>
|
||||||
|
{{ percent(p.tally.yes) }}% voted Yes
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-no'+p.id"
|
||||||
|
>
|
||||||
|
{{ percent(p.tally.no) }}% voted No
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-veto'+p.id"
|
||||||
|
>
|
||||||
|
{{ percent(p.tally.veto) }}% voted No With Veto
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-abstain'+p.id"
|
||||||
|
>
|
||||||
|
{{ percent(p.tally.abstain) }}% voted Abstain
|
||||||
|
</b-tooltip>
|
||||||
|
<b-card-footer class="pb-0">
|
||||||
|
<span
|
||||||
|
v-for="(v,k) in p.votes"
|
||||||
|
:key="k"
|
||||||
|
> <b-badge :variant="color(v.vote.option)">{{ v.keyname }} : {{ v.vote.option }}</b-badge></span>
|
||||||
|
</b-card-footer>
|
||||||
|
</b-card>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-tab>
|
||||||
|
|
||||||
|
<!-- This tabs content will not be mounted until the tab is shown -->
|
||||||
|
<!-- and will be un-mounted when hidden -->
|
||||||
|
<b-tab
|
||||||
|
title="Upgrade Events"
|
||||||
|
lazy
|
||||||
|
>
|
||||||
|
<b-alert
|
||||||
|
variant="info"
|
||||||
|
show
|
||||||
|
class="mb-0"
|
||||||
|
>
|
||||||
|
<div class="alert-body">
|
||||||
|
{{ votes }}
|
||||||
|
</div>
|
||||||
|
</b-alert>
|
||||||
|
</b-tab>
|
||||||
|
</b-tabs>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
VBTooltip, BTabs, BTab, BRow, BCol, BCard, BCardFooter, BBadge,
|
||||||
|
BCardTitle, BCardBody, BProgress, BProgressBar, BTooltip, BAvatar,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
|
import Ripple from 'vue-ripple-directive'
|
||||||
|
import {
|
||||||
|
getLocalAccounts, getLocalChains, percent, ProposalTally, tokenFormatter,
|
||||||
|
} from '@/libs/utils'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BAvatar,
|
||||||
|
BTab,
|
||||||
|
BTabs,
|
||||||
|
BRow,
|
||||||
|
BCol,
|
||||||
|
BCard,
|
||||||
|
BCardFooter,
|
||||||
|
BCardTitle,
|
||||||
|
BCardBody,
|
||||||
|
BBadge,
|
||||||
|
BProgress,
|
||||||
|
BProgressBar,
|
||||||
|
BTooltip,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'b-tooltip': VBTooltip,
|
||||||
|
Ripple,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
islive: true,
|
||||||
|
proposals: [],
|
||||||
|
tally: {},
|
||||||
|
voters: [], // need to be query.
|
||||||
|
votes: [], // votes of voters
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
list() {
|
||||||
|
return this.proposals.map(x => {
|
||||||
|
const x2 = x
|
||||||
|
x2.tally = this.tally[`${x.chain.chain_name}-${x.id}`] || new ProposalTally()
|
||||||
|
x2.votes = this.votes.filter(v => v.vote.proposal_id === x.id)
|
||||||
|
return x2
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.islive = false
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
color(v) {
|
||||||
|
switch (v) {
|
||||||
|
case 'VOTE_OPTION_YES':
|
||||||
|
return 'success'
|
||||||
|
case 'VOTE_OPTION_NO':
|
||||||
|
return 'warning'
|
||||||
|
case 'VOTE_OPTION_NOWITHVETO':
|
||||||
|
return 'danger'
|
||||||
|
case 'VOTE_OPTION_ABSTAIN':
|
||||||
|
return 'info'
|
||||||
|
default:
|
||||||
|
return 'danger'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keyname(addr) {
|
||||||
|
const key = Object.values(this.accounts).find(k => k.address.findIndex(a => a.addr === addr) > -1)
|
||||||
|
return key ? key.name : addr.substring(addr.length - 6)
|
||||||
|
},
|
||||||
|
formatType(v) {
|
||||||
|
const txt = String(v).replace('Proposal', '')
|
||||||
|
const index = txt.lastIndexOf('.')
|
||||||
|
return index > 0 ? txt.substring(index + 1) : txt
|
||||||
|
},
|
||||||
|
percent: v => percent(v),
|
||||||
|
formatDate: v => dayjs(v).format('YYYY-MM-DD'),
|
||||||
|
formatToken: v => tokenFormatter(v, {}),
|
||||||
|
init() {
|
||||||
|
this.accounts = getLocalAccounts()
|
||||||
|
if (this.accounts) {
|
||||||
|
const chains = getLocalChains()
|
||||||
|
const toQuery = {}
|
||||||
|
|
||||||
|
Object.keys(this.accounts).forEach(acc => {
|
||||||
|
this.accounts[acc].address.forEach(add => {
|
||||||
|
const conf = chains[add.chain]
|
||||||
|
if (conf) {
|
||||||
|
if (toQuery[add.chain]) {
|
||||||
|
toQuery[add.chain].addresses.push(add.addr)
|
||||||
|
} else {
|
||||||
|
toQuery[add.chain] = {
|
||||||
|
conf,
|
||||||
|
addresses: [add.addr],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
let promise = Promise.resolve()
|
||||||
|
Object.values(toQuery).forEach(item => {
|
||||||
|
promise = promise.then(() => new Promise(resolve => {
|
||||||
|
this.fetchProposals(item, resolve)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetchProposals(item, resolve) {
|
||||||
|
if (this.islive) {
|
||||||
|
this.$http.getGovernanceListByStatus(2, item.conf).then(data => {
|
||||||
|
resolve()
|
||||||
|
data.proposals.forEach(p => {
|
||||||
|
const p2 = p
|
||||||
|
p2.chain = item.conf
|
||||||
|
this.proposals.push(p2)
|
||||||
|
item.addresses.forEach(a => {
|
||||||
|
this.fetchMyVote(p.id, a, item.conf)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.updateTally(data.proposals, item.conf)
|
||||||
|
}, err => {
|
||||||
|
throw new Error(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fetchMyVote(pid, addr, chain) {
|
||||||
|
if (this.islive) {
|
||||||
|
this.$http.getGovernanceProposalVote(pid, addr, chain).then(data => {
|
||||||
|
const x = data
|
||||||
|
x.keyname = this.keyname(data.vote.voter)
|
||||||
|
this.votes.push(x)
|
||||||
|
}).catch(() => { })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTally(voting, chain) {
|
||||||
|
if (voting.length > 0) {
|
||||||
|
voting.forEach(p => this.$http.getGovernanceTally(p.id, 0, chain).then(update => {
|
||||||
|
this.$set(this.tally, `${chain.chain_name}-${p.id}`, update)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
section {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
flex-basis: 49%;
|
||||||
|
}
|
||||||
|
.gov-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content:center;
|
||||||
|
}
|
||||||
|
.dark-layout .gov-wrapper .gov {
|
||||||
|
background-color: #161d31;
|
||||||
|
}
|
||||||
|
.gov-wrapper .gov {
|
||||||
|
padding: .5rem;
|
||||||
|
margin: .3rem;
|
||||||
|
min-width: 7.5rem;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border-radius: .357rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
@ -6416,6 +6416,11 @@ marked@^2.0.3:
|
|||||||
resolved "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz"
|
resolved "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz"
|
||||||
integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
|
integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
|
||||||
|
|
||||||
|
marked@^4.0.14:
|
||||||
|
version "4.0.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.14.tgz#7a3a5fa5c80580bac78c1ed2e3b84d7bd6fc3870"
|
||||||
|
integrity sha512-HL5sSPE/LP6U9qKgngIIPTthuxC0jrfxpYMZ3LdGDD3vTnLs59m2Z7r6+LNDR3ToqEQdkKd6YaaEfJhodJmijQ==
|
||||||
|
|
||||||
md5.js@^1.3.4:
|
md5.js@^1.3.4:
|
||||||
version "1.3.5"
|
version "1.3.5"
|
||||||
resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
|
resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user