Skip to content

Commit de572a6

Browse files
committed
feat(gov): Add VotingPower bar
1 parent 6937c82 commit de572a6

3 files changed

Lines changed: 231 additions & 22 deletions

File tree

components/modules/proposal/ProposalOverview.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Tooltip from "@/components/ui/Tooltip.vue"
88
/** Shared & Local Components */
99
import ProposalTimeline from "./ProposalTimeline.vue"
1010
import VotesAllocation from "./VotesAllocation.vue"
11+
import VotingPower from "./VotingPower.vue"
1112
import VotesTable from "./VotesTable.vue"
1213
1314
/** Services */
@@ -228,6 +229,8 @@ const handleViewRawVotes = () => {
228229

229230
<VotesAllocation v-if="proposal.status !== 'removed'" :proposal />
230231

232+
<VotingPower v-if="!['inactive', 'removed'].includes(proposal.status)" :proposal />
233+
231234
<Flex direction="column" gap="16">
232235
<Text size="12" weight="600" color="secondary">Details</Text>
233236

components/modules/proposal/VotesAllocation.vue

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,28 @@ const expand = ref(["inactive", "active"].includes(props.proposal.status))
2626
<template>
2727
<Flex direction="column" gap="10" :class="$style.wrapper">
2828
<Flex @click="expand = !expand" align="center" justify="between" class="clickable">
29-
<Text size="12" weight="600" color="secondary">Allocation of votes</Text>
29+
<Tooltip position="start" :disabled="!['applied', 'rejected'].includes(proposal.status)">
30+
<Flex align="center" gap="6">
31+
<Text size="12" weight="600" color="secondary">Allocation of votes</Text>
32+
<Icon
33+
v-if="['applied', 'rejected'].includes(proposal.status)"
34+
:name="
35+
(proposal.no_with_veto / proposal.votes_count > Number(proposal.veto_quorum) && 'warning') ||
36+
(proposal.yes / proposal.votes_count > Number(proposal.threshold) && 'check-circle')
37+
"
38+
size="12"
39+
color="secondary"
40+
/>
41+
</Flex>
42+
43+
<template v-if="proposal.no_with_veto / proposal.votes_count > Number(proposal.veto_quorum)" #content>
44+
The No With Veto vote threshold is met - {{ Number(proposal.veto_quorum) * 100 }}%
45+
</template>
46+
<template v-else-if="proposal.yes / proposal.votes_count > Number(proposal.threshold)" #content>
47+
The Yes vote threshold is met - {{ Number(proposal.threshold) * 100 }}%
48+
</template>
49+
</Tooltip>
50+
3051
<Icon name="chevron" size="12" color="secondary" :style="{ transform: `rotate(${expand ? '180deg' : '0deg'})` }" />
3152
</Flex>
3253

@@ -87,7 +108,7 @@ const expand = ref(["inactive", "active"].includes(props.proposal.status))
87108
</Flex>
88109

89110
<Flex v-if="expand" direction="column" gap="16">
90-
<Flex direction="column" gap="12">
111+
<Flex direction="column" gap="16">
91112
<Flex v-for="vote in votes" align="center" justify="between">
92113
<Flex align="center" gap="6">
93114
<div :class="[$style.dot, $style[vote]]" />
@@ -98,29 +119,13 @@ const expand = ref(["inactive", "active"].includes(props.proposal.status))
98119
</Flex>
99120

100121
<Text size="12" weight="600" :color="proposal[vote] ? 'secondary' : 'tertiary'">
101-
<Text v-if="Number(proposal[`${vote}_voting_power`])" color="tertiary">
102-
{{ comma(proposal[`${vote}_voting_power`] / 1_000_000) }} TIA
103-
</Text>
104-
{{ ((proposal[vote] * 100) / proposal.votes_count).toFixed(0) }}%
122+
<template v-if="(proposal[vote] * 100) / proposal.votes_count < 1">
123+
<Text color="tertiary">< 1%</Text>
124+
</template>
125+
<template v-else> {{ ((proposal[vote] * 100) / proposal.votes_count).toFixed(0) }}% </template>
105126
</Text>
106127
</Flex>
107128
</Flex>
108-
109-
<Flex v-if="proposal.yes / proposal.votes_count > Number(proposal.threshold)" align="center" gap="4">
110-
<Icon name="check-circle" size="12" color="tertiary" />
111-
<Text size="12" weight="500" color="tertiary">
112-
The <Text color="secondary" weight="600">Yes</Text> vote threshold of
113-
<Text color="secondary">{{ Number(proposal.threshold) * 100 }}%</Text> is met
114-
</Text>
115-
</Flex>
116-
117-
<Flex v-if="proposal.no_with_veto / proposal.votes_count > Number(proposal.veto_quorum)" align="center" gap="4">
118-
<Icon name="check-circle" size="12" color="tertiary" />
119-
<Text size="12" weight="500" color="tertiary">
120-
The <Text color="secondary" weight="600">No With Veto</Text> vote threshold of
121-
<Text color="secondary">{{ Number(proposal.veto_quorum) * 100 }}%</Text> is met
122-
</Text>
123-
</Flex>
124129
</Flex>
125130
</Flex>
126131
</template>
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
<script setup>
2+
/** UI */
3+
import Tooltip from "@/components/ui/Tooltip.vue"
4+
5+
/** Services */
6+
import { comma } from "@/services/utils"
7+
8+
/** Store */
9+
import { useAppStore } from "@/store/app"
10+
import { useEnumStore } from "@/store/enums"
11+
const appStore = useAppStore()
12+
const enumStore = useEnumStore()
13+
14+
const votes = computed(() => enumStore.enums.voteOption)
15+
16+
const props = defineProps({
17+
proposal: {
18+
type: Object,
19+
default: {},
20+
},
21+
})
22+
23+
const expand = ref(["active"].includes(props.proposal.status))
24+
</script>
25+
26+
<template>
27+
<Flex direction="column" gap="10" :class="$style.wrapper">
28+
<Flex @click="expand = !expand" align="center" justify="between" class="clickable">
29+
<Tooltip position="start" :disabled="!proposal.status === 'applied'">
30+
<Flex align="center" gap="6">
31+
<Text size="12" weight="600" color="secondary">Voting power</Text>
32+
<Icon v-if="proposal.status === 'applied'" name="check-circle" size="12" color="secondary" />
33+
</Flex>
34+
35+
<template #content> The quorum is reached - {{ Number(proposal.quorum) * 100 }}% </template>
36+
</Tooltip>
37+
38+
<Icon name="chevron" size="12" color="secondary" :style="{ transform: `rotate(${expand ? '180deg' : '0deg'})` }" />
39+
</Flex>
40+
41+
<Flex align="center" gap="4" :class="$style.voting_wrapper">
42+
<div :style="{ left: `${Number(proposal.quorum) * 100}%` }" :class="$style.threshold" />
43+
44+
<Tooltip
45+
v-if="proposal.yes"
46+
wide
47+
:trigger-width="`${Math.max(5, (Number(proposal.yes_voting_power) * 100) / (proposal.voting_power * 2))}%`"
48+
>
49+
<div
50+
:style="{
51+
background: 'var(--brand)',
52+
}"
53+
:class="$style.voting_bar"
54+
/>
55+
<template #content>
56+
Yes:
57+
<Text color="primary">
58+
{{ comma(Number(proposal.yes_voting_power) / 1_000_000) }}
59+
</Text>
60+
TIA
61+
</template>
62+
</Tooltip>
63+
<Tooltip
64+
v-if="proposal.no"
65+
wide
66+
:trigger-width="`${Math.max(5, (Number(proposal.no_voting_power) * 100) / (proposal.voting_power * 2))}%`"
67+
>
68+
<div
69+
:style="{
70+
background: 'var(--red)',
71+
}"
72+
:class="$style.voting_bar"
73+
/>
74+
<template #content>
75+
No: <Text color="primary">{{ comma(Number(proposal.no_voting_power) / 1_000_000) }}</Text> TIA
76+
</template>
77+
</Tooltip>
78+
<Tooltip
79+
v-if="proposal.no_with_veto"
80+
wide
81+
:trigger-width="`${Math.max(5, (Number(proposal.no_with_veto_voting_power) * 100) / (proposal.voting_power * 2))}%`"
82+
>
83+
<div
84+
:style="{
85+
background: 'var(--red)',
86+
}"
87+
:class="$style.voting_bar"
88+
/>
89+
<template #content>
90+
No with veto: <Text color="primary">{{ comma(Number(proposal.no_with_veto_voting_power) / 1_000_000) }}</Text> TIA
91+
</template>
92+
</Tooltip>
93+
<Tooltip
94+
v-if="proposal.abstain"
95+
wide
96+
:trigger-width="`${Math.max(5, (Number(proposal.abstain_voting_power) * 100) / (proposal.voting_power * 2))}%`"
97+
>
98+
<div
99+
:style="{
100+
background: 'var(--op-40)',
101+
}"
102+
:class="$style.voting_bar"
103+
/>
104+
<template #content>
105+
Abstain: <Text color="primary">{{ comma(Number(proposal.abstain_voting_power / 1_000_000)) }}</Text> TIA
106+
</template>
107+
</Tooltip>
108+
</Flex>
109+
110+
<Flex v-if="expand" direction="column" gap="16">
111+
<Flex v-for="vote in votes" align="center" justify="between">
112+
<Flex align="center" gap="6">
113+
<div :class="[$style.dot, $style[vote]]" />
114+
<Text size="12" weight="600" color="secondary" style="text-transform: capitalize">{{ vote.replaceAll("_", " ") }}</Text>
115+
<Text v-if="Number(proposal[`${vote}_voting_power`])" size="12" weight="600" color="tertiary">
116+
{{ comma(proposal[`${vote}_voting_power`] / 1_000_000) }} TIA
117+
</Text>
118+
</Flex>
119+
120+
<Text size="12" weight="600" :color="proposal[vote] ? 'secondary' : 'tertiary'">
121+
<template v-if="(Number(proposal[`${vote}_voting_power`]) * 100) / (Number(proposal.voting_power) * 2) < 1">
122+
<Text color="tertiary">< 1%</Text>
123+
</template>
124+
<template v-else>
125+
{{ ((Number(proposal[`${vote}_voting_power`]) * 100) / (Number(proposal.voting_power) * 2)).toFixed(0) }}%
126+
</template>
127+
</Text>
128+
</Flex>
129+
130+
<Flex align="center" justify="between">
131+
<Flex align="center" gap="6">
132+
<div :class="$style.dot" />
133+
<Text size="12" weight="600" color="secondary" style="text-transform: capitalize"> Summary </Text>
134+
</Flex>
135+
136+
<Text size="12" weight="600" color="secondary"> {{ comma(proposal.voting_power / 1_000_000) }} TIA </Text>
137+
</Flex>
138+
</Flex>
139+
</Flex>
140+
</template>
141+
142+
<style module>
143+
.wrapper {
144+
}
145+
146+
.voting_wrapper {
147+
position: relative;
148+
width: 100%;
149+
150+
border-radius: 50px;
151+
background: var(--op-8);
152+
153+
padding: 4px;
154+
}
155+
156+
.threshold {
157+
position: absolute;
158+
top: 0;
159+
160+
width: 4px;
161+
height: 12px;
162+
163+
border-radius: 50px;
164+
background: #fff;
165+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
166+
z-index: 1;
167+
168+
transform: translateX(-50%);
169+
}
170+
171+
.voting_bar {
172+
width: 100%;
173+
height: 4px;
174+
175+
border-radius: 50px;
176+
}
177+
178+
.dot {
179+
width: 6px;
180+
height: 6px;
181+
182+
border-radius: 50%;
183+
background: var(--txt-primary);
184+
185+
&.yes {
186+
background: var(--brand);
187+
}
188+
189+
&.no {
190+
background: var(--red);
191+
}
192+
193+
&.no_with_veto {
194+
background: var(--red);
195+
}
196+
197+
&.abstain {
198+
background: var(--txt-tertiary);
199+
}
200+
}
201+
</style>

0 commit comments

Comments
 (0)