finish staking list
This commit is contained in:
parent
e02cac6154
commit
df6a20ee67
@ -12,7 +12,14 @@
|
|||||||
class="d-flex align-items-center"
|
class="d-flex align-items-center"
|
||||||
@click="() => updateGroupOpen(!isOpen)"
|
@click="() => updateGroupOpen(!isOpen)"
|
||||||
>
|
>
|
||||||
<feather-icon :icon="item.icon || 'CircleIcon'" />
|
<b-avatar
|
||||||
|
variant="info"
|
||||||
|
:src="item.icon"
|
||||||
|
icon="people-fill"
|
||||||
|
size="sm"
|
||||||
|
class="mr-1"
|
||||||
|
/>
|
||||||
|
|
||||||
<span class="menu-title text-truncate">{{ t(item.title) }}</span>
|
<span class="menu-title text-truncate">{{ t(item.title) }}</span>
|
||||||
<b-badge
|
<b-badge
|
||||||
v-if="item.tag"
|
v-if="item.tag"
|
||||||
@ -40,7 +47,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { BLink, BBadge, BCollapse } from 'bootstrap-vue'
|
import {
|
||||||
|
BLink, BBadge, BCollapse, BAvatar,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
import { resolveVerticalNavMenuItemComponent as resolveNavItemComponent } from '@core/layouts/utils'
|
import { resolveVerticalNavMenuItemComponent as resolveNavItemComponent } from '@core/layouts/utils'
|
||||||
import { useUtils as useI18nUtils } from '@core/libs/i18n'
|
import { useUtils as useI18nUtils } from '@core/libs/i18n'
|
||||||
import { useUtils as useAclUtils } from '@core/libs/acl'
|
import { useUtils as useAclUtils } from '@core/libs/acl'
|
||||||
@ -56,6 +65,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
VerticalNavMenuHeader,
|
VerticalNavMenuHeader,
|
||||||
VerticalNavMenuLink,
|
VerticalNavMenuLink,
|
||||||
|
BAvatar,
|
||||||
BLink,
|
BLink,
|
||||||
BBadge,
|
BBadge,
|
||||||
BCollapse,
|
BCollapse,
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
v-bind="linkProps"
|
v-bind="linkProps"
|
||||||
class="d-flex align-items-center"
|
class="d-flex align-items-center"
|
||||||
>
|
>
|
||||||
<feather-icon :icon="item.icon || 'CircleIcon'" />
|
<feather-icon :icon="item.icon || 'ChevronRightIcon'" />
|
||||||
<span class="menu-title text-truncate">{{ t(item.title) }}</span>
|
<span class="text-truncate">{{ t(item.title) }}</span>
|
||||||
<b-badge
|
<b-badge
|
||||||
v-if="item.tag"
|
v-if="item.tag"
|
||||||
pill
|
pill
|
||||||
|
@ -9,6 +9,20 @@
|
|||||||
"staking": "Staking",
|
"staking": "Staking",
|
||||||
"governance": "Governance",
|
"governance": "Governance",
|
||||||
"summary": "Summary",
|
"summary": "Summary",
|
||||||
"blockchains": "Blockchains"
|
"blockchains": "Blockchains",
|
||||||
|
|
||||||
|
"proposal_id": "Proposal ID",
|
||||||
|
"proposal_type": "Proposal Type",
|
||||||
|
"proposal_proposer": "Proposer",
|
||||||
|
"proposal_submit_time": "Submited Time",
|
||||||
|
"proposal_voting_start_time": "Voting Begin Time",
|
||||||
|
"proposal_voting_end_time": "Voting End Time",
|
||||||
|
"proposal_description": "Description",
|
||||||
|
"proposal_content": "Content",
|
||||||
|
"proposal_total_deposit": "Total Deposit",
|
||||||
|
|
||||||
|
"btn_vote": "Vote",
|
||||||
|
"btn_detail": "Detail",
|
||||||
|
"btn_back_list": "Back To List"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
<h6 class="mb-0 text-uppercase">
|
<h6 class="mb-0 text-uppercase">
|
||||||
{{ selected_chain.chain_name }}
|
{{ selected_chain.chain_name }}
|
||||||
</h6>
|
</h6>
|
||||||
<small v-b-tooltip.hover.bottom="'Data Provider'">{{ selected_chain.api }}</small>
|
<small v-b-tooltip.hover.bottom="'Data Provider'">{{ selected_chain.api }} {{ selected_chain.sdk_version }}</small>
|
||||||
</b-media-body>
|
</b-media-body>
|
||||||
</b-media>
|
</b-media>
|
||||||
</div>
|
</div>
|
||||||
@ -94,11 +94,10 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
selected_chain() {
|
selected_chain() {
|
||||||
const c = this.$route.params.chain
|
// const c = this.$route.params.chain
|
||||||
const has = Object.keys(store.state.chains.chains).findIndex(i => i === c)
|
// const has = Object.keys(store.state.chains.config).findIndex(i => i === c)
|
||||||
const selected = (has > -1) ? store.state.chains.chains[c] : store.state.chains.chains.cosmos
|
// const selected = (has > -1) ? store.state.chains.config[c] : store.state.chains.config.cosmos
|
||||||
localStorage.setItem('selected_chain', selected)
|
return store.state.chains.selected
|
||||||
return selected
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<layout-vertical>
|
<layout-vertical>
|
||||||
|
|
||||||
<router-view />
|
<router-view :key="$route.fullPath" />
|
||||||
|
|
||||||
<template #navbar="{ toggleVerticalMenuActive }">
|
<template #navbar="{ toggleVerticalMenuActive }">
|
||||||
<navbar :toggle-vertical-menu-active="toggleVerticalMenuActive" />
|
<navbar :toggle-vertical-menu-active="toggleVerticalMenuActive" />
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
export function toDay(time) {
|
export function toDay(time) {
|
||||||
return dayjs(time).format('YYYY-MM-DD')
|
return dayjs(time).format('YYYY-MM-DD HH:mm')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function percent(num) {
|
export function percent(num) {
|
||||||
return (num * 100).toFixed(2)
|
return parseFloat((num * 100).toFixed(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatToken(token) {
|
export function formatToken(token) {
|
||||||
// token.denom
|
|
||||||
// token.amount
|
|
||||||
let denom = token.denom.toUpperCase()
|
let denom = token.denom.toUpperCase()
|
||||||
if (denom.charAt(0) === 'U') {
|
if (denom.charAt(0) === 'U') {
|
||||||
denom = denom.substring(1)
|
denom = denom.substring(1)
|
||||||
@ -18,6 +16,13 @@ export function formatToken(token) {
|
|||||||
return `${(token.amount / 1000000).toFixed()} ${denom}`
|
return `${(token.amount / 1000000).toFixed()} ${denom}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function tokenFormatter(tokens) {
|
||||||
|
if (Array.isArray(tokens)) {
|
||||||
|
return tokens.map(t => formatToken(t))
|
||||||
|
}
|
||||||
|
return formatToken(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
export * from 'compare-versions'
|
export * from 'compare-versions'
|
||||||
|
|
||||||
export class Data {
|
export class Data {
|
||||||
|
18
src/libs/data/deposit.js
Normal file
18
src/libs/data/deposit.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export default class Deposit {
|
||||||
|
constructor() {
|
||||||
|
this.proposal_id = ''
|
||||||
|
this.depositor = ''
|
||||||
|
this.amount = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
this.proposal_id = element.proposal_id
|
||||||
|
this.depositor = element.depositor
|
||||||
|
this.amount = element.amount
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return console.log(this)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,10 @@
|
|||||||
export { default as Proposal } from './proposal'
|
export { default as Proposal } from './proposal'
|
||||||
export { default as ProposalTally } from './proposal-tally'
|
export { default as ProposalTally } from './proposal-tally'
|
||||||
export { default as StakingPool } from './staking-pool'
|
export { default as StakingPool } from './staking-pool'
|
||||||
|
export { default as Proposer } from './proposer'
|
||||||
|
export { default as Votes } from './votes'
|
||||||
|
export { default as Deposit } from './deposit'
|
||||||
|
export { default as Validator } from './validator'
|
||||||
|
export * from './data'
|
||||||
|
|
||||||
export default class Test {}
|
export default class Test {}
|
||||||
|
@ -1,13 +1,28 @@
|
|||||||
import { percent } from './data'
|
import { percent } from './data'
|
||||||
|
|
||||||
export default class ProposalTally {
|
export default class ProposalTally {
|
||||||
constructor(element, total) {
|
constructor() {
|
||||||
this.yes = percent(Number(element.yes) / total)
|
this.total = 0
|
||||||
this.no = percent(Number(element.no) / total)
|
this.yes = 0
|
||||||
this.veto = percent(Number(element.no_with_veto) / total)
|
this.no = 0
|
||||||
this.abstain = percent(Number(element.abstain) / total)
|
this.veto = 0
|
||||||
this.turnout = percent((Number(element.yes) + Number(element.no) + Number(element.abstain) + Number(element.no_with_veto)) / total)
|
this.abstain = 0
|
||||||
this.total = total
|
this.turnout = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element, total) {
|
||||||
|
const subtotal = Number(element.yes) + Number(element.no) + Number(element.abstain) + Number(element.no_with_veto)
|
||||||
|
if (total < 1) {
|
||||||
|
this.total = subtotal + 1
|
||||||
|
} else {
|
||||||
|
this.total = total
|
||||||
|
}
|
||||||
|
this.yes = percent(Number(element.yes) / this.total)
|
||||||
|
this.no = percent(Number(element.no) / this.total)
|
||||||
|
this.veto = percent(Number(element.no_with_veto) / this.total)
|
||||||
|
this.abstain = percent(Number(element.abstain) / this.total)
|
||||||
|
this.turnout = percent(subtotal / this.total)
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
total() {
|
total() {
|
||||||
|
@ -1,31 +1,43 @@
|
|||||||
import compareVersions from 'compare-versions'
|
import compareVersions from 'compare-versions'
|
||||||
import { toDay, formatToken, percent } from './data'
|
import { toDay, formatToken } from './data'
|
||||||
|
import ProposalTally from './proposal-tally'
|
||||||
|
|
||||||
export default class Proposal {
|
export default class Proposal {
|
||||||
constructor(element, total) {
|
constructor() {
|
||||||
|
this.element = null
|
||||||
|
|
||||||
|
this.id = 0
|
||||||
|
this.status = 1
|
||||||
|
this.type = '-'
|
||||||
|
this.title = '-'
|
||||||
|
this.description = '-'
|
||||||
|
this.tally = new ProposalTally()
|
||||||
|
this.submit_time = ' - '
|
||||||
|
this.voting_end_time = '0000-00-00'
|
||||||
|
this.voting_start_time = '-'
|
||||||
|
this.total_deposit = '-'
|
||||||
|
this.contents = null
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element, total) {
|
||||||
this.element = element
|
this.element = element
|
||||||
const yes = Number(element.final_tally_result.yes)
|
|
||||||
const no = Number(element.final_tally_result.no)
|
|
||||||
const abstain = Number(element.final_tally_result.abstain)
|
|
||||||
const veto = Number(element.final_tally_result.no_with_veto)
|
|
||||||
|
|
||||||
this.id = element.id
|
this.id = element.id
|
||||||
this.status = element.status
|
this.status = element.status
|
||||||
this.type = element.content.type
|
this.type = element.content.type
|
||||||
this.title = element.content.value.title
|
this.title = element.content.value.title
|
||||||
this.description = element.content.value.description
|
this.description = element.content.value.description
|
||||||
this.tally = {
|
this.tally = new ProposalTally().init(element.final_tally_result, total)
|
||||||
yes: percent(yes / total),
|
|
||||||
no: percent(no / total),
|
|
||||||
abstain: percent(abstain / total),
|
|
||||||
veto: percent(veto / total),
|
|
||||||
turnout: percent((yes + no + abstain + veto) / total),
|
|
||||||
total,
|
|
||||||
}
|
|
||||||
this.submit_time = toDay(element.submit_time)
|
this.submit_time = toDay(element.submit_time)
|
||||||
this.voting_end_time = toDay(element.voting_end_time)
|
this.voting_end_time = toDay(element.voting_end_time)
|
||||||
this.voting_start_time = toDay(element.voting_start_time)
|
this.voting_start_time = toDay(element.voting_start_time)
|
||||||
this.total_deposit = formatToken(element.total_deposit[0])
|
this.total_deposit = formatToken(element.total_deposit[0])
|
||||||
|
this.contents = element.content.value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
hello() {
|
||||||
|
return this.title
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTally(newTally) {
|
updateTally(newTally) {
|
||||||
@ -33,7 +45,6 @@ export default class Proposal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
versionFixed(ver) {
|
versionFixed(ver) {
|
||||||
console.log(ver, compareVersions(ver, '0.4'))
|
|
||||||
if (compareVersions(ver, '0.40') >= 0) {
|
if (compareVersions(ver, '0.40') >= 0) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (compareVersions(ver, '0.37') >= 0) {
|
} else if (compareVersions(ver, '0.37') >= 0) {
|
||||||
@ -50,7 +61,6 @@ export default class Proposal {
|
|||||||
default:
|
default:
|
||||||
this.status = 1
|
this.status = 1
|
||||||
}
|
}
|
||||||
console.log(this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
src/libs/data/proposer.js
Normal file
18
src/libs/data/proposer.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export default class Proposer {
|
||||||
|
constructor() {
|
||||||
|
this.proposal_id = ''
|
||||||
|
this.proposer = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
if (element != null) {
|
||||||
|
this.proposal_id = element.proposal_id
|
||||||
|
this.proposer = element.proposer
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return console.log(this)
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,17 @@
|
|||||||
import { percent } from './data'
|
import { percent } from './data'
|
||||||
|
|
||||||
export default class StakingPool {
|
export default class StakingPool {
|
||||||
constructor(element) {
|
constructor() {
|
||||||
|
this.element = null
|
||||||
|
this.bondedToken = 0
|
||||||
|
this.notBondedToken = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
this.element = element
|
this.element = element
|
||||||
this.bondedToken = Number(element.bonded_tokens)
|
this.bondedToken = Number(element.bonded_tokens)
|
||||||
this.notBondedToken = Number(element.not_bonded_tokens)
|
this.notBondedToken = Number(element.not_bonded_tokens)
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
total() {
|
total() {
|
||||||
@ -12,6 +19,6 @@ export default class StakingPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bondedRatio() {
|
bondedRatio() {
|
||||||
return percent((this.bondedToken * 100) / this.total)
|
return percent((this.bondedToken * 100) / this.total())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
src/libs/data/valdiator-description.js
Normal file
24
src/libs/data/valdiator-description.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
export default class ValidatorDescription {
|
||||||
|
constructor() {
|
||||||
|
this.moniker = 'string'
|
||||||
|
this.identity = 'string'
|
||||||
|
this.website = 'string'
|
||||||
|
this.security_contact = 'string'
|
||||||
|
this.details = 'string'
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
if (element != null) {
|
||||||
|
this.moniker = element.moniker
|
||||||
|
this.identity = element.identity
|
||||||
|
this.website = element.website
|
||||||
|
this.security_contact = element.security_contact
|
||||||
|
this.details = element.details
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return console.log(this)
|
||||||
|
}
|
||||||
|
}
|
22
src/libs/data/validator-commission.js
Normal file
22
src/libs/data/validator-commission.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export default class ValidatorCommission {
|
||||||
|
constructor() {
|
||||||
|
this.rate = '0'
|
||||||
|
this.max_rate = '0'
|
||||||
|
this.max_change_rate = '0'
|
||||||
|
this.update_time = '1970-01-01T00:00:00Z'
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
if (element != null) {
|
||||||
|
this.rate = element.commission_rates.rate
|
||||||
|
this.max_rate = element.commission_rates.max_rate
|
||||||
|
this.max_change_rate = element.commission_rates.max_change_rate
|
||||||
|
this.update_time = element.update_time
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return console.log(this)
|
||||||
|
}
|
||||||
|
}
|
35
src/libs/data/validator.js
Normal file
35
src/libs/data/validator.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import ValidatorCommission from './validator-commission'
|
||||||
|
import ValidatorDescription from './valdiator-description'
|
||||||
|
|
||||||
|
export default class Validator {
|
||||||
|
constructor() {
|
||||||
|
this.operator_address = 'cosmosvaloper16xyempempp92x9hyzz9wrgf94r6j9h5f2w4n2l'
|
||||||
|
this.consensus_pubkey = 'cosmosvalconspub1zcjduepq0vu2zgkgk49efa0nqwzndanq5m4c7pa3u4apz4g2r9gspqg6g9cs3k9cuf'
|
||||||
|
this.jailed = true
|
||||||
|
this.status = 0
|
||||||
|
this.tokens = '-'
|
||||||
|
this.delegator_shares = 0
|
||||||
|
this.description = new ValidatorDescription()
|
||||||
|
this.bond_height = 0
|
||||||
|
this.bond_intra_tx_counter = 0
|
||||||
|
this.unbonding_height = 0
|
||||||
|
this.unbonding_time = '1970-01-01T00:00:00Z'
|
||||||
|
this.commission = new ValidatorCommission()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
this.operator_address = element.operator_address
|
||||||
|
this.consensus_pubkey = element.consensus_pubkey
|
||||||
|
this.jailed = element.jailed
|
||||||
|
this.status = element.status
|
||||||
|
this.tokens = element.tokens
|
||||||
|
this.delegator_shares = element.delegator_shares
|
||||||
|
this.description = new ValidatorDescription().init(element.description)
|
||||||
|
this.bond_height = element.bond_height
|
||||||
|
this.bond_intra_tx_counter = element.bond_intra_tx_counter
|
||||||
|
this.unbonding_height = element.unbonding_height
|
||||||
|
this.unbonding_time = element.unbonding_time
|
||||||
|
this.commission = new ValidatorCommission().init(element.commission)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
18
src/libs/data/votes.js
Normal file
18
src/libs/data/votes.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export default class Votes {
|
||||||
|
constructor() {
|
||||||
|
this.proposal_id = 0
|
||||||
|
this.voter = ''
|
||||||
|
this.option = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
init(element) {
|
||||||
|
this.proposal_id = element.proposal_id
|
||||||
|
this.voter = element.voter
|
||||||
|
this.option = element.option
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
return console.log(this)
|
||||||
|
}
|
||||||
|
}
|
@ -1,50 +1,67 @@
|
|||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import DefaultHandler from '@/libs/default-handler'
|
import {
|
||||||
import { Proposal, ProposalTally, StakingPool } from './data'
|
Proposal, ProposalTally, Proposer, StakingPool, Votes, Deposit,
|
||||||
|
Validator,
|
||||||
const requestVersion = async (c, url) => {
|
} from './data'
|
||||||
const response = await fetch(url)
|
|
||||||
const json = await response.json()
|
|
||||||
const sdk = json.application_version.build_deps.find(e => e.startsWith('github.com/cosmos/cosmos-sdk'))
|
|
||||||
const re = /(\d+(\.\d+)*)/i
|
|
||||||
const version = sdk.match(re)
|
|
||||||
console.log(`${c} sdk version:`, version[0])
|
|
||||||
store.commit('setup_sdk_version', { chain_name: c, version: version[0] })
|
|
||||||
return version[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
function commonProcess(res) {
|
function commonProcess(res) {
|
||||||
return res.result
|
return res.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 头像
|
||||||
|
export async function keybase(identity) {
|
||||||
|
return fetch(`https://keybase.io/_/api/1.0/user/lookup.json?key_suffix=${identity}&fields=pictures`)
|
||||||
|
.then(res => res.json())
|
||||||
|
}
|
||||||
|
|
||||||
const chainAPI = class ChainFetch {
|
const chainAPI = class ChainFetch {
|
||||||
constructor(route) {
|
getSelectedConfig() {
|
||||||
const c = route.params.chain
|
this.config = store.state.chains.selected
|
||||||
const has = Object.keys(store.state.chains.chains).findIndex(i => i === c)
|
return this.config
|
||||||
const selected = (has > -1) ? store.state.chains.chains[c] : store.state.chains.chains.cosmos
|
|
||||||
if (selected.sdk_version === undefined) {
|
|
||||||
const v = requestVersion(c, `${selected.api}/node_info`)
|
|
||||||
selected.sdk_version = v
|
|
||||||
}
|
|
||||||
this.config = selected
|
|
||||||
this.handler = new DefaultHandler()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStakingPool() {
|
async getStakingPool() {
|
||||||
return this.get('/staking/pool').then(data => new StakingPool(commonProcess(data)))
|
return this.get('/staking/pool').then(data => new StakingPool().init(commonProcess(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getValidatorList() {
|
||||||
|
return this.get('/staking/validators').then(data => commonProcess(data).map(i => new Validator().init(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGovernanceTally(pid, total) {
|
async getGovernanceTally(pid, total) {
|
||||||
return this.get(`/gov/proposals/${pid}/tally`).then(data => new ProposalTally(commonProcess(data), total))
|
return this.get(`/gov/proposals/${pid}/tally`).then(data => new ProposalTally().init(commonProcess(data), total))
|
||||||
|
}
|
||||||
|
|
||||||
|
getGovernance(pid) {
|
||||||
|
return this.get(`/gov/proposals/${pid}`).then(data => {
|
||||||
|
const p = new Proposal().init(commonProcess(data), 0)
|
||||||
|
p.versionFixed(this.config.sdk_version)
|
||||||
|
return p
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGovernanceProposer(pid) {
|
||||||
|
return this.get(`/gov/proposals/${pid}/proposer`).then(data => new Proposer().init(commonProcess(data))).catch(e => console.log(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGovernanceDeposits(pid) {
|
||||||
|
return this.get(`/gov/proposals/${pid}/deposits`).then(data => {
|
||||||
|
const result = commonProcess(data)
|
||||||
|
return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGovernanceVotes(pid) {
|
||||||
|
return this.get(`/gov/proposals/${pid}/votes`).then(data => commonProcess(data).map(d => new Votes().init(d)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGovernanceList() {
|
async getGovernanceList() {
|
||||||
return Promise.all([this.get('/gov/proposals'), this.get('/staking/pool')]).then(data => {
|
return Promise.all([this.get('/gov/proposals'), this.get('/staking/pool')]).then(data => {
|
||||||
const pool = new StakingPool(commonProcess(data[1]))
|
const pool = new StakingPool().init(commonProcess(data[1]))
|
||||||
const ret = []
|
const ret = []
|
||||||
commonProcess(data[0]).forEach(e => {
|
commonProcess(data[0]).forEach(e => {
|
||||||
const g = new Proposal(e, pool.bondedToken)
|
const g = new Proposal().init(e, pool.bondedToken)
|
||||||
g.versionFixed(this.config.sdk_version)
|
g.versionFixed(this.config.sdk_version)
|
||||||
ret.push(g)
|
ret.push(g)
|
||||||
})
|
})
|
||||||
@ -53,8 +70,9 @@ const chainAPI = class ChainFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async get(url) {
|
async get(url) {
|
||||||
const response = await fetch(this.config.api + url)
|
this.getSelectedConfig()
|
||||||
return response.json()
|
const ret = await fetch(this.config.api + url).then(response => response.json()).catch(e => console.log(e))
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,13 +6,14 @@ import messages from '@/lang'
|
|||||||
|
|
||||||
import VueI18n from 'vue-i18n'
|
import VueI18n from 'vue-i18n'
|
||||||
|
|
||||||
|
import ChainAPI from '@/libs/fetch'
|
||||||
|
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
|
||||||
// Global Components
|
// Global Components
|
||||||
import './global-components'
|
import './global-components'
|
||||||
import '@/libs/fetch'
|
|
||||||
|
|
||||||
// 3rd party plugins
|
// 3rd party plugins
|
||||||
import '@/libs/portal-vue'
|
import '@/libs/portal-vue'
|
||||||
@ -41,6 +42,7 @@ require('@core/scss/core.scss')
|
|||||||
require('@/assets/scss/style.scss')
|
require('@/assets/scss/style.scss')
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
Vue.prototype.$http = new ChainAPI()
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
|
@ -29,10 +29,10 @@ function processMenu() {
|
|||||||
header: 'blockchains',
|
header: 'blockchains',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
Object.keys(store.state.chains.chains).forEach(chain => {
|
Object.keys(store.state.chains.config).forEach(chain => {
|
||||||
const menu = {
|
const menu = {
|
||||||
title: chain,
|
title: chain,
|
||||||
icon: 'PieChartIcon',
|
icon: store.state.chains.config[chain].logo,
|
||||||
}
|
}
|
||||||
const children = []
|
const children = []
|
||||||
modules.forEach(m => {
|
modules.forEach(m => {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
import store from '../store'
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|
||||||
@ -24,20 +26,6 @@ const router = new VueRouter({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/second-page',
|
|
||||||
name: 'second-page',
|
|
||||||
component: () => import('@/views/Info.vue'),
|
|
||||||
meta: {
|
|
||||||
pageTitle: 'Second Page',
|
|
||||||
breadcrumb: [
|
|
||||||
{
|
|
||||||
text: 'Second Page',
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// chain modules
|
// chain modules
|
||||||
{
|
{
|
||||||
path: '/:chain/info',
|
path: '/:chain/info',
|
||||||
@ -79,6 +67,28 @@ const router = new VueRouter({
|
|||||||
text: 'Governance',
|
text: 'Governance',
|
||||||
active: true,
|
active: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Proposals',
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/:chain/gov/:proposalid',
|
||||||
|
name: 'proposal',
|
||||||
|
component: () => import('@/views/ProposalView.vue'),
|
||||||
|
meta: {
|
||||||
|
pageTitle: 'Governance',
|
||||||
|
breadcrumb: [
|
||||||
|
{
|
||||||
|
text: 'Governance',
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Proposal Detail',
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -105,6 +115,26 @@ const router = new VueRouter({
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
const c = to.params.chain
|
||||||
|
const has = Object.keys(store.state.chains.config).findIndex(i => i === c)
|
||||||
|
if (has > -1) {
|
||||||
|
const chain = store.state.chains.config[c]
|
||||||
|
store.commit('select', { chain_name: c })
|
||||||
|
if (chain.sdk_version === undefined) {
|
||||||
|
fetch(`${chain.api}/node_info`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(json => {
|
||||||
|
const sdk = json.application_version.build_deps.find(e => e.startsWith('github.com/cosmos/cosmos-sdk'))
|
||||||
|
const re = /(\d+(\.\d+)*)/i
|
||||||
|
const version = sdk.match(re)
|
||||||
|
store.commit('setup_sdk_version', { chain_name: c, version: version[0] })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
// ? For splash screen
|
// ? For splash screen
|
||||||
// Remove afterEach hook if you are not using splash screen
|
// Remove afterEach hook if you are not using splash screen
|
||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
|
7
src/store/chains/crypto.json
Normal file
7
src/store/chains/crypto.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
{
|
||||||
|
"chain_name": "crypto",
|
||||||
|
"chain_id": "akashnet-1",
|
||||||
|
"api": "https://mainnet.crypto.org:1317",
|
||||||
|
"logo": "https://look.ping.pub/static/chains/cosmoshub.svg"
|
||||||
|
}
|
@ -9,14 +9,18 @@ configs.keys().forEach(k => {
|
|||||||
export default {
|
export default {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state: {
|
state: {
|
||||||
chains,
|
config: chains,
|
||||||
|
selected: {},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getchains: state => state.chains,
|
getchains: state => state.chains,
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setup_sdk_version(state, info) {
|
setup_sdk_version(state, info) {
|
||||||
state.chains.chains[info.chain_name].sdk_version = info.version
|
state.chains.config[info.chain_name].sdk_version = info.version
|
||||||
|
},
|
||||||
|
select(state, args) {
|
||||||
|
state.chains.selected = state.chains.config[args.chain_name]
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
>
|
>
|
||||||
Rejected
|
Rejected
|
||||||
</b-badge>
|
</b-badge>
|
||||||
#{{ p.id }}. {{ p.title }}
|
#{{ p.id }}. <a :href="`./gov/${p.id}`">{{ p.title }}</a>
|
||||||
</b-card-title>
|
</b-card-title>
|
||||||
<b-card-body md="12">
|
<b-card-body md="12">
|
||||||
<div class="gov-wrapper">
|
<div class="gov-wrapper">
|
||||||
@ -57,14 +57,6 @@
|
|||||||
{{ p.voting_end_time }}
|
{{ p.voting_end_time }}
|
||||||
</h6>
|
</h6>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="gov">
|
|
||||||
<p class="card-text mb-25">
|
|
||||||
Proposer
|
|
||||||
</p>
|
|
||||||
<h6 class="mb-0">
|
|
||||||
Ping.pub
|
|
||||||
</h6>
|
|
||||||
</div> -->
|
|
||||||
<div class="gov">
|
<div class="gov">
|
||||||
<p class="card-text mb-25">
|
<p class="card-text mb-25">
|
||||||
Deposit
|
Deposit
|
||||||
@ -136,17 +128,26 @@
|
|||||||
{{ p.tally.abstain }}% voted Abstain
|
{{ p.tally.abstain }}% voted Abstain
|
||||||
</b-tooltip>
|
</b-tooltip>
|
||||||
<b-card-footer>
|
<b-card-footer>
|
||||||
<b-button
|
<router-link
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
|
:to="`./gov/${p.id}`"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
|
class="btn"
|
||||||
>
|
>
|
||||||
Detail
|
<b-button
|
||||||
</b-button>
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
|
:href="`./gov/${p.id}`"
|
||||||
|
variant="outline-primary"
|
||||||
|
>
|
||||||
|
{{ $t('btn_detail') }}
|
||||||
|
</b-button>
|
||||||
|
</router-link>
|
||||||
<b-button
|
<b-button
|
||||||
|
:disabled="p.status!=2"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2"
|
class="btn float-right mg-2"
|
||||||
>
|
>
|
||||||
Vote
|
{{ $t('btn_vote') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</b-card-footer>
|
</b-card-footer>
|
||||||
</b-card>
|
</b-card>
|
||||||
@ -158,7 +159,7 @@ import {
|
|||||||
BCard, BCardTitle, BCardBody, BCardFooter, BButton, BProgressBar, BProgress, BBadge, BTooltip,
|
BCard, BCardTitle, BCardBody, BCardFooter, BButton, BProgressBar, BProgress, BBadge, BTooltip,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import Ripple from 'vue-ripple-directive'
|
import Ripple from 'vue-ripple-directive'
|
||||||
import ChainAPI from '@/libs/fetch'
|
import { Proposal } from '@/libs/data'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -177,43 +178,64 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
proposals: [new Proposal()],
|
||||||
values: [15, 50, 10, 5],
|
values: [15, 50, 10, 5],
|
||||||
max: 1,
|
max: 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
mounted() {
|
||||||
selected_c() {
|
this.getList()
|
||||||
console.log(localStorage.getItem('selected_chain'))
|
|
||||||
return localStorage.getItem('selected_chain')
|
|
||||||
},
|
|
||||||
// this.$http.get()
|
|
||||||
},
|
},
|
||||||
asyncComputed: {
|
methods: {
|
||||||
proposals: {
|
getList() {
|
||||||
get() {
|
// this.$http.setup(this.$route)
|
||||||
const api = new ChainAPI(this.$route)
|
this.$http.getGovernanceList().then(res => {
|
||||||
return api.getGovernanceList().then(res => {
|
const voting = res.filter(i => i.status === 2)
|
||||||
const voting = res.filter(i => i.status === 2)
|
if (voting.length > 0) {
|
||||||
if (voting.length > 0) {
|
let i = 0
|
||||||
let i = 0
|
Promise.all(voting.reverse().map(p => this.$http.getGovernanceTally(p.id, p.tally.total))).then(update => {
|
||||||
Promise.all(voting.reverse().map(p => api.getGovernanceTally(p.id, p.tally.total))).then(update => {
|
this.proposals.map(x => {
|
||||||
this.proposals.map(x => {
|
if (x.status === 2) {
|
||||||
if (x.status === 2) {
|
const xh = x
|
||||||
const xh = x
|
xh.tally = update[i]
|
||||||
xh.tally = update[i]
|
i += 1
|
||||||
i += 1
|
return xh
|
||||||
return xh
|
}
|
||||||
}
|
return x
|
||||||
return x
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
return res.reverse()
|
}
|
||||||
})
|
this.proposals = res.reverse()
|
||||||
},
|
})
|
||||||
// default: 'loading...',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// asyncComputed: {
|
||||||
|
// proposals: {
|
||||||
|
// get() {
|
||||||
|
// const api = new ChainAPI(this.$route)
|
||||||
|
// api.setup(this.$route)
|
||||||
|
// return api.getGovernanceList().then(res => {
|
||||||
|
// const voting = res.filter(i => i.status === 2)
|
||||||
|
// if (voting.length > 0) {
|
||||||
|
// let i = 0
|
||||||
|
// Promise.all(voting.reverse().map(p => api.getGovernanceTally(p.id, p.tally.total))).then(update => {
|
||||||
|
// this.proposals.map(x => {
|
||||||
|
// if (x.status === 2) {
|
||||||
|
// const xh = x
|
||||||
|
// xh.tally = update[i]
|
||||||
|
// i += 1
|
||||||
|
// return xh
|
||||||
|
// }
|
||||||
|
// return x
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// return res.reverse()
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
// // default: 'loading...',
|
||||||
|
// },
|
||||||
|
// },
|
||||||
// watch: {
|
// watch: {
|
||||||
// proposals(val, newdata) {
|
// proposals(val, newdata) {
|
||||||
// console.log('In watch', val, newdata)
|
// console.log('In watch', val, newdata)
|
||||||
@ -251,6 +273,6 @@ section {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gov-wrapper .gov {
|
.gov-wrapper .gov {
|
||||||
width: 8.4rem;
|
width: 9.8rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { BCard, BCardText } from 'bootstrap-vue'
|
import { BCard, BCardText } from 'bootstrap-vue'
|
||||||
// import fetch from 'node-fetch'
|
// import fetch from 'node-fetch'
|
||||||
import '@/libs/fetch'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -26,14 +25,6 @@ export default {
|
|||||||
// }).catch(e => {
|
// }).catch(e => {
|
||||||
// console.log(e)
|
// console.log(e)
|
||||||
// })
|
// })
|
||||||
this.fetchdata('http://lcd.akash.forbole.com/node_info', {
|
|
||||||
Headers: {
|
|
||||||
'Content-Type': 'text/html',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then(response => {
|
|
||||||
console.log(response)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
357
src/views/ProposalView.vue
Normal file
357
src/views/ProposalView.vue
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
<template>
|
||||||
|
<section>
|
||||||
|
<b-card>
|
||||||
|
<b-card-header>
|
||||||
|
<b-card-title>
|
||||||
|
<b-badge
|
||||||
|
v-if="proposal.status == 1"
|
||||||
|
pill
|
||||||
|
variant="light-info"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Deposit
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="proposal.status == 2"
|
||||||
|
pill
|
||||||
|
variant="light-primary"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Voting
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="proposal.status == 3"
|
||||||
|
pill
|
||||||
|
variant="light-success"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Passed
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-if="proposal.status == 4"
|
||||||
|
pill
|
||||||
|
variant="light-danger"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
Rejected
|
||||||
|
</b-badge>
|
||||||
|
#{{ proposal.id }} {{ proposal.title }}
|
||||||
|
</b-card-title>
|
||||||
|
</b-card-header>
|
||||||
|
<b-card-body>
|
||||||
|
<b-table-simple>
|
||||||
|
<b-tr>
|
||||||
|
<b-td lg="2">
|
||||||
|
{{ $t('proposal_id') }}
|
||||||
|
</b-td><b-td>{{ proposal.id }}</b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_proposer') }}
|
||||||
|
</b-td><b-td>{{ proposer.proposer }} </b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_total_deposit') }}
|
||||||
|
</b-td><b-td>{{ proposal.total_deposit }} </b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_submit_time') }}
|
||||||
|
</b-td><b-td>{{ proposal.submit_time }}</b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_voting_start_time') }}
|
||||||
|
</b-td><b-td>{{ proposal.voting_start_time }}</b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_voting_end_time') }}
|
||||||
|
</b-td><b-td>{{ proposal.voting_end_time }}</b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr>
|
||||||
|
<b-td>
|
||||||
|
{{ $t('proposal_type') }}
|
||||||
|
</b-td><b-td>{{ proposal.type }}</b-td>
|
||||||
|
</b-tr>
|
||||||
|
<b-tr
|
||||||
|
v-for="(value, name) in proposal.contents"
|
||||||
|
:key="name"
|
||||||
|
>
|
||||||
|
<b-td style="text-transform: capitalize; vertical-align: top;">
|
||||||
|
{{ name.replaceAll('_',' ') }}
|
||||||
|
</b-td>
|
||||||
|
<b-td v-if="!Array.isArray(value)">
|
||||||
|
{{ value }}
|
||||||
|
</b-td>
|
||||||
|
<b-td v-if="Array.isArray(value) && name === 'amount'">
|
||||||
|
<span
|
||||||
|
v-for="token in value"
|
||||||
|
:key="token.amount"
|
||||||
|
>
|
||||||
|
{{ token.amount }} {{ token.denom }}
|
||||||
|
</span>
|
||||||
|
</b-td>
|
||||||
|
<b-td v-if="Array.isArray(value) && name != 'amount'">
|
||||||
|
<b-table :items="value">
|
||||||
|
<!-- A custom formatted column -->
|
||||||
|
<template #cell(amount)="data">
|
||||||
|
<span
|
||||||
|
v-for="token in data.value"
|
||||||
|
:key="token.amount"
|
||||||
|
>
|
||||||
|
{{ token.amount }} {{ token.denom }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
|
</b-td>
|
||||||
|
</b-tr>
|
||||||
|
</b-table-simple>
|
||||||
|
</b-card-body>
|
||||||
|
<b-card-footer>
|
||||||
|
<router-link :to="`../gov`">
|
||||||
|
<b-button
|
||||||
|
variant="outline-primary"
|
||||||
|
>
|
||||||
|
{{ $t('btn_back_list') }}
|
||||||
|
</b-button>
|
||||||
|
</router-link>
|
||||||
|
<b-button
|
||||||
|
:disabled="proposer.status!=2"
|
||||||
|
variant="primary"
|
||||||
|
class="btn float-right mg-2"
|
||||||
|
>
|
||||||
|
{{ $t('btn_vote') }}
|
||||||
|
</b-button>
|
||||||
|
</b-card-footer>
|
||||||
|
</b-card>
|
||||||
|
|
||||||
|
<b-card>
|
||||||
|
<b-card-header>
|
||||||
|
<b-card-title>
|
||||||
|
Votes
|
||||||
|
</b-card-title>
|
||||||
|
</b-card-header>
|
||||||
|
<b-card-body>
|
||||||
|
<b-progress
|
||||||
|
:max="100"
|
||||||
|
height="2rem"
|
||||||
|
class="mb-2"
|
||||||
|
show-progress
|
||||||
|
>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-yes'+proposal.id"
|
||||||
|
variant="success"
|
||||||
|
:value="proposal.tally.yes"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-no'+proposal.id"
|
||||||
|
variant="warning"
|
||||||
|
:value="proposal.tally.no"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-veto'+proposal.id"
|
||||||
|
variant="danger"
|
||||||
|
:value="proposal.tally.veto"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
<b-progress-bar
|
||||||
|
:id="'vote-abstain'+proposal.id"
|
||||||
|
variant="info"
|
||||||
|
:value="proposal.tally.abstain"
|
||||||
|
show-progress
|
||||||
|
/>
|
||||||
|
</b-progress>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-yes'+proposal.id"
|
||||||
|
>
|
||||||
|
{{ proposal.tally.yes }}% voted Yes
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-no'+proposal.id"
|
||||||
|
>
|
||||||
|
{{ proposal.tally.no }}% voted No
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-veto'+proposal.id"
|
||||||
|
>
|
||||||
|
{{ proposal.tally.veto }}% voted No With Veta
|
||||||
|
</b-tooltip>
|
||||||
|
<b-tooltip
|
||||||
|
:target="'vote-abstain'+proposal.id"
|
||||||
|
>
|
||||||
|
{{ proposal.tally.abstain }}% voted Abstain
|
||||||
|
</b-tooltip>
|
||||||
|
<b-table
|
||||||
|
:fields="votes_fields"
|
||||||
|
:items="votes"
|
||||||
|
/>
|
||||||
|
</b-card-body>
|
||||||
|
</b-card>
|
||||||
|
<b-card>
|
||||||
|
<b-card-header>
|
||||||
|
<b-card-title>
|
||||||
|
Deposits ({{ proposal.total_deposit }})
|
||||||
|
</b-card-title>
|
||||||
|
</b-card-header>
|
||||||
|
<b-card-body>
|
||||||
|
<b-table
|
||||||
|
:items="deposits"
|
||||||
|
:fields="deposit_fields"
|
||||||
|
/>
|
||||||
|
</b-card-body>
|
||||||
|
<b-card-footer>
|
||||||
|
<router-link :to="`../gov`">
|
||||||
|
<b-button
|
||||||
|
variant="outline-primary"
|
||||||
|
>
|
||||||
|
{{ $t('btn_back_list') }}
|
||||||
|
</b-button>
|
||||||
|
</router-link>
|
||||||
|
<b-button
|
||||||
|
:disabled="proposer.status!=2"
|
||||||
|
variant="primary"
|
||||||
|
class="btn float-right mg-2"
|
||||||
|
>
|
||||||
|
{{ $t('btn_vote') }}
|
||||||
|
</b-button>
|
||||||
|
</b-card-footer>
|
||||||
|
</b-card>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
BCard, BCardBody, BCardFooter, BButton, BTable, BTableSimple, BTr, BTd, BCardTitle, BCardHeader,
|
||||||
|
BProgressBar, BProgress, BTooltip, BBadge,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
|
// import fetch from 'node-fetch'
|
||||||
|
|
||||||
|
import { tokenFormatter } from '@/libs/data/data'
|
||||||
|
import { Proposal, Proposer } from '@/libs/data'
|
||||||
|
// import { formatToken } from '@/libs/data/data'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BCard,
|
||||||
|
BCardTitle,
|
||||||
|
BCardBody,
|
||||||
|
BCardFooter,
|
||||||
|
BButton,
|
||||||
|
BTable,
|
||||||
|
BTableSimple,
|
||||||
|
BCardHeader,
|
||||||
|
BTr,
|
||||||
|
BTd,
|
||||||
|
BProgressBar,
|
||||||
|
BProgress,
|
||||||
|
BTooltip,
|
||||||
|
BBadge,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
proposal: new Proposal(),
|
||||||
|
proposer: new Proposer(),
|
||||||
|
deposits: [],
|
||||||
|
votes: [],
|
||||||
|
votes_fields: [
|
||||||
|
{ key: 'voter', sortable: true },
|
||||||
|
{
|
||||||
|
key: 'option',
|
||||||
|
sortable: true,
|
||||||
|
formatter: value => {
|
||||||
|
switch (value) {
|
||||||
|
case 1:
|
||||||
|
return 'Yes'
|
||||||
|
case 2:
|
||||||
|
return 'Abstain'
|
||||||
|
case 3:
|
||||||
|
return 'No'
|
||||||
|
case 4:
|
||||||
|
return 'No With Veto'
|
||||||
|
default:
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
deposit_fields: [
|
||||||
|
'depositor',
|
||||||
|
{
|
||||||
|
key: 'amount',
|
||||||
|
sortable: true,
|
||||||
|
formatter: tokenFormatter,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
const pid = this.$route.params.proposalid
|
||||||
|
|
||||||
|
this.$http.getGovernance(pid).then(p => {
|
||||||
|
if (p.status === 2) {
|
||||||
|
this.$http.getGovernanceTally(pid, 0).then(t => p.updateTally(t)).catch(e => console.log('failed on update voting tally:', e))
|
||||||
|
}
|
||||||
|
this.proposal = p
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$http.getGovernanceProposer(pid).then(res => {
|
||||||
|
this.proposer = res
|
||||||
|
})
|
||||||
|
this.$http.getGovernanceDeposits(pid).then(res => {
|
||||||
|
this.deposits = res
|
||||||
|
})
|
||||||
|
this.$http.getGovernanceVotes(pid).then(res => {
|
||||||
|
this.votes = res
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// asyncComputed: {
|
||||||
|
// proposal: {
|
||||||
|
// get() {
|
||||||
|
// const pid = this.$route.params.proposalid
|
||||||
|
// // const api = new ChainAPI(this.$route)
|
||||||
|
// return this.$http.getGovernance(pid).then(p => {
|
||||||
|
// if (p.status === 2) {
|
||||||
|
// this.$http.getGovernanceTally(pid, 0).then(t => p.updateTally(t)).catch(e => console.log('failed on update voting tally:', e))
|
||||||
|
// }
|
||||||
|
// return p
|
||||||
|
// })
|
||||||
|
// },
|
||||||
|
// default: new Proposal(),
|
||||||
|
// },
|
||||||
|
// proposer: {
|
||||||
|
// get() {
|
||||||
|
// const pid = this.$route.params.proposalid
|
||||||
|
// // const api = new ChainAPI(this.$route)
|
||||||
|
// return this.$http.getGovernanceProposer(pid)
|
||||||
|
// },
|
||||||
|
// default: new Proposer(),
|
||||||
|
// },
|
||||||
|
// deposits: {
|
||||||
|
// get() {
|
||||||
|
// const pid = this.$route.params.proposalid
|
||||||
|
// // const api = new ChainAPI(this.$route)
|
||||||
|
// return this.$http.getGovernanceDeposits(pid)
|
||||||
|
// },
|
||||||
|
// default: [],
|
||||||
|
// },
|
||||||
|
// votes: {
|
||||||
|
// get() {
|
||||||
|
// const pid = this.$route.params.proposalid
|
||||||
|
// // const api = new ChainAPI(this.$route)
|
||||||
|
// return this.$http.getGovernanceVotes(pid)
|
||||||
|
// },
|
||||||
|
// default: [],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
@ -6,7 +6,8 @@
|
|||||||
>
|
>
|
||||||
<b-table
|
<b-table
|
||||||
responsive="sm"
|
responsive="sm"
|
||||||
:items="items"
|
:items="delegations"
|
||||||
|
:fields="validator_fields"
|
||||||
/>
|
/>
|
||||||
</b-card-code>
|
</b-card-code>
|
||||||
|
|
||||||
@ -16,41 +17,90 @@
|
|||||||
>
|
>
|
||||||
<b-table
|
<b-table
|
||||||
responsive="sm"
|
responsive="sm"
|
||||||
:items="items"
|
striped
|
||||||
/>
|
:items="validators"
|
||||||
|
:fields="validator_fields"
|
||||||
|
:sort-desc="true"
|
||||||
|
sort-by="tokens"
|
||||||
|
>
|
||||||
|
<!-- Column: Validator -->
|
||||||
|
<template #cell(description)="data">
|
||||||
|
<b-media vertical-align="center">
|
||||||
|
<template #aside>
|
||||||
|
<b-avatar
|
||||||
|
size="32"
|
||||||
|
icon="ChevronRightIcon"
|
||||||
|
variant="light-primary"
|
||||||
|
:src="data.item.avatar"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<span class="font-weight-bold d-block text-nowrap">
|
||||||
|
{{ data.item.description.moniker }}
|
||||||
|
</span>
|
||||||
|
<small class="text-muted">{{ data.item.description.website || data.item.description.identity }}</small>
|
||||||
|
</b-media>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
</b-card-code>
|
</b-card-code>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { BTable } from 'bootstrap-vue'
|
import { BTable, BMedia, BAvatar } from 'bootstrap-vue'
|
||||||
import BCardCode from '@core/components/b-card-code/BCardCode.vue'
|
import BCardCode from '@core/components/b-card-code/BCardCode.vue'
|
||||||
|
import { Validator, percent } from '@/libs/data'
|
||||||
|
import { keybase } from '@/libs/fetch'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
BCardCode,
|
BCardCode,
|
||||||
BTable,
|
BTable,
|
||||||
|
BMedia,
|
||||||
|
BAvatar,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
items: [
|
|
||||||
|
sortBy: 'tokens',
|
||||||
|
sortDesc: true,
|
||||||
|
validators: [new Validator()],
|
||||||
|
delegations: [new Validator()],
|
||||||
|
validator_fields: [
|
||||||
|
{ key: 'description', label: 'Validator', sortable: true },
|
||||||
{
|
{
|
||||||
age: 40, first_name: 'Dickerson', last_name: 'Macdonald', Occupation: 'Job',
|
key: 'tokens',
|
||||||
|
sortable: true,
|
||||||
|
formatter: value => parseInt(value / 100000, 0),
|
||||||
|
tdClass: 'text-right',
|
||||||
|
thClass: 'text-right',
|
||||||
|
sortByFormatted: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
age: 21, first_name: 'Larsen', last_name: 'Shaw', Occupation: 'Job',
|
key: 'commission',
|
||||||
},
|
sortable: true,
|
||||||
{
|
formatter: value => `${percent(value.rate)}%`,
|
||||||
age: 89, first_name: 'Geneva', last_name: 'Wilson', Occupation: 'Bussiness',
|
tdClass: 'text-right',
|
||||||
},
|
thClass: 'text-right',
|
||||||
{
|
|
||||||
age: 38, first_name: 'Jami', last_name: 'Carney', Occupation: 'Bussiness',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
age: 40, first_name: 'James', last_name: 'Thomson', Occupation: 'Job',
|
|
||||||
},
|
},
|
||||||
|
{ key: 'delegator_shares', sortable: true },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.$http.getValidatorList().then(res => {
|
||||||
|
this.validators = res
|
||||||
|
this.validators.forEach(i => {
|
||||||
|
if (i.description.identity) {
|
||||||
|
keybase(i.description.identity).then(d => {
|
||||||
|
if (Array.isArray(d.them) && d.them.length > 0) {
|
||||||
|
console.log(d.them[0].pictures.primary.url)
|
||||||
|
const validator = this.validators.find(u => u.description.identity === i.description.identity)
|
||||||
|
validator.avatar = d.them[0].pictures.primary.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user