Skip to content

Commit 7520761

Browse files
committed
feat: add rewards chart filters
- prevent showing `aggregation` filter in `summary` chart to match `rewards chart` - fix aggregation filter for logged-out usrers in `summary chart` See: BEDS-875
1 parent 6777d5c commit 7520761

File tree

9 files changed

+649
-274
lines changed

9 files changed

+649
-274
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<script setup lang="ts">
2+
const {
3+
dateFormat = 'M dd, yy',
4+
label,
5+
} = defineProps<{
6+
dateFormat?: string,
7+
id: string,
8+
label: string,
9+
maxDate: Date,
10+
minDate: Date,
11+
}>()
12+
13+
const modelValue = defineModel<Date>({
14+
required: true,
15+
})
16+
</script>
17+
18+
<template>
19+
<label
20+
:id
21+
class="bc-datepicker__label"
22+
>
23+
<span>{{ label }}</span>
24+
<Datepicker
25+
:id
26+
v-model="modelValue"
27+
:date-format
28+
:min-date
29+
:max-date
30+
/>
31+
</label>
32+
</template>
33+
34+
<style lang="scss">
35+
.bc-datepicker__label {
36+
display: flex;
37+
flex-direction: column;
38+
font-size: 0.8rem;
39+
color: var(--text-color-discreet);
40+
}
41+
42+
div.p-datepicker-input {
43+
max-width: min-content;
44+
}
45+
46+
div.p-datepicker-panel {
47+
background: var(--input-background);
48+
width: 268px;
49+
margin-top: var(--padding-tiny);
50+
padding: var(--padding-small);
51+
border-radius: var(--border-radius);
52+
border: 1px solid var(--input-border-color);
53+
54+
.p-datepicker-header {
55+
padding: var(--padding-small);
56+
padding-bottom: var(--padding);
57+
border-bottom: 1px solid var(--light-grey-7);
58+
59+
.p-datepicker-prev-button,
60+
.p-datepicker-next-button {
61+
height: 30px;
62+
}
63+
64+
.p-datepicker-title {
65+
gap: var(--padding);
66+
67+
.p-datepicker-select-month,
68+
.p-datepicker-select-year {
69+
font-size: 1rem
70+
}
71+
}
72+
}
73+
74+
.p-datepicker-day-view {
75+
margin-top: var(--padding-small);
76+
77+
.p-datepicker-weekday-cell {
78+
padding: var(--padding-tiny);
79+
}
80+
81+
.p-datepicker-day-cell {
82+
padding: var(--padding-tiny);
83+
84+
&.p-datepicker-other-month {
85+
color: var(--text-color-disabled);
86+
87+
&.p-datepicker-today > .p-datepicker-day {
88+
color: var(--white);
89+
}
90+
}
91+
92+
&.p-datepicker-today > .p-datepicker-day {
93+
background-color: var(--grey);
94+
}
95+
96+
.p-datepicker-day {
97+
border-radius: 50%;
98+
width: 30px;
99+
height: 30px;
100+
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
101+
102+
&.p-datepicker-day-selected {
103+
background-color: var(--primary-color);
104+
}
105+
106+
&:not(.p-datepicker-day-selected):not(.p-disabled):hover {
107+
background-color: var(--grey);
108+
}
109+
}
110+
111+
.p-disabled {
112+
color: var(--text-color-disabled);
113+
}
114+
}
115+
}
116+
117+
.p-datepicker-month-view {
118+
margin-top: var(--padding-small);
119+
120+
.p-datepicker-month {
121+
padding: var(--padding-small);
122+
border-radius: var(--border-radius);
123+
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
124+
125+
&.p-datepicker-month-selected {
126+
background-color: var(--primary-color);
127+
}
128+
129+
&:not(.p-datepicker-month-selected):not(.p-disabled):hover {
130+
background-color: var(--grey);
131+
}
132+
}
133+
134+
.p-disabled {
135+
color: var(--text-color-disabled);
136+
}
137+
}
138+
139+
.p-datepicker-year-view {
140+
margin-top: var(--padding-small);
141+
142+
.p-datepicker-year {
143+
padding: var(--padding-small);
144+
border-radius: var(--border-radius);
145+
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
146+
147+
&.p-datepicker-year-selected {
148+
background-color: var(--primary-color);
149+
}
150+
151+
&:not(.p-datepicker-year-selected):not(.p-disabled):hover {
152+
background-color: var(--grey);
153+
}
154+
}
155+
156+
.p-disabled {
157+
color: var(--text-color-disabled);
158+
}
159+
}
160+
}
161+
</style>

