cosmos-explorer/src/views/WalletDelegations.vue
2021-12-22 15:43:07 +08:00

265 lines
7.4 KiB
Vue

<template>
<div>
<router-link
v-if="delegations.length === 0"
to="/wallet/import"
>
<b-card class="addzone text-center">
<feather-icon icon="PlusIcon" />
Connect Wallet
</b-card>
</router-link>
<b-card
v-for="(items,k) in groupedDelegations"
:key="k"
:title="k"
>
<b-table
:items="items"
stacked="sm"
:fields="fields"
>
<template #cell(validator)="data">
<router-link :to="`/${data.item.validator.chain}/staking/${data.item.validator.validator}`">
<b-avatar
:src="data.item.validator.logo"
size="18"
variant="light-primary"
rounded=""
/>
{{ data.item.validator.moniker }}
</router-link>
</template>
<template #cell(delegator)="data">
<router-link :to="`/${data.item.validator.chain}/account/${data.item.delegator_address}`">
Withdraw
</router-link>
</template>
<template #cell(action)="data">
<!-- size -->
<b-button-group
size="sm"
>
<b-button
v-b-modal.delegate-window
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Delegate'"
variant="outline-primary"
@click="selectValue(data.item)"
>
<feather-icon icon="LogInIcon" />
</b-button>
<b-button
v-b-modal.redelegate-window
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Redelegate'"
variant="outline-primary"
@click="selectValue(data.item)"
>
<feather-icon icon="ShuffleIcon" />
</b-button>
<b-button
v-b-modal.unbond-window
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Unbond'"
variant="outline-primary"
@click="selectValue(data.item)"
>
<feather-icon icon="LogOutIcon" />
</b-button>
</b-button-group>
</template>
</b-table>
</b-card>
<!--- not completed--->
<operation-withdraw-component :address="address" />
<operation-unbond-component
:address="address"
:validator-address.sync="selectedValidator"
/>
<operation-delegate-component
:address="address"
:validator-address.sync="selectedValidator"
/>
<operation-redelegate-component
:address="address"
:validator-address.sync="selectedValidator"
/>
</div>
</template>
<script>
import {
BButton, VBTooltip, BTable, BCard, BButtonGroup, BAvatar,
} from 'bootstrap-vue'
import Ripple from 'vue-ripple-directive'
import {
formatToken, getCachedValidators, getLocalAccounts, getLocalChains, tokenFormatter,
} from '@/libs/utils'
import FeatherIcon from '@/@core/components/feather-icon/FeatherIcon.vue'
import OperationWithdrawComponent from './OperationWithdrawComponent.vue'
import OperationUnbondComponent from './OperationUnbondComponent.vue'
import OperationDelegateComponent from './OperationDelegateComponent.vue'
import OperationRedelegateComponent from './OperationRedelegateComponent.vue'
export default {
components: {
BAvatar,
BButton,
BButtonGroup,
BTable,
BCard,
FeatherIcon,
OperationWithdrawComponent,
OperationDelegateComponent,
OperationRedelegateComponent,
OperationUnbondComponent,
},
directives: {
'b-tooltip': VBTooltip,
Ripple,
},
data() {
return {
fields: [
{
key: 'validator',
sortable: true,
// sortByFormatted: true,
},
{
key: 'delegation',
sortable: true,
// sortByFormatted: true,
},
{
key: 'reward',
sortable: true,
// sortByFormatted: true,
},
{
key: 'delegator',
label: '',
sortable: true,
// sortByFormatted: true,
},
],
address: '',
selectedValidator: '',
accounts: [],
delegations: [],
rewards: {},
}
},
computed: {
formatedDelegations() {
return this.delegations.map(x => ({
validator: {
logo: x.chain.logo,
validator: x.delegation.validator_address,
moniker: this.findMoniker(x.chain.chain_name, x.delegation.validator_address),
chain: x.chain.chain_name,
},
delegator: x.keyname,
delegator_address: x.delegation.delegator_address,
delegation: formatToken(x.balance),
reward: this.findReward(x.delegation.delegator_address, x.delegation.validator_address),
// action: '',
}))
},
groupedDelegations() {
const group = {}
this.delegations.forEach(x => {
const d = {
validator: {
logo: x.chain.logo,
validator: x.delegation.validator_address,
moniker: this.findMoniker(x.chain.chain_name, x.delegation.validator_address),
chain: x.chain.chain_name,
},
delegator: x.keyname,
delegator_address: x.delegation.delegator_address,
delegation: formatToken(x.balance),
reward: this.findReward(x.delegation.delegator_address, x.delegation.validator_address),
// action: '',
}
if (group[x.keyname]) {
group[x.keyname].push(d)
} else {
group[x.keyname] = [d]
}
})
return group
},
},
created() {
this.init()
},
methods: {
selectValue(v) {
this.address = v.delegator_address
this.selectedValidator = v.validator.validator
return v
},
findMoniker(chain, addr) {
const vals = JSON.parse(getCachedValidators(chain))
const val = vals.find(x => x.operator_address === addr)
if (val) {
return val.description.moniker
}
return addr
},
findReward(delegator, validator) {
const reward = this.rewards[delegator]?.rewards.find(x => x.validator_address === validator) || null
if (reward) {
return tokenFormatter(reward.reward)
}
return '-'
},
init() {
this.accounts = getLocalAccounts()
const chains = getLocalChains()
if (this.accounts) {
Object.keys(this.accounts).forEach(acc => {
this.accounts[acc].address.forEach(add => {
const chain = chains[add.chain]
this.$http.getStakingReward(add.addr, chain).then(res => {
this.rewards[add.addr] = res
})
this.$http.getStakingDelegations(add.addr, chain).then(res => {
if (res.delegation_responses && res.delegation_responses.length > 0) {
const delegation = res.delegation_responses.map(x => {
const x2 = x
x2.keyname = acc
x2.chain = chain
return x2
})
this.delegations = this.delegations.concat(delegation)
}
}).catch(() => {})
})
})
}
},
},
}
</script>
<style lang="css">
.addzone {
border: 2px dashed #ced4da;
background: #fff;
border-radius: 6px;
cursor: pointer;
box-shadow: none;
}
.addzone :hover {
border: 2px dashed #7367F0;
}
</style>