forked from cerc-io/cosmos-explorer
add new Dashboard
This commit is contained in:
parent
0fb20ce4f3
commit
da77476827
@ -255,16 +255,20 @@ export default {
|
|||||||
},
|
},
|
||||||
accounts() {
|
accounts() {
|
||||||
let accounts = getLocalAccounts() || {}
|
let accounts = getLocalAccounts() || {}
|
||||||
accounts = Object.entries(accounts).map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.selected_chain.chain_name) }))
|
accounts = Object.entries(accounts)
|
||||||
|
.map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.selected_chain.chain_name) }))
|
||||||
|
.filter(v => v.address)
|
||||||
|
|
||||||
if (accounts.length > 0) {
|
// accounts > 0 and wallet not setted, pick the first one as default
|
||||||
|
if (accounts.length > 0 && accounts.findIndex(x => x.wallet === this.walletName) < 0) {
|
||||||
this.updateDefaultWallet(accounts[0].wallet)
|
this.updateDefaultWallet(accounts[0].wallet)
|
||||||
}
|
}
|
||||||
return accounts.filter(x => x.address)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
|
|
||||||
|
if (accounts.findIndex(x => x.wallet === this.walletName) < 0 && this.walletName !== 'Wallet') {
|
||||||
|
this.updateDefaultWallet(null)
|
||||||
|
}
|
||||||
|
return accounts
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatAddr(v) {
|
formatAddr(v) {
|
||||||
|
@ -416,6 +416,10 @@ export default class ChainFetch {
|
|||||||
return this.get('/bank/balances/'.concat(address), config).then(data => commonProcess(data))
|
return this.get('/bank/balances/'.concat(address), config).then(data => commonProcess(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getCommunityPool(config = null) {
|
||||||
|
return this.get('/cosmos/distribution/v1beta1/community_pool', config).then(data => commonProcess(data))
|
||||||
|
}
|
||||||
|
|
||||||
async getAllIBCDenoms(config = null) {
|
async getAllIBCDenoms(config = null) {
|
||||||
const conf = config || this.getSelectedConfig()
|
const conf = config || this.getSelectedConfig()
|
||||||
const sdkVersion = conf.sdk_version
|
const sdkVersion = conf.sdk_version
|
||||||
@ -470,6 +474,14 @@ export default class ChainFetch {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getCoinInfo(coin = null) {
|
||||||
|
const conf = this.getSelectedConfig()
|
||||||
|
if (conf.assets[0] && conf.assets[0].coingecko_id) {
|
||||||
|
return ChainFetch.fetch(' https://api.coingecko.com', `/api/v3/coins/${coin || conf.assets[0].coingecko_id}`)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
// CoinMarketCap
|
// CoinMarketCap
|
||||||
static async fetchCoinMarketCap(url) {
|
static async fetchCoinMarketCap(url) {
|
||||||
const host = 'https://price.ping.pub'
|
const host = 'https://price.ping.pub'
|
||||||
|
@ -439,9 +439,9 @@ export function formatNumber(count, withAbbr = false, decimals = 2) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tokenFormatter(tokens, denoms = {}) {
|
export function tokenFormatter(tokens, denoms = {}, decimal = 2) {
|
||||||
if (Array.isArray(tokens)) {
|
if (Array.isArray(tokens)) {
|
||||||
return tokens.map(t => formatToken(t, denoms, 2)).join(', ')
|
return tokens.map(t => formatToken(t, denoms, decimal)).join(', ')
|
||||||
}
|
}
|
||||||
return formatToken(tokens, denoms, 2)
|
return formatToken(tokens, denoms, 2)
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ const router = new VueRouter({
|
|||||||
path: '/:chain/',
|
path: '/:chain/',
|
||||||
name: 'dashboard',
|
name: 'dashboard',
|
||||||
alias: '/:chain',
|
alias: '/:chain',
|
||||||
component: () => import('@/views/Summary.vue'),
|
component: () => import('@/views/Dashboard.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
pageTitle: 'Home',
|
pageTitle: 'Home',
|
||||||
breadcrumb: [
|
breadcrumb: [
|
||||||
@ -136,7 +136,7 @@ const router = new VueRouter({
|
|||||||
{
|
{
|
||||||
path: '/:chain/parameters',
|
path: '/:chain/parameters',
|
||||||
name: 'parameters',
|
name: 'parameters',
|
||||||
component: () => import('@/views/Summary.vue'),
|
component: () => import('@/views/Parameters.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
pageTitle: 'Parameters',
|
pageTitle: 'Parameters',
|
||||||
breadcrumb: [
|
breadcrumb: [
|
||||||
@ -400,7 +400,6 @@ router.beforeEach((to, from, next) => {
|
|||||||
const c = to.params.chain
|
const c = to.params.chain
|
||||||
if (c) {
|
if (c) {
|
||||||
store.commit('select', { chain_name: String(c).toLowerCase() })
|
store.commit('select', { chain_name: String(c).toLowerCase() })
|
||||||
store.dispatch('chains/getAllIBCDenoms', Vue.prototype)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = JSON.parse(localStorage.getItem('chains'))
|
const config = JSON.parse(localStorage.getItem('chains'))
|
||||||
|
@ -70,6 +70,8 @@ export default {
|
|||||||
if (defaultWallet && defaultWallet.length > 0) {
|
if (defaultWallet && defaultWallet.length > 0) {
|
||||||
localStorage.setItem('default-wallet', defaultWallet)
|
localStorage.setItem('default-wallet', defaultWallet)
|
||||||
state.chains.defaultWallet = defaultWallet
|
state.chains.defaultWallet = defaultWallet
|
||||||
|
} else {
|
||||||
|
state.chains.defaultWallet = null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setIBCDenoms(state, denoms) {
|
setIBCDenoms(state, denoms) {
|
||||||
|
@ -47,8 +47,8 @@ import { fromBase64 } from '@cosmjs/encoding'
|
|||||||
import { decodeTxRaw } from '@cosmjs/proto-signing'
|
import { decodeTxRaw } from '@cosmjs/proto-signing'
|
||||||
import Tx from '@/libs/data/tx'
|
import Tx from '@/libs/data/tx'
|
||||||
import { abbrMessage, tokenFormatter } from '@/libs/utils'
|
import { abbrMessage, tokenFormatter } from '@/libs/utils'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||||
import ArrayFieldComponent from './ArrayFieldComponent.vue'
|
import ArrayFieldComponent from './components/ArrayFieldComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
418
src/views/Dashboard.vue
Normal file
418
src/views/Dashboard.vue
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<b-alert
|
||||||
|
variant="danger"
|
||||||
|
:show="syncing"
|
||||||
|
>
|
||||||
|
<div class="alert-body">
|
||||||
|
<span>No new blocks have been produced since <strong>{{ latestTime }}</strong> </span>
|
||||||
|
</div>
|
||||||
|
</b-alert>
|
||||||
|
|
||||||
|
<b-row>
|
||||||
|
<b-col><dashboard-price-chart-2 /></b-col>
|
||||||
|
</b-row>
|
||||||
|
<!-- Stats Card Vertical -->
|
||||||
|
<b-row class="match-height">
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
icon="BoxIcon"
|
||||||
|
:statistic="height"
|
||||||
|
statistic-title="Height"
|
||||||
|
color="info"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
color="warning"
|
||||||
|
icon="DollarSignIcon"
|
||||||
|
:statistic="supply"
|
||||||
|
statistic-title="Total Supply"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
color="danger"
|
||||||
|
icon="PercentIcon"
|
||||||
|
:statistic="ratio"
|
||||||
|
:statistic-title="`Bonded: ${bonded}`"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
color="primary"
|
||||||
|
icon="TrendingUpIcon"
|
||||||
|
:statistic="inflation"
|
||||||
|
statistic-title="Inflation"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
color="success"
|
||||||
|
icon="AwardIcon"
|
||||||
|
:statistic="communityPool"
|
||||||
|
statistic-title="Community Pool"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
xl="2"
|
||||||
|
md="4"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-vertical
|
||||||
|
hide-chart
|
||||||
|
color="danger"
|
||||||
|
icon="UserCheckIcon"
|
||||||
|
:statistic="validators"
|
||||||
|
statistic-title="Active Validators"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-card no-body>
|
||||||
|
<b-card-header>
|
||||||
|
<b-card-title>Active Proposals</b-card-title>
|
||||||
|
</b-card-header>
|
||||||
|
<b-card-body>
|
||||||
|
<b-link
|
||||||
|
v-for="prop in proposals"
|
||||||
|
:key="prop.id"
|
||||||
|
:to="`./${chain}/gov/${prop.id}`"
|
||||||
|
>
|
||||||
|
<b-media
|
||||||
|
no-body
|
||||||
|
class="mb-1"
|
||||||
|
>
|
||||||
|
<b-media-aside>
|
||||||
|
<b-avatar
|
||||||
|
rounded
|
||||||
|
size="42"
|
||||||
|
variant="light-primary"
|
||||||
|
>
|
||||||
|
{{ prop.id }}
|
||||||
|
</b-avatar>
|
||||||
|
</b-media-aside>
|
||||||
|
<b-media-body class="d-flex flex-column justify-content-center">
|
||||||
|
<h6 class="transaction-title">
|
||||||
|
{{ prop.title }}
|
||||||
|
</h6>
|
||||||
|
<small>{{ formatType(prop.contents['@type']) }} {{ formatEnding(prop.voting_end_time) }}</small>
|
||||||
|
</b-media-body>
|
||||||
|
</b-media>
|
||||||
|
</b-link>
|
||||||
|
<div v-if="proposals.length === 0">
|
||||||
|
No active proposal!
|
||||||
|
<b-link :to="`./${chain}/gov`">
|
||||||
|
Browse all
|
||||||
|
</b-link>
|
||||||
|
</div>
|
||||||
|
</b-card-body>
|
||||||
|
</b-card>
|
||||||
|
<b-card
|
||||||
|
border-variant="primary"
|
||||||
|
:title="`${walletName} Assets`"
|
||||||
|
bg-variant="transparent"
|
||||||
|
class="shadow-none"
|
||||||
|
>
|
||||||
|
<b-row>
|
||||||
|
<b-col
|
||||||
|
lg="3"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-horizontal
|
||||||
|
icon="DollarSignIcon"
|
||||||
|
color="success"
|
||||||
|
:statistic="walletBalances"
|
||||||
|
statistic-title="Balances"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
lg="3"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-horizontal
|
||||||
|
icon="BoxIcon"
|
||||||
|
:statistic="walletStaking"
|
||||||
|
statistic-title="Staking"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
lg="3"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-horizontal
|
||||||
|
icon="PercentIcon"
|
||||||
|
color="danger"
|
||||||
|
:statistic="walletRewards"
|
||||||
|
statistic-title="Rewards"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
lg="3"
|
||||||
|
sm="6"
|
||||||
|
>
|
||||||
|
<dashboard-card-horizontal
|
||||||
|
icon="TrendingUpIcon"
|
||||||
|
color="warning"
|
||||||
|
|
||||||
|
:statistic="walletUnbonding"
|
||||||
|
statistic-title="Unbonding"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-card>
|
||||||
|
<router-link to="/wallet/import">
|
||||||
|
<b-card class="addzone text-center">
|
||||||
|
<feather-icon icon="PlusIcon" />
|
||||||
|
Connect Wallet
|
||||||
|
</b-card>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
BRow, BCol, BAlert, BCard, BTable, BFormCheckbox, BCardHeader, BCardTitle, BMedia, BMediaAside, BMediaBody, BAvatar,
|
||||||
|
BCardBody, BLink,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
|
import {
|
||||||
|
formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter, getLocalAccounts,
|
||||||
|
} from '@/libs/utils'
|
||||||
|
import ParametersModuleComponent from './components/parameters/ParametersModuleComponent.vue'
|
||||||
|
import DashboardCardHorizontal from './components/dashboard/DashboardCardHorizontal.vue'
|
||||||
|
import DashboardCardVertical from './components/dashboard/DashboardCardVertical.vue'
|
||||||
|
import DashboardPriceChart2 from './components/dashboard/DashboardPriceChart2.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BAvatar,
|
||||||
|
BRow,
|
||||||
|
BCol,
|
||||||
|
BAlert,
|
||||||
|
BCard,
|
||||||
|
BTable,
|
||||||
|
BFormCheckbox,
|
||||||
|
BCardHeader,
|
||||||
|
BCardTitle,
|
||||||
|
BMediaBody,
|
||||||
|
BMediaAside,
|
||||||
|
BMedia,
|
||||||
|
BCardBody,
|
||||||
|
BLink,
|
||||||
|
|
||||||
|
ParametersModuleComponent,
|
||||||
|
DashboardCardHorizontal,
|
||||||
|
DashboardPriceChart2,
|
||||||
|
DashboardCardVertical,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chain: this.$store.state.chains.selected.chain_name,
|
||||||
|
syncing: false,
|
||||||
|
latestTime: '',
|
||||||
|
marketData: null,
|
||||||
|
height: '-',
|
||||||
|
supply: '-',
|
||||||
|
bonded: '-',
|
||||||
|
validators: '-',
|
||||||
|
communityPool: '-',
|
||||||
|
ratio: '-',
|
||||||
|
inflation: '-',
|
||||||
|
proposals: [],
|
||||||
|
|
||||||
|
walletBalances: '-',
|
||||||
|
walletStaking: '-',
|
||||||
|
walletRewards: '-',
|
||||||
|
walletUnbonding: '-',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
walletName() {
|
||||||
|
const key = this.$store?.state?.chains?.defaultWallet
|
||||||
|
return key || 'Wallet'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$http.getLatestBlock().then(res => {
|
||||||
|
this.height = res.block.header.height
|
||||||
|
if (timeIn(res.block.header.time, 3, 'm')) {
|
||||||
|
this.syncing = true
|
||||||
|
} else {
|
||||||
|
this.syncing = false
|
||||||
|
}
|
||||||
|
this.latestTime = toDay(res.block.header.time, 'long')
|
||||||
|
this.validators = res.block.last_commit.signatures.length
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$http.getStakingParameters().then(res => {
|
||||||
|
Promise.all([this.$http.getStakingPool(), this.$http.getBankTotal(res.bond_denom)])
|
||||||
|
.then(pool => {
|
||||||
|
this.supply = `${formatNumber(formatTokenAmount(pool[1].amount, 2, res.bond_denom, false), true, 2)}`
|
||||||
|
this.bonded = `${formatNumber(formatTokenAmount(pool[0].bondedToken, 2, res.bond_denom, false), true, 2)}`
|
||||||
|
this.ratio = `${percent(pool[0].bondedToken / pool[1].amount)}%`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$http.getCommunityPool().then(res => {
|
||||||
|
this.communityPool = this.formatToken(res.pool)
|
||||||
|
})
|
||||||
|
|
||||||
|
const conf = this.$http.getSelectedConfig()
|
||||||
|
if (conf.excludes && conf.excludes.indexOf('mint') > -1) {
|
||||||
|
this.inflation = '-'
|
||||||
|
} else {
|
||||||
|
this.$http.getMintingInflation().then(res => {
|
||||||
|
this.inflation = `${percent(res)}%`
|
||||||
|
}).catch(() => {
|
||||||
|
this.inflation = '-'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$http.getGovernanceListByStatus(2).then(res => {
|
||||||
|
this.proposals = res.proposals
|
||||||
|
})
|
||||||
|
|
||||||
|
const accounts = getLocalAccounts() || {}
|
||||||
|
const account = Object.entries(accounts)
|
||||||
|
.map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.$store.state.chains.selected.chain_name) }))
|
||||||
|
.filter(v => v.address)
|
||||||
|
.find(x => x.wallet === this.walletName)
|
||||||
|
if (account) {
|
||||||
|
this.fetchAccount(account.address.addr)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatToken(tokens) {
|
||||||
|
if (Array.isArray(tokens)) {
|
||||||
|
let nativeToken = tokens.filter(x => !x.denom.toUpperCase().startsWith('IBC/'))
|
||||||
|
if (tokens.length > 1) {
|
||||||
|
const sum = {}
|
||||||
|
const reduce = nativeToken.reduce((b, a) => {
|
||||||
|
const b2 = b
|
||||||
|
if (b2[a.denom]) {
|
||||||
|
b2[a.denom] += Number(a.amount)
|
||||||
|
} else {
|
||||||
|
b2[a.denom] = Number(a.amount)
|
||||||
|
}
|
||||||
|
return b2
|
||||||
|
}, sum)
|
||||||
|
nativeToken = Object.keys(reduce).map(k => ({ denom: k, amount: reduce[k] }))
|
||||||
|
}
|
||||||
|
return tokenFormatter(nativeToken, {}, 0)
|
||||||
|
}
|
||||||
|
return '-'
|
||||||
|
},
|
||||||
|
fetchAccount(address) {
|
||||||
|
this.$http.getBankAccountBalance(address).then(bal => {
|
||||||
|
this.walletBalances = this.formatToken(bal)
|
||||||
|
})
|
||||||
|
this.$http.getStakingReward(address).then(res => {
|
||||||
|
this.walletRewards = this.formatToken(res.rewards.map(x => x.reward).flat())
|
||||||
|
})
|
||||||
|
this.$http.getStakingDelegations(address).then(res => {
|
||||||
|
const delegations = res.delegation_responses || res
|
||||||
|
this.walletStaking = this.formatToken(delegations.map(x => x.balance).flat())
|
||||||
|
})
|
||||||
|
this.$http.getStakingUnbonding(address).then(res => {
|
||||||
|
const token = this.$store.state.chains.selected.assets[0]
|
||||||
|
if (token) {
|
||||||
|
const newTokens = []
|
||||||
|
const denom = token.base
|
||||||
|
const unbonding = res.unbonding_responses || res
|
||||||
|
unbonding.forEach(x => {
|
||||||
|
x.entries.forEach(y => {
|
||||||
|
newTokens.push({
|
||||||
|
amount: y.balance,
|
||||||
|
denom,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.walletUnbonding = this.formatToken(newTokens)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
formatEnding(v) {
|
||||||
|
return toDay(v, 'from')
|
||||||
|
},
|
||||||
|
formatType(v) {
|
||||||
|
const txt = String(v).replace('Proposal', '')
|
||||||
|
const index = txt.lastIndexOf('.')
|
||||||
|
return index > 0 ? txt.substring(index + 1) : txt
|
||||||
|
},
|
||||||
|
normalize(data, title) {
|
||||||
|
if (!data) return null
|
||||||
|
const items = this.makeItems(data)
|
||||||
|
return {
|
||||||
|
title,
|
||||||
|
items,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
makeItems(data) {
|
||||||
|
return Object.keys(data).map(k => {
|
||||||
|
if (isToken(data[k])) {
|
||||||
|
return { title: tokenFormatter(data[k]), subtitle: k }
|
||||||
|
}
|
||||||
|
if (typeof data[k] === 'boolean') {
|
||||||
|
return { title: data[k], subtitle: k }
|
||||||
|
}
|
||||||
|
return { title: this.convert(data[k]), subtitle: k }
|
||||||
|
})
|
||||||
|
},
|
||||||
|
convert(v) {
|
||||||
|
if (typeof v === 'object') {
|
||||||
|
const v2 = {}
|
||||||
|
Object.entries(v).forEach(e => {
|
||||||
|
const k = e[0]
|
||||||
|
const x = e[1]
|
||||||
|
v2[k] = this.convert(x)
|
||||||
|
})
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
const d = parseFloat(v)
|
||||||
|
if (d === 0) return '0'
|
||||||
|
if (d < 1.01) {
|
||||||
|
return `${percent(d)}%`
|
||||||
|
}
|
||||||
|
if (d > 1000000000) {
|
||||||
|
return `${toDuration(d / 1000000)}`
|
||||||
|
}
|
||||||
|
if (d > 0) {
|
||||||
|
return d.toFixed()
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.addzone {
|
||||||
|
border: 2px dashed #ced4da;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.addzone :hover {
|
||||||
|
border: 2px dashed #7367F0;
|
||||||
|
}
|
||||||
|
</style>
|
@ -278,7 +278,7 @@ import {
|
|||||||
import { Proposal, Proposer } from '@/libs/data'
|
import { Proposal, Proposer } from '@/libs/data'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||||
|
|
||||||
// import { formatToken } from '@/libs/data/data'
|
// import { formatToken } from '@/libs/data/data'
|
||||||
|
|
||||||
|
@ -118,7 +118,6 @@ import { formatTokenDenom } from '@/libs/utils'
|
|||||||
import FeatherIcon from '@/@core/components/feather-icon/FeatherIcon.vue'
|
import FeatherIcon from '@/@core/components/feather-icon/FeatherIcon.vue'
|
||||||
import Place from './components/KlineTrade/Place.vue'
|
import Place from './components/KlineTrade/Place.vue'
|
||||||
// import Kline from './components/kline/index.vue'
|
// import Kline from './components/kline/index.vue'
|
||||||
import SummaryPriceChart from './SummaryPriceChart.vue'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -130,7 +129,6 @@ export default {
|
|||||||
BSpinner,
|
BSpinner,
|
||||||
Place,
|
Place,
|
||||||
BCard,
|
BCard,
|
||||||
SummaryPriceChart,
|
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
},
|
},
|
||||||
beforeRouteUpdate(to, from, next) {
|
beforeRouteUpdate(to, from, next) {
|
||||||
|
@ -10,50 +10,32 @@
|
|||||||
</b-alert>
|
</b-alert>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-parmeters-component
|
<parameters-module-component :data="chain" />
|
||||||
:data="chain"
|
|
||||||
/>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row v-if="marketChartData">
|
|
||||||
<b-col>
|
|
||||||
<b-card>
|
|
||||||
<summary-price-chart
|
|
||||||
:chart-data="marketChartData"
|
|
||||||
:height="150"
|
|
||||||
:min-height="150"
|
|
||||||
/>
|
|
||||||
</b-card>
|
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-assets-component />
|
<parameters-module-component :data="mint" />
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-parmeters-component :data="mint" />
|
<parameters-module-component :data="staking" />
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<summary-parmeters-component :data="staking" />
|
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row v-if="gov.items.length > 0">
|
<b-row v-if="gov.items.length > 0">
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-parmeters-component :data="gov" />
|
<parameters-module-component :data="gov" />
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-parmeters-component :data="distribution" />
|
<parameters-module-component :data="distribution" />
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col>
|
<b-col>
|
||||||
<summary-parmeters-component :data="slashing" />
|
<parameters-module-component :data="slashing" />
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</div>
|
</div>
|
||||||
@ -64,12 +46,10 @@ import {
|
|||||||
BRow, BCol, BAlert, BCard,
|
BRow, BCol, BAlert, BCard,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import {
|
import {
|
||||||
formatNumber, formatTokenAmount, getUserCurrency, isToken, percent, timeIn, toDay, toDuration, tokenFormatter,
|
formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
|
|
||||||
import SummaryParmetersComponent from './SummaryParmetersComponent.vue'
|
import ParametersModuleComponent from './components/parameters/ParametersModuleComponent.vue'
|
||||||
import SummaryAssetsComponent from './SummaryAssetsComponent.vue'
|
|
||||||
import SummaryPriceChart from './SummaryPriceChart.vue'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -77,9 +57,7 @@ export default {
|
|||||||
BCol,
|
BCol,
|
||||||
BAlert,
|
BAlert,
|
||||||
BCard,
|
BCard,
|
||||||
SummaryParmetersComponent,
|
ParametersModuleComponent,
|
||||||
SummaryAssetsComponent,
|
|
||||||
SummaryPriceChart,
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -118,29 +96,6 @@ export default {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
marketChartData() {
|
|
||||||
if (this.marketData && this.marketData.prices) {
|
|
||||||
const labels = this.marketData.prices.map(x => x[0])
|
|
||||||
const data = this.marketData.prices.map(x => x[1])
|
|
||||||
return {
|
|
||||||
labels,
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
label: `Price (${getUserCurrency().toUpperCase()})`,
|
|
||||||
data,
|
|
||||||
backgroundColor: 'rgba(54, 162, 235, 0.2)',
|
|
||||||
borderColor: 'rgba(54, 162, 235, 1)',
|
|
||||||
borderWidth: 1,
|
|
||||||
pointStyle: 'dash',
|
|
||||||
barThickness: 15,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
created() {
|
||||||
this.$http.getLatestBlock().then(res => {
|
this.$http.getLatestBlock().then(res => {
|
||||||
const height = this.chain.items.findIndex(x => x.subtitle === 'height')
|
const height = this.chain.items.findIndex(x => x.subtitle === 'height')
|
@ -204,70 +204,68 @@
|
|||||||
</b-card-footer>
|
</b-card-footer>
|
||||||
</b-card>
|
</b-card>
|
||||||
<!-- First Row -->
|
<!-- First Row -->
|
||||||
<template>
|
<b-row class="match-height">
|
||||||
<b-row class="match-height">
|
<b-col
|
||||||
<b-col
|
lg="4"
|
||||||
lg="4"
|
md="12"
|
||||||
md="12"
|
>
|
||||||
>
|
<staking-commission-component :data="validator.commission" />
|
||||||
<staking-commission-component :data="validator.commission" />
|
</b-col>
|
||||||
</b-col>
|
<b-col
|
||||||
<b-col
|
lg="4"
|
||||||
lg="4"
|
md="12"
|
||||||
md="12"
|
>
|
||||||
>
|
<staking-reward-component
|
||||||
<staking-reward-component
|
:data="distribution"
|
||||||
:data="distribution"
|
:validator="validator.operator_address"
|
||||||
:validator="validator.operator_address"
|
:address="accountAddress"
|
||||||
:address="accountAddress"
|
/>
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
lg="4"
|
||||||
|
md="12"
|
||||||
|
>
|
||||||
|
<staking-address-component
|
||||||
|
:hex-address="hexAddress"
|
||||||
|
:operator-address="validator.operator_address"
|
||||||
|
:consensus-pubkey="validator.consensus_pubkey"
|
||||||
|
:account-address="accountAddress"
|
||||||
|
/>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-row>
|
||||||
|
<b-col>
|
||||||
|
<b-card title="Transactions">
|
||||||
|
<b-table
|
||||||
|
:items="txs"
|
||||||
|
striped
|
||||||
|
hover
|
||||||
|
responsive="sm"
|
||||||
|
stacked="sm"
|
||||||
|
>
|
||||||
|
<template #cell(height)="data">
|
||||||
|
<router-link :to="`../blocks/${data.item.height}`">
|
||||||
|
{{ data.item.height }}
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
<template #cell(txhash)="data">
|
||||||
|
<router-link :to="`../tx/${data.item.txhash}`">
|
||||||
|
{{ formatHash(data.item.txhash) }}
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
</b-table>
|
||||||
|
<b-pagination
|
||||||
|
v-if="Number(transactions.page_total) > 1"
|
||||||
|
:total-rows="transactions.total_count"
|
||||||
|
:per-page="transactions.limit"
|
||||||
|
:value="transactions.page_number"
|
||||||
|
align="center"
|
||||||
|
class="mt-1"
|
||||||
|
@change="pageload"
|
||||||
/>
|
/>
|
||||||
</b-col>
|
</b-card>
|
||||||
<b-col
|
</b-col>
|
||||||
lg="4"
|
</b-row>
|
||||||
md="12"
|
|
||||||
>
|
|
||||||
<staking-address-component
|
|
||||||
:hex-address="hexAddress"
|
|
||||||
:operator-address="validator.operator_address"
|
|
||||||
:consensus-pubkey="validator.consensus_pubkey"
|
|
||||||
:account-address="accountAddress"
|
|
||||||
/>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-card title="Transactions">
|
|
||||||
<b-table
|
|
||||||
:items="txs"
|
|
||||||
striped
|
|
||||||
hover
|
|
||||||
responsive="sm"
|
|
||||||
stacked="sm"
|
|
||||||
>
|
|
||||||
<template #cell(height)="data">
|
|
||||||
<router-link :to="`../blocks/${data.item.height}`">
|
|
||||||
{{ data.item.height }}
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
<template #cell(txhash)="data">
|
|
||||||
<router-link :to="`../tx/${data.item.txhash}`">
|
|
||||||
{{ formatHash(data.item.txhash) }}
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
</b-table>
|
|
||||||
<b-pagination
|
|
||||||
v-if="Number(transactions.page_total) > 1"
|
|
||||||
:total-rows="transactions.total_count"
|
|
||||||
:per-page="transactions.limit"
|
|
||||||
:value="transactions.page_number"
|
|
||||||
align="center"
|
|
||||||
class="mt-1"
|
|
||||||
@change="pageload"
|
|
||||||
/>
|
|
||||||
</b-card>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</template>
|
|
||||||
<operation-modal
|
<operation-modal
|
||||||
type="Delegate"
|
type="Delegate"
|
||||||
:validator-address="validator.operator_address"
|
:validator-address="validator.operator_address"
|
||||||
@ -286,9 +284,9 @@ import {
|
|||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import { keybase } from '@/libs/fetch'
|
import { keybase } from '@/libs/fetch'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||||
import StakingAddressComponent from './StakingAddressComponent.vue'
|
import StakingAddressComponent from './components/staking/StakingAddressComponent.vue'
|
||||||
import StakingCommissionComponent from './StakingCommissionComponent.vue'
|
import StakingCommissionComponent from './components/staking/StakingCommissionComponent.vue'
|
||||||
import StakingRewardComponent from './StakingRewardComponent.vue'
|
import StakingRewardComponent from './components/staking/StakingRewardComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -107,7 +107,7 @@ import {
|
|||||||
BCard, BTableSimple, BTr, BTd, BBadge, BCardBody, BAlert,
|
BCard, BTableSimple, BTr, BTd, BBadge, BCardBody, BAlert,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import { toDay, tokenFormatter } from '@/libs/utils'
|
import { toDay, tokenFormatter } from '@/libs/utils'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -430,8 +430,8 @@ import {
|
|||||||
toDuration, abbrMessage, abbrAddress, getUserCurrency, getUserCurrencySign, numberWithCommas, toETHAddress,
|
toDuration, abbrMessage, abbrAddress, getUserCurrency, getUserCurrencySign, numberWithCommas, toETHAddress,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||||
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
import ChartComponentDoughnut from './components/charts/ChartComponentDoughnut.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -251,7 +251,7 @@ import ToastificationContent from '@core/components/toastification/Toastificatio
|
|||||||
import AppCollapse from '@core/components/app-collapse/AppCollapse.vue'
|
import AppCollapse from '@core/components/app-collapse/AppCollapse.vue'
|
||||||
import AppCollapseItem from '@core/components/app-collapse/AppCollapseItem.vue'
|
import AppCollapseItem from '@core/components/app-collapse/AppCollapseItem.vue'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||||
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
import ChartComponentDoughnut from './components/charts/ChartComponentDoughnut.vue'
|
||||||
import EchartScatter from './components/charts/EchartScatter.vue'
|
import EchartScatter from './components/charts/EchartScatter.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<b-tabs content-class="mt-1">
|
<b-tabs content-class="mt-1">
|
||||||
<!-- This tabs content will always be mounted -->
|
<!-- This tabs content will always be mounted -->
|
||||||
<b-tab
|
<b-tab
|
||||||
title="Ongoing Proposals"
|
title="Active Proposals"
|
||||||
pill
|
pill
|
||||||
>
|
>
|
||||||
<b-row class="match-height">
|
<b-row class="match-height">
|
||||||
@ -158,7 +158,7 @@ import {
|
|||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import WalletUpgradeEvents from './WalletUpgradeEvents.vue'
|
import WalletUpgradeEvents from './WalletUpgradeEvents.vue'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
import { percent } from '@/libs/utils'
|
import { percent } from '@/libs/utils'
|
||||||
import { $themeColors } from '@themeConfig'
|
import { $themeColors } from '@themeConfig'
|
||||||
|
|
||||||
import ChartjsComponentDoughnutChart from './ChartjsComponentDoughnutChart.vue'
|
import ChartjsComponentDoughnutChart from './ChartjsComponentDoughnutChart'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartDoughnut',
|
name: 'ChartDoughnut',
|
51
src/views/components/dashboard/DashboardCardHorizontal.vue
Normal file
51
src/views/components/dashboard/DashboardCardHorizontal.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<b-card no-body>
|
||||||
|
<b-card-body class="d-flex justify-content-between align-items-center">
|
||||||
|
<div class="truncate">
|
||||||
|
<h2 class="mb-25 font-weight-bolder">
|
||||||
|
{{ statistic }}
|
||||||
|
</h2>
|
||||||
|
<span>{{ statisticTitle }}</span>
|
||||||
|
</div>
|
||||||
|
<b-avatar
|
||||||
|
:variant="`light-${color}`"
|
||||||
|
size="45"
|
||||||
|
>
|
||||||
|
<feather-icon
|
||||||
|
size="21"
|
||||||
|
:icon="icon"
|
||||||
|
/>
|
||||||
|
</b-avatar>
|
||||||
|
</b-card-body>
|
||||||
|
</b-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { BCard, BCardBody, BAvatar } from 'bootstrap-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BCard,
|
||||||
|
BCardBody,
|
||||||
|
BAvatar,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
statistic: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
statisticTitle: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
49
src/views/components/dashboard/DashboardCardVertical.vue
Normal file
49
src/views/components/dashboard/DashboardCardVertical.vue
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<b-card class="text-center">
|
||||||
|
<b-avatar
|
||||||
|
class="mb-1"
|
||||||
|
:variant="`light-${color}`"
|
||||||
|
size="45"
|
||||||
|
>
|
||||||
|
<feather-icon
|
||||||
|
size="21"
|
||||||
|
:icon="icon"
|
||||||
|
/>
|
||||||
|
</b-avatar>
|
||||||
|
<div class="truncate">
|
||||||
|
<h2 class="mb-25 font-weight-bolder">
|
||||||
|
{{ statistic }}
|
||||||
|
</h2>
|
||||||
|
<span>{{ statisticTitle }}</span>
|
||||||
|
</div>
|
||||||
|
</b-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { BCard, BAvatar } from 'bootstrap-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BCard,
|
||||||
|
BAvatar,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
statistic: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
statisticTitle: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'primary',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
391
src/views/components/dashboard/DashboardPriceChart2.vue
Normal file
391
src/views/components/dashboard/DashboardPriceChart2.vue
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
<template>
|
||||||
|
<b-card v-if="marketData && marketData.prices">
|
||||||
|
<b-row>
|
||||||
|
<b-col md="4">
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<h2 class="font-weight-bold">
|
||||||
|
{{ coinInfo.name }} <span class="text-uppercase">({{ coinInfo.symbol }})</span>
|
||||||
|
</h2>
|
||||||
|
<span
|
||||||
|
v-b-tooltip.hover.v-danger
|
||||||
|
title="Coingecko Rank"
|
||||||
|
>Coingecko Rank: <b-badge variant="light-danger">
|
||||||
|
#{{ coinInfo.coingecko_rank }}
|
||||||
|
</b-badge></span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="my-1">
|
||||||
|
<b-badge
|
||||||
|
v-for="tag in coinInfo.categories"
|
||||||
|
:key="tag"
|
||||||
|
variant="light-secondary"
|
||||||
|
style="margin: 2px;"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</b-badge>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- buy -->
|
||||||
|
<div
|
||||||
|
class="rounded d-flex justify-content-between p-2"
|
||||||
|
:class="`bg-light-${color}`"
|
||||||
|
>
|
||||||
|
<b-dropdown
|
||||||
|
id="dropdown-3"
|
||||||
|
size="sm"
|
||||||
|
text="Pairs"
|
||||||
|
:variant="color"
|
||||||
|
>
|
||||||
|
<b-dropdown-item
|
||||||
|
v-for="(pair, i) in tickers"
|
||||||
|
:key="i"
|
||||||
|
@click="selectPair(pair)"
|
||||||
|
>
|
||||||
|
<b-row style="width:400px;">
|
||||||
|
<b-col cols="4">
|
||||||
|
{{ pair.market.name }}
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
cols="4"
|
||||||
|
class="text-uppercase text-truncate"
|
||||||
|
>
|
||||||
|
{{ coinInfo.symbol }}/{{ pair.target }}
|
||||||
|
</b-col>
|
||||||
|
<b-col
|
||||||
|
cols="4"
|
||||||
|
class="font-weight-bold"
|
||||||
|
:class="`text-${colorMap(pair.trust_score)}`"
|
||||||
|
>
|
||||||
|
${{ pair.converted_last.usd }}
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
<div class="text-truncate ml-1">
|
||||||
|
<sup class="text-body">
|
||||||
|
<small>$</small>
|
||||||
|
</sup>
|
||||||
|
<h2 class="d-inline mr-25">
|
||||||
|
{{ selectedTicker.converted_last.usd }}
|
||||||
|
</h2>
|
||||||
|
<sub class="text-body"><small>/ {{ selectedTicker.target }}</small></sub>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--/ buy -->
|
||||||
|
<b-button
|
||||||
|
block
|
||||||
|
:variant="color"
|
||||||
|
class="mt-1"
|
||||||
|
:href="selectedTicker.trade_url"
|
||||||
|
>
|
||||||
|
Buy {{ String(coinInfo.symbol).toUpperCase() }}
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</b-col>
|
||||||
|
<b-col md="8">
|
||||||
|
<b-card-header class="d-flex justify-content-between">
|
||||||
|
<!-- size -->
|
||||||
|
<b-button-group
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<b-button
|
||||||
|
:variant="type==='prices'? 'primary': 'outline-primary'"
|
||||||
|
@click="selectChart('prices')"
|
||||||
|
>
|
||||||
|
Price
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:variant="type !== 'prices'? 'primary': 'outline-primary'"
|
||||||
|
@click="selectChart('total_volumes')"
|
||||||
|
>
|
||||||
|
Volumes
|
||||||
|
</b-button>
|
||||||
|
</b-button-group>
|
||||||
|
<!-- size -->
|
||||||
|
<b-button-group
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<b-button
|
||||||
|
:variant="days===1? 'primary': 'outline-primary'"
|
||||||
|
@click="selectDays(1)"
|
||||||
|
>
|
||||||
|
Daily
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:variant="days===7? 'primary': 'outline-primary'"
|
||||||
|
@click="selectDays(7)"
|
||||||
|
>
|
||||||
|
Weekly
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:variant="days===30? 'primary': 'outline-primary'"
|
||||||
|
@click="selectDays(30)"
|
||||||
|
>
|
||||||
|
Monthly
|
||||||
|
</b-button>
|
||||||
|
</b-button-group>
|
||||||
|
</b-card-header>
|
||||||
|
|
||||||
|
<b-card-body class="pb-0">
|
||||||
|
<!-- apex chart -->
|
||||||
|
<vue-apex-charts
|
||||||
|
type="line"
|
||||||
|
height="240"
|
||||||
|
:options="chartOptions"
|
||||||
|
:series="series"
|
||||||
|
/>
|
||||||
|
</b-card-body>
|
||||||
|
</b-col>
|
||||||
|
</b-row>
|
||||||
|
<b-card-footer class="px-0">
|
||||||
|
<div v-if="coinInfo.description && coinInfo.description.en">
|
||||||
|
{{ coinInfo.description.en || '' }}
|
||||||
|
</div>
|
||||||
|
<div class="my-1">
|
||||||
|
LINKS:
|
||||||
|
<b-button
|
||||||
|
:href="homepage"
|
||||||
|
class="mr-1"
|
||||||
|
variant="outline-primary"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<feather-icon icon="CastIcon" /> Webwite
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:href="twitter"
|
||||||
|
class="mr-1"
|
||||||
|
variant="outline-primary"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<feather-icon icon="TwitterIcon" /> Twitter
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:href="github"
|
||||||
|
class="mr-1"
|
||||||
|
variant="outline-primary"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<feather-icon icon="GithubIcon" /> Github
|
||||||
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
:href="telegram"
|
||||||
|
class="mr-1"
|
||||||
|
variant="outline-primary"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<feather-icon icon="SendIcon" /> Telegram
|
||||||
|
</b-button>
|
||||||
|
<b-dropdown
|
||||||
|
v-if="coinInfo.links && coinInfo.links.blockchain_site"
|
||||||
|
id="dropdown-2"
|
||||||
|
size="sm"
|
||||||
|
text="Explorers"
|
||||||
|
variant="outline-primary"
|
||||||
|
>
|
||||||
|
<b-dropdown-item
|
||||||
|
v-for="site in coinInfo.links.blockchain_site.filter(x => x)"
|
||||||
|
:key="site"
|
||||||
|
:href="site"
|
||||||
|
>{{ site }}</b-dropdown-item>
|
||||||
|
</b-dropdown>
|
||||||
|
</div>
|
||||||
|
</b-card-footer>
|
||||||
|
</b-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
BCard, BCardHeader, BCardTitle, BCardBody, BCardText, BFormRadio, BButton, BButtonGroup, BCol, BRow,
|
||||||
|
BCardFooter, BBadge, VBTooltip, BDropdown, BDropdownItem,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
|
import VueApexCharts from 'vue-apexcharts'
|
||||||
|
import { $themeColors } from '@themeConfig'
|
||||||
|
import FeatherIcon from '../../../@core/components/feather-icon/FeatherIcon.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
VueApexCharts,
|
||||||
|
BCard,
|
||||||
|
BCardHeader,
|
||||||
|
BCardText,
|
||||||
|
BCardTitle,
|
||||||
|
BCardBody,
|
||||||
|
BFormRadio,
|
||||||
|
BButton,
|
||||||
|
BButtonGroup,
|
||||||
|
BCol,
|
||||||
|
BRow,
|
||||||
|
BCardFooter,
|
||||||
|
BBadge,
|
||||||
|
BDropdown,
|
||||||
|
BDropdownItem,
|
||||||
|
FeatherIcon,
|
||||||
|
},
|
||||||
|
directives: {
|
||||||
|
'b-tooltip': VBTooltip,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
colors: {
|
||||||
|
green: 'success',
|
||||||
|
yellow: 'warning',
|
||||||
|
},
|
||||||
|
coinInfo: {},
|
||||||
|
type: 'prices',
|
||||||
|
days: 30,
|
||||||
|
tickers: [],
|
||||||
|
selectedTicker: {
|
||||||
|
converted_last: {},
|
||||||
|
},
|
||||||
|
marketData: {
|
||||||
|
prices: [],
|
||||||
|
volumes: [],
|
||||||
|
},
|
||||||
|
chartOptions: {
|
||||||
|
chart: {
|
||||||
|
toolbar: { show: false },
|
||||||
|
zoom: { enabled: false },
|
||||||
|
type: 'line',
|
||||||
|
dropShadow: {
|
||||||
|
enabled: true,
|
||||||
|
top: 18,
|
||||||
|
left: 2,
|
||||||
|
blur: 5,
|
||||||
|
opacity: 0.2,
|
||||||
|
},
|
||||||
|
offsetX: -10,
|
||||||
|
},
|
||||||
|
stroke: {
|
||||||
|
curve: 'smooth',
|
||||||
|
width: 4,
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
borderColor: '#ebe9f1',
|
||||||
|
padding: {
|
||||||
|
top: -20,
|
||||||
|
bottom: 5,
|
||||||
|
left: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false,
|
||||||
|
},
|
||||||
|
colors: ['#df87f2'],
|
||||||
|
fill: {
|
||||||
|
type: 'gradient',
|
||||||
|
gradient: {
|
||||||
|
shade: 'dark',
|
||||||
|
inverseColors: false,
|
||||||
|
gradientToColors: [$themeColors.primary],
|
||||||
|
shadeIntensity: 1,
|
||||||
|
type: 'horizontal',
|
||||||
|
opacityFrom: 1,
|
||||||
|
opacityTo: 1,
|
||||||
|
stops: [0, 100, 100, 100],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
markers: {
|
||||||
|
size: 0,
|
||||||
|
hover: {
|
||||||
|
size: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xaxis: {
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
yaxis: {
|
||||||
|
tickAmount: 5,
|
||||||
|
labels: {
|
||||||
|
style: {
|
||||||
|
colors: '#b9b9c3',
|
||||||
|
fontSize: '0.857rem',
|
||||||
|
},
|
||||||
|
formatter(val) {
|
||||||
|
if (val > 999999999) {
|
||||||
|
return `${(val / 1000000000).toFixed(1)}b`
|
||||||
|
}
|
||||||
|
if (val > 999999) {
|
||||||
|
return `${(val / 1000000).toFixed(1)}m`
|
||||||
|
}
|
||||||
|
return val > 999 ? `${(val / 1000).toFixed(1)}k` : val.toFixed(2)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
x: { show: false },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
series() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: this.type,
|
||||||
|
data: this.marketData[this.type].map(x => ({ x: x[0], y: x[1] })),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
color() {
|
||||||
|
return this.colorMap(this.selectedTicker.trust_score)
|
||||||
|
},
|
||||||
|
homepage() {
|
||||||
|
if (this.coinInfo.links) {
|
||||||
|
return this.coinInfo.links.homepage[0] || '#'
|
||||||
|
}
|
||||||
|
return '#'
|
||||||
|
},
|
||||||
|
twitter() {
|
||||||
|
if (this.coinInfo.links) {
|
||||||
|
return this.coinInfo.links.twitter_screen_name ? `https://twitter.com/${this.coinInfo.links.twitter_screen_name}` : '#'
|
||||||
|
}
|
||||||
|
return '#'
|
||||||
|
},
|
||||||
|
telegram() {
|
||||||
|
if (this.coinInfo.links) {
|
||||||
|
return this.coinInfo.links.telegram_channel_identifier ? `https://twitter.com/${this.coinInfo.links.telegram_channel_identifier}` : '#'
|
||||||
|
}
|
||||||
|
return '#'
|
||||||
|
},
|
||||||
|
github() {
|
||||||
|
if (this.coinInfo.links) {
|
||||||
|
return this.coinInfo.links.repos_url.github[0] || '#'
|
||||||
|
}
|
||||||
|
return '#'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.$http.getMarketChart(this.days).then(res => {
|
||||||
|
this.marketData = res
|
||||||
|
})
|
||||||
|
this.$http.getCoinInfo().then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.coinInfo = res
|
||||||
|
this.tickers = res.tickers
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
|
this.selectedTicker = this.tickers[0]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
colorMap(v) {
|
||||||
|
return this.colors[v] || 'secondary'
|
||||||
|
},
|
||||||
|
selectChart(v) {
|
||||||
|
this.type = v
|
||||||
|
},
|
||||||
|
selectDays(v) {
|
||||||
|
this.days = v
|
||||||
|
this.$http.getMarketChart(this.days).then(res => {
|
||||||
|
this.marketData = res
|
||||||
|
})
|
||||||
|
},
|
||||||
|
selectPair(v) {
|
||||||
|
this.selectedTicker = v
|
||||||
|
},
|
||||||
|
url(which) {
|
||||||
|
return this.coinInfo[which][0] || '#'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
@ -85,8 +85,8 @@
|
|||||||
import {
|
import {
|
||||||
BCard, BCardHeader, BCardTitle, BCardText, BCardBody, BRow, BCol, BMedia, BMediaAside, BAvatar, BMediaBody, BPopover, BButton,
|
BCard, BCardHeader, BCardTitle, BCardText, BCardBody, BRow, BCol, BMedia, BMediaAside, BAvatar, BMediaBody, BPopover, BButton,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from '../ObjectFieldComponent.vue'
|
||||||
import ArrayFieldComponent from './ArrayFieldComponent.vue'
|
import ArrayFieldComponent from '../ArrayFieldComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
Loading…
Reference in New Issue
Block a user