frontend/components/dashboard/chart/DashboardChartRewards.vue

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
import {
33
h, render,
44
} from 'vue'
5-
import {
6-
type ElementEvent, use,
7-
} from 'echarts/core'
5+
import { use } from 'echarts/core'
86
import { CanvasRenderer } from 'echarts/renderers'
97
import { BarChart } from 'echarts/charts'
108
import {
@@ -16,27 +14,26 @@ import {
1614
TransformComponent,
1715
} from 'echarts/components'
1816
import VChart from 'vue-echarts'
19-
2017
import type {
2118
BarSeriesOption,
2219
EChartsOption,
2320
EChartsType,
2421
} from 'echarts'
22+
import type { RewardsChartFilter } from '../chart/DashboardChartRewardsFilter.vue'
23+
2524
import {
2625
getChartTextColor,
2726
getChartTooltipBackgroundColor,
2827
getRewardChartColors,
2928
getRewardsChartLineColor,
3029
} from '~/utils/colors'
3130
import type { GetValidatorDashboardRewardsChartResponse } from '~/types/api/validator_dashboard'
32-
import type {
33-
ChartData, ChartSeries,
34-
} from '~/types/api/common'
31+
import type { ChartSeries } from '~/types/api/common'
3532
import { DashboardChartRewardsTooltip } from '#components'
3633
37-
const {
38-
getTimestampFromEpoch,
39-
} = useNetworkStore()
34+
const { filter } = defineProps<{
35+
filter: RewardsChartFilter,
36+
}>()
4037
4138
use([
4239
GridComponent,
@@ -55,26 +52,33 @@ const {
5552
dashboardKey,
5653
} = useDashboardKey()
5754
58-
const data = ref<ChartData<number, string> | undefined>()
59-
60-
const { status } = useAsyncData(
55+
const {
56+
data,
57+
status,
58+
} = useAsyncData(
6159
'validator_dashboard_rewards_chart',
6260
async () => {
6361
if (dashboardKey.value === undefined) {
64-
data.value = undefined
6562
return
6663
}
67-
const res = await fetch<GetValidatorDashboardRewardsChartResponse>(
64+
return await fetch<GetValidatorDashboardRewardsChartResponse>(
6865
'DASHBOARD_VALIDATOR_REWARDS_CHART',
69-
undefined,
66+
{
67+
query: {
68+
...filter,
69+
group_ids: filter.group_ids.join(','),
70+
},
71+
},
7072
{ dashboardKey: dashboardKey.value },
7173
)
72-
data.value = res.data
7374
},
7475
{
7576
immediate: true,
7677
server: false,
77-
watch: [ dashboardKey ],
78+
watch: [
79+
dashboardKey,
80+
filter,
81+
],
7882
},
7983
)
8084
@@ -106,7 +110,7 @@ const {
106110
selectedCurrencyMain,
107111
} = useCurrency()
108112
109-
const categoryCount = computed(() => data.value?.categories?.length ?? 0)
113+
const categoryCount = computed(() => data.value?.data.categories?.length ?? 0)
110114
111115
const isGwei = ref(false)
112116
@@ -153,7 +157,7 @@ const autoFormatAmount = (values: string[], {
153157
return result
154158
}
155159
156-
const clSeries = computed(() => data.value?.series?.filter(series => series.property === 'cl') ?? [])
160+
const clSeries = computed(() => data.value?.data.series?.filter(series => series.property === 'cl') ?? [])
157161
const clSeriesGroupTotal = computed(() => {
158162
let total = Array(categoryCount.value).fill('0')
159163
clSeries.value.forEach((group) => {
@@ -170,7 +174,7 @@ const clSeriesGroupTotal = computed(() => {
170174
})
171175
const clSeriesGroupTotalFormatted = computed(() => autoFormatAmount(clSeriesGroupTotal.value))
172176
173-
const elSeries = computed(() => data.value?.series?.filter(series => series.property === 'el') ?? [])
177+
const elSeries = computed(() => data.value?.data.series?.filter(series => series.property === 'el') ?? [])
174178
const elSeriesGroupTotal = computed(() => {
175179
let total = Array(categoryCount.value).fill('0')
176180
elSeries.value.forEach((group) => {
@@ -230,7 +234,7 @@ type DataZoomEvent = {
230234
start: number,
231235
type: 'datazoom',
232236
}
233-
const dataZoomStart = ref(60)
237+
const dataZoomStart = ref(0)
234238
const dataZoomEnd = ref(100)
235239
// position of tooltip get's lost due to rerendering of `options` (> computed > currency recalculations > latest-state)
236240
const onDatazoom = ({
@@ -246,10 +250,7 @@ const tooltipPosition = ref({
246250
x: 0,
247251
y: 0,
248252
})
249-
const setTooltipPosition = (event: ElementEvent) => {
250-
tooltipPosition.value.x = event.offsetX
251-
tooltipPosition.value.y = event.offsetY
252-
}
253+
253254
const restoreTooltip = () => {
254255
nextTick(() => {
255256
if (!chart.value) return
@@ -318,8 +319,7 @@ const option = computed<EChartsOption>(() => {
318319
},
319320
end: dataZoomEnd.value,
320321
labelFormatter: (_value: number, valueStr: string) => {
321-
const unixTimestamp = getTimestampFromEpoch(Number(valueStr))
322-
return getDateTime(unixTimestamp, { hasTime: false })
322+
return getDateTime(Number(valueStr), { hasTime: false })
323323
},
324324
start: dataZoomStart.value,
325325
type: 'slider',
@@ -353,17 +353,18 @@ const option = computed<EChartsOption>(() => {
353353
borderColor: colors.value.background,
354354
confine: true,
355355
enterable: true,
356+
extraCssText: 'z-index: 100;',
357+
356358
formatter(params) {
357359
if (!Array.isArray(params)) return ''
358360
if (params.length === 0) return ''
359361
360362
const paramsConsensusLayer = params.find(param => param.seriesId === seriesId.cl)
361363
const paramsExecutionLayer = params.find(param => param.seriesId === seriesId.el)
362364
const currentIndex = params[0].dataIndex
363-
const currentTimestamp = getTimestampFromEpoch(Number(params[0].name))
364365
const currentEpoch = {
365366
index: params[0].name,
366-
timestamp: currentTimestamp,
367+
timestamp: Number(params[0].name),
367368
}
368369
const currentGroupTotalCl = clSeriesGroupTotal.value[currentIndex]
369370
const currentGroupTotalEl = elSeriesGroupTotal.value[currentIndex]
@@ -412,20 +413,19 @@ const option = computed<EChartsOption>(() => {
412413
order: 'seriesAsc',
413414
padding: 0,
414415
trigger: 'axis',
415-
triggerOn: 'click',
416+
triggerOn: isTriggeringOnMouseMove.value ? 'mousemove|click' : 'click',
416417
},
417418
xAxis: {
418419
axisLabel: {
419420
fontSize: textSize,
420421
fontWeight: fontWeightMedium,
421-
formatter: (epoch: number) => {
422-
const unixTimestamp = getTimestampFromEpoch(epoch)
423-
const date = getDateTime(unixTimestamp, { hasTime: false })
424-
return `${date}\n${$t('common.epoch')} ${epoch}`
422+
formatter: (timestamp: number) => {
423+
const date = getDateTime(timestamp, { hasTime: false })
424+
return date
425425
},
426426
lineHeight: 20,
427427
},
428-
data: data.value?.categories,
428+
data: data.value?.data.categories,
429429
type: 'category',
430430
},
431431
yAxis: {
@@ -446,6 +446,12 @@ const option = computed<EChartsOption>(() => {
446446
},
447447
}
448448
})
449+
450+
const isTriggeringOnMouseMove = ref(true)
451+
452+
const toggleTriggeringOnMouseMove = () => {
453+
isTriggeringOnMouseMove.value = !isTriggeringOnMouseMove.value
454+
}
449455
</script>
450456

451457
<template>
@@ -459,7 +465,7 @@ const option = computed<EChartsOption>(() => {
459465
:option
460466
autoresize
461467
@datazoom="onDatazoom"
462-
@zr:click="setTooltipPosition"
468+
@zr:mousedown="toggleTriggeringOnMouseMove"
463469
/>
464470
</ClientOnly>
465471
<BcLoadingSpinner
@@ -473,14 +479,14 @@ const option = computed<EChartsOption>(() => {
473479
class="no-data"
474480
alignment="center"
475481
>
476-
{{ $t("dashboard.validator.summary.chart.error") }}
482+
{{ $t("dashboard.validator.rewards.chart.error") }}
477483
</div>
478484
<div
479485
v-if="status === 'success' && !clSeries.length"
480486
class="no-data"
481487
alignment="center"
482488
>
483-
{{ $t("dashboard.validator.summary.chart.no_data") }}
489+
{{ $t("dashboard.validator.rewards.chart.no_data") }}
484490
</div>
485491
</div>
486492
</template>

0 commit comments

Comments
 (0)