QuotaUsageTab.vue refactoring

This commit is contained in:
Fabricio Duarte 2026-06-22 09:18:54 -03:00
parent 19e60ab037
commit 6cda0d4647
3 changed files with 188 additions and 190 deletions

View File

@ -30,6 +30,7 @@ export default {
title: 'label.quota.summary',
icon: 'bars-outlined',
permission: ['quotaSummary'],
customParamHandler: (params, query) => { return { ...params, ignoreproject: true } },
tabs: [
{
name: 'consumption',

View File

@ -81,7 +81,7 @@
<script>
import { dayjs, toLocaleDate } from '@/utils/date'
import { dayjs, parseDayJsObject, toLocaleDate } from '@/utils/date'
import { reactive, toRaw } from 'vue'
export default {
@ -137,8 +137,8 @@ export default {
},
getPeriodToString () {
return this.$t('label.quota.filter.period', {
startDate: toLocaleDate({ date: this.startDate }),
endDate: toLocaleDate({ date: this.endDate })
startDate: toLocaleDate({ date: parseDayJsObject({ value: this.startDate, keepMoment: true, format: false }) }),
endDate: toLocaleDate({ date: parseDayJsObject({ value: this.endDate, keepMoment: true, format: false }) })
})
},
handleSubmit () {

View File

@ -26,8 +26,7 @@
<div>
<a-radio-group
v-model:value="graphType"
buttonStyle="solid"
@change="handlePeriodChange">
buttonStyle="solid">
<a-radio-button value="bar_chart">
{{ $t('label.total') }}
</a-radio-button>
@ -45,12 +44,12 @@
<strong> {{ $t('label.quota.usage.types.summary') }} </strong>
</div>
<export-to-csv-button :action="exportDataToCsv" />
<bar-chart v-if="graphType === 'bar_chart'" :chart-options="getUsageTypeChartOptions()" :chart-data="getUsageTypeBarChartData()"/>
<bar-chart v-if="graphType === 'bar_chart'" :chart-options="getBarChartOptions()" :chart-data="getUsageTypeBarChartData()"/>
<resource-stats-line-chart
v-else
:chart-labels="usageLineChartLabels"
:chart-data="getGraphType(this.usageTypeChartData)"
:yAxisIncrementValue="getYaxisIncrement(this.getGraphType(this.yAxisMax.usageType))"
:chart-data="getEntryForCurrentGraphType(this.usageLineChartData)"
:yAxisIncrementValue="getYAxisIncrement(getEntryForCurrentGraphType(this.YAxisMax.usageTypes))"
:yAxisMeasurementUnit="''"
/>
<a-table
@ -108,12 +107,12 @@
</a-select-option>
</a-select>
<export-to-csv-button v-if="dataSourceResource.length > 0" :action="exportResourcesToCsv" :label="`label.export.resources.csv`" />
<bar-chart v-if="dataSourceResource.length > 0 && graphType === 'bar_chart'" :chart-options="getUsageTypeChartOptions()" :chart-data="getResourceByUsageTypeBarChartData()"/>
<bar-chart v-if="dataSourceResource.length > 0 && graphType === 'bar_chart'" :chart-options="getBarChartOptions()" :chart-data="getResourceBarChartData()"/>
<resource-stats-line-chart
v-else-if="dataSourceResource.length > 0 && graphType !== 'bar_chart'"
:chart-labels="resourceLineChartLabels"
:chart-data="getGraphType(this.resourceByTypeChartData)"
:yAxisIncrementValue="getYaxisIncrement(this.getGraphType(this.yAxisMax.resourceByType))"
:chart-data="getEntryForCurrentGraphType(this.resourceLineChartData)"
:yAxisIncrementValue="getYAxisIncrement(getEntryForCurrentGraphType(this.YAxisMax.resources))"
:yAxisMeasurementUnit="''"
/>
<a-table
@ -167,24 +166,24 @@
{{ $t(item.name) }}
</a-select-option>
</a-select>
<export-to-csv-button v-if="dataSourceResourceDetails.length > 0" :action="exportResourceDetailsToCsv" :label="`label.export.details.csv`" />
<bar-chart v-if="dataSourceResourceDetails.length > 0 && graphType === 'bar_chart'" :chart-options="getUsageTypeChartOptions()" :chart-data="getResourceDetailsBarChartData()"/>
<export-to-csv-button v-if="dataSourceTariffs.length > 0" :action="exportResourceDetailsToCsv" :label="`label.export.details.csv`" />
<bar-chart v-if="dataSourceTariffs.length > 0 && graphType === 'bar_chart'" :chart-options="getBarChartOptions()" :chart-data="getTariffsBarChartData()"/>
<resource-stats-line-chart
v-else-if="dataSourceResourceDetails.length > 0 && graphType !== 'bar_chart'"
v-else-if="dataSourceTariffs.length > 0 && graphType !== 'bar_chart'"
:chart-labels="tariffLineChartLabels"
:chart-data="getGraphType(this.usageResourceDetailsChartData)"
:yAxisIncrementValue="getYaxisIncrement(this.getGraphType(this.yAxisMax.resourceDetails))"
:chart-data="getEntryForCurrentGraphType(this.tariffLineChartData)"
:yAxisIncrementValue="getYAxisIncrement(getEntryForCurrentGraphType(this.YAxisMax.tariffs))"
:yAxisMeasurementUnit="''"
/>
<a-table
size="small"
:loading="loadingResourceDetails"
:loading="loadingTariffs"
:columns="resourceDetailsColumns"
:dataSource="dataSourceResourceDetails"
:rowKey="record => record.tariffname + '-' + record.startDate"
:dataSource="dataSourceTariffs"
:rowKey="record => record.tariffname + '-' + record.startdate"
:pagination="false"
:scroll="{ y: '55vh' }">
<template #title v-if="dataSourceResourceDetails.length > 0">
<template #title v-if="dataSourceTariffs.length > 0">
<div>{{ $t('label.currency') }}: <b>{{ currency }}</b></div>
</template>
<template #tariffName="props">
@ -195,10 +194,10 @@
{{ props.text }}
</span>
</template>
<template #endDate="{ text }">
{{ $toLocaleDate(text) }}
<template #enddate="{ text }">
{{ text }}
</template>
<template #startDate="{ text }">
<template #startdate="{ text }">
{{ $toLocaleDate(text) }}
</template>
<template #quota="{ text }">
@ -242,18 +241,18 @@ export default {
loadingResources: false,
dataSourceResource: [],
selectedResource: '',
loadingResourceDetails: false,
dataSourceResourceDetails: [],
loadingTariffs: false,
dataSourceTariffs: [],
startDate: undefined,
endDate: undefined,
graphType: 'bar_chart',
usageLineChartLabels: [],
resourceLineChartLabels: [],
tariffLineChartLabels: [],
usageTypeChartData: {},
resourceByTypeChartData: {},
usageResourceDetailsChartData: {},
yAxisMax: {}
usageLineChartData: {},
resourceLineChartData: {},
tariffLineChartData: {},
YAxisMax: {}
}
},
watch: {
@ -261,15 +260,15 @@ export default {
if (newGraphType === 'bar_chart') {
return
}
this.fetchDataForUsageTypeLineGraph()
this.prepareDataForUsageTypeLineGraph()
if (!this.selectedType) {
return
}
this.fetchDataForResourceByTypeLineGraph()
this.prepareDataForResourceLineGraph()
if (!this.selectedResource) {
return
}
this.fetchDataForResourceDetailsLineGraph()
this.prepareDataForTariffLineGraph()
}
},
computed: {
@ -328,16 +327,16 @@ export default {
},
{
title: this.$t('label.start.date'),
dataIndex: 'startDate',
dataIndex: 'startdate',
slots: { customRender: 'startDate' },
sorter: (a, b) => a.startDate.localeCompare(b.startDate),
sorter: (a, b) => a.startdate.localeCompare(b.startdate),
defaultSortOrder: 'descend'
},
{
title: this.$t('label.end.date'),
dataIndex: 'endDate',
dataIndex: 'enddate',
slots: { customRender: 'endDate' },
sorter: (a, b) => a.endDate.localeCompare(b.endDate)
sorter: (a, b) => a.enddate.localeCompare(b.enddate)
},
{
title: this.$t('label.quota.consumed'),
@ -357,7 +356,7 @@ export default {
this.loading = true
this.dataSource = []
this.dataSourceResource = []
this.dataSourceResourceDetails = []
this.dataSourceTariffs = []
this.selectedResource = ''
this.selectedType = ''
@ -372,10 +371,14 @@ export default {
}
this.dataSource = quotaStatement.quotausage.filter(row => row.quota !== 0)
if (this.dataSource.length === 0) {
this.$notification.info({ message: this.$t('message.request.no.data') })
}
this.currency = quotaStatement.currency
this.totalQuota = quotaStatement.totalquota
if (this.graphType !== 'bar_chart') {
this.fetchDataForUsageTypeLineGraph()
this.prepareDataForUsageTypeLineGraph()
}
} finally {
this.loading = false
@ -389,47 +392,54 @@ export default {
try {
const quotaStatement = await this.getQuotaStatement({
startDate: this.startDate,
endDate: this.endDate,
showResources: true,
startdate: this.startDate,
enddate: this.endDate,
showresources: true,
type: this.selectedType.split('-')[0]
})
this.dataSourceResource = quotaStatement.quotausage[0].resources
this.dataSourceResource = this.dataSourceResource.filter(row => row.quotaconsumed !== 0)
this.dataSourceResource = quotaStatement.quotausage[0].resources.filter(row => row.quotaconsumed !== 0)
if (this.dataSourceResource.length === 0) {
this.$notification.info({ message: this.$t('message.request.no.data') })
}
if (this.graphType !== 'bar_chart') {
this.fetchDataForResourceByTypeLineGraph()
this.prepareDataForResourceLineGraph()
}
} finally {
this.loadingResources = false
}
},
async fetchResourceDetailsData () {
if (this.selectedResource === '' || this.loadingResourceDetails) return
async fetchTariffData () {
if (this.selectedResource === '' || this.loadingTariffs) return
this.dataSourceResourceDetails = []
this.loadingResourceDetails = true
this.dataSourceTariffs = []
this.loadingTariffs = true
try {
this.dataSourceResourceDetails = await getAPI('quotaResourceStatement', {
startDate: this.startDate,
endDate: this.endDate, // TODO: remover
usageType: this.selectedType.split('-')[0],
const quotaResourceStatement = await getAPI('quotaResourceStatement', {
startdate: this.startDate,
enddate: this.endDate,
usagetype: this.selectedType.split('-')[0],
id: this.selectedResource,
accountId: this.$route.params?.id
accountid: this.$route.params?.id,
ignoreproject: true
}).then(json => json.quotaresourcestatementresponse?.quotaresourcestatement?.items || [])
.catch(error => { error && this.$notification.info({ message: this.$t('message.request.no.data') }) })
this.dataSourceResourceDetails = this.dataSourceResourceDetails.map(detail => ({
...detail,
startDate: dateUtils.parseDayJsObject({ value: detail.startdate }),
endDate: dateUtils.parseDayJsObject({ value: detail.enddate })
this.dataSourceTariffs = quotaResourceStatement.map(quotaUsage => ({
...quotaUsage,
startdate: dateUtils.parseDayJsObject({ value: quotaUsage.startdate, keepMoment: false }),
enddate: dateUtils.parseDayJsObject({ value: quotaUsage.enddate, keepMoment: false })
})).filter(row => row.quotaconsumed !== 0)
if (this.dataSourceTariffs.length === 0) {
this.$notification.info({ message: this.$t('message.request.no.data') })
}
if (this.graphType !== 'bar_chart') {
this.fetchDataForResourceDetailsLineGraph()
this.prepareDataForTariffLineGraph()
}
} finally {
this.loadingResourceDetails = false
this.loadingTariffs = false
}
},
async getQuotaStatement (apiParams) {
@ -441,13 +451,8 @@ export default {
return await getAPI('quotaStatement', params)
.then(json => json.quotastatementresponse.statement || {})
.catch(error => {
if (error) {
this.$notification.info({ message: this.$t('message.request.no.data') })
}
})
},
getUsageTypeChartOptions () {
getBarChartOptions () {
return { responsive: true }
},
getUsageTypeBarChartData () {
@ -459,10 +464,9 @@ export default {
...this.getColor(row)
})
}
return { labels: [this.$t('label.quota.type.name')], datasets }
},
getResourceByUsageTypeBarChartData () {
getResourceBarChartData () {
const datasets = []
for (const row of this.dataSourceResource) {
datasets.push({
@ -471,85 +475,89 @@ export default {
...this.getColor(row)
})
}
return { labels: [this.$t('label.resource')], datasets }
},
getResourceDetailsBarChartData () {
const tariffs = {}
for (const row of this.dataSourceResourceDetails) {
if (tariffs[row.tariffname] === undefined) {
tariffs[row.tariffname] = row.quotaconsumed
} else {
tariffs[row.tariffname] += row.quotaconsumed
}
}
getTariffsBarChartData () {
const aggregatedTariffs = this.aggregateTariffQuotas()
const datasets = []
for (const key in tariffs) {
for (const key in aggregatedTariffs) {
datasets.push({
label: key,
data: [tariffs[key]],
data: [aggregatedTariffs[key]],
...this.getColor({ tariffname: key })
})
}
return { labels: [this.$t('label.quota.tariff')], datasets }
},
setUsageTypeChartData () {
aggregateTariffQuotas () {
const tariffs = {}
for (const row of this.dataSourceTariffs) {
const currentValue = tariffs[row.tariffname] ?? 0
tariffs[row.tariffname] = currentValue + row.quotaconsumed
}
return tariffs
},
setUsageTypeLineChartData () {
this.usageLineChartLabels = this.getLineChartLabelsForData(this.dataSource)
this.usageTypeChartData = this.getChartData(this.dataSource, this.usageLineChartLabels)
this.usageLineChartData = this.prepareLineChartData(this.dataSource, this.usageLineChartLabels)
},
setResourceByTypeChartData () {
setResourceLineChartData () {
this.resourceLineChartLabels = this.getLineChartLabelsForData(this.dataSourceResource)
this.resourceByTypeChartData = this.getChartData(this.dataSourceResource, this.resourceLineChartLabels)
this.resourceLineChartData = this.prepareLineChartData(this.dataSourceResource, this.resourceLineChartLabels)
},
setResourceDetailsChartData () {
const transformedData = {}
setTariffLineChartData () {
this.dataSourceTariffs.sort((a, b) => new Date(a.enddate) - new Date(b.enddate))
const usageGroupedByTariffName = this.groupUsageByTariffName()
this.dataSourceResourceDetails.sort((a, b) => new Date(a.enddate) - new Date(b.enddate))
this.dataSourceResourceDetails.forEach((obj) => {
if (!(obj.tariffname in transformedData)) {
transformedData[obj.tariffname] = { tariffname: obj.tariffname, history: [] }
const transformedData = Object.values(usageGroupedByTariffName)
this.tariffLineChartLabels = this.getLineChartLabelsForData(transformedData)
this.tariffLineChartData = this.prepareLineChartData(transformedData, this.tariffLineChartLabels)
},
groupUsageByTariffName () {
const groupedData = {}
this.dataSourceTariffs.forEach((obj) => {
if (!(obj.tariffname in groupedData)) {
groupedData[obj.tariffname] = { tariffname: obj.tariffname, history: [] }
}
transformedData[obj.tariffname].history.push(obj)
groupedData[obj.tariffname].history.push(obj)
})
const filteredDataSource = Object.values(transformedData)
this.tariffLineChartLabels = this.getLineChartLabelsForData(filteredDataSource)
this.usageResourceDetailsChartData = this.getChartData(filteredDataSource, this.tariffLineChartLabels)
return groupedData
},
getAdjustedDate (date) {
getLineChartLabelForDate (date) {
return this.$toLocalDate(date)
},
getLineChartLabelsForData (data) {
const lineChartLabels = [this.getAdjustedDate(this.startDate)]
const lineChartLabels = [this.getLineChartLabelForDate(this.startDate)]
for (const row of data) {
let lastIsZero = true
let isPreviousZero = true
for (let i = 0; i < row.history.length; i++) {
const item = row.history[i]
if (item.quotaconsumed === 0) {
if (lastIsZero) {
continue
}
lastIsZero = true
const isCurrentZero = item.quotaconsumed === 0
if (isCurrentZero && isPreviousZero) {
continue
}
if (lastIsZero) {
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getAdjustedDate(item.startdate))
if (isPreviousZero) {
// Last was zero, but we are not. Push our startdate to have an accurate curve
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getLineChartLabelForDate(item.startdate))
}
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getAdjustedDate(item.enddate))
lastIsZero = false
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getLineChartLabelForDate(item.enddate))
isPreviousZero = isCurrentZero
}
}
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getAdjustedDate(this.endDate))
this.pushDateToLabelsIfNotPresent(lineChartLabels, this.getLineChartLabelForDate(this.endDate))
lineChartLabels.sort((a, b) => new Date(a) - new Date(b))
return lineChartLabels
},
pushDateToLabelsIfNotPresent (lineChartLabels, date) {
const hasDate = lineChartLabels.some(d => {
const diff = Math.abs(new Date(date) - new Date(d).getTime())
return diff < 5 * 1000
return diff < 5 * 1000 // Do not push the label if there is already one within 5 minutes
})
if (!hasDate) {
lineChartLabels.push(date)
@ -557,104 +565,99 @@ export default {
}
return false
},
setYAxisMax () {
this.yAxisMax.usageType = {}
this.yAxisMax.usageType.incremental = Math.round(Math.max(...this.dataSource.map(obj => obj.quotaconsumed)) * 1.2)
const max = []
for (const row of this.dataSource) {
max.push(Math.max(...Object.values(row.history.map(h => h.quotaconsumed))))
}
this.yAxisMax.usageType.history = Math.max(...max)
calculatePaddedMax (values) {
return Math.ceil(Math.max(...values) * 1.2)
},
setYAxisInitialMaxResourceByType () {
this.yAxisMax.resourceByType = {}
this.yAxisMax.resourceByType.incremental = Math.max(...this.dataSourceResource.map(obj => obj.quotaconsumed))
const max = []
for (const row of this.dataSourceResource) {
max.push(Math.max(...Object.values(row.history.map(h => h.quotaconsumed))))
}
this.yAxisMax.resourceByType.history = Math.round(Math.max(...max) * 1.2)
getChartDataMaxValues (chartData) {
return Object.values(chartData).map(item => Math.max(...item.data.map(obj => obj.stat)))
},
setYAxisInitialMaxResourceDetails () {
this.yAxisMax.resourceDetails = {}
const historyMax = []
const incrementalMax = []
for (const row in this.usageResourceDetailsChartData.history) {
historyMax.push(Math.max(...this.usageResourceDetailsChartData.history[row].data.map(obj => obj.stat)))
setYAxisMaxForUsageTypes () {
this.YAxisMax.usageTypes = {
incremental: this.calculatePaddedMax(this.getChartDataMaxValues(this.usageLineChartData.incremental)),
history: this.calculatePaddedMax(this.getChartDataMaxValues(this.usageLineChartData.history))
}
for (const row in this.usageResourceDetailsChartData.incremental) {
incrementalMax.push(Math.max(...this.usageResourceDetailsChartData.incremental[row].data.map(obj => obj.stat)))
}
this.yAxisMax.resourceDetails.history = (Math.max(...historyMax))
this.yAxisMax.resourceDetails.incremental = (Math.max(...incrementalMax))
},
getGraphType (data) {
setYAxisMaxForResources () {
this.YAxisMax.resources = {
incremental: this.calculatePaddedMax(this.getChartDataMaxValues(this.resourceLineChartData.incremental)),
history: this.calculatePaddedMax(this.getChartDataMaxValues(this.resourceLineChartData.history))
}
},
setYAxisMaxForTariffs () {
this.YAxisMax.tariffs = {
incremental: this.calculatePaddedMax(this.getChartDataMaxValues(this.tariffLineChartData.incremental)),
history: this.calculatePaddedMax(this.getChartDataMaxValues(this.tariffLineChartData.history))
}
},
getEntryForCurrentGraphType (data) {
if (this.graphType === 'line_chart') {
return data.history
}
return data.incremental
},
fetchDataForUsageTypeLineGraph () {
this.setUsageTypeChartData()
this.setYAxisMax()
prepareDataForUsageTypeLineGraph () {
this.setUsageTypeLineChartData()
this.setYAxisMaxForUsageTypes()
},
fetchDataForResourceByTypeLineGraph () {
this.setResourceByTypeChartData()
this.setYAxisInitialMaxResourceByType()
prepareDataForResourceLineGraph () {
this.setResourceLineChartData()
this.setYAxisMaxForResources()
},
fetchDataForResourceDetailsLineGraph () {
this.setResourceDetailsChartData()
this.setYAxisInitialMaxResourceDetails()
prepareDataForTariffLineGraph () {
this.setTariffLineChartData()
this.setYAxisMaxForTariffs()
},
getChartData (data, lineChartLabels) {
const chartData = {
history: [],
incremental: []
}
prepareLineChartData (data, lineChartLabels) {
const chartData = { history: [], incremental: [] }
for (const row of data) {
const name = this.$t(this.getName(row))
const historyData = { label: name, data: [], fill: false, ...this.getColor(row) }
const incrementalData = { label: name, data: [], fill: false, ...this.getColor(row) }
const datasetName = this.$t(this.getName(row))
const color = this.getColor(row)
let i = 0
const historyDataset = { label: datasetName, data: [], fill: false, ...color }
const incrementalDataset = { label: datasetName, data: [], fill: false, ...color }
let historyIndex = 0
let accumulatedQuota = 0
for (const label of lineChartLabels) {
let labelQuota = 0
while (true) {
if (i >= row.history.length) {
break
}
const item = row.history[i]
if (this.getAdjustedDate(item.enddate) > label) {
break
}
labelQuota += item.quotaconsumed
i++
}
accumulatedQuota += labelQuota
historyData.data.push({ stat: labelQuota })
incrementalData.data.push({ stat: accumulatedQuota })
const periodQuota = this.calculateQuotaForPeriod(row.history, label, historyIndex)
historyIndex = periodQuota.nextIndex
accumulatedQuota += periodQuota.value
historyDataset.data.push({ stat: periodQuota.value })
incrementalDataset.data.push({ stat: accumulatedQuota })
}
chartData.history.push(historyData)
chartData.incremental.push(incrementalData)
chartData.history.push(historyDataset)
chartData.incremental.push(incrementalDataset)
}
return chartData
},
calculateQuotaForPeriod (historyItems, label, startIndex) {
let quota = 0
let currentIndex = startIndex
while (currentIndex < historyItems.length) {
const item = historyItems[currentIndex]
if (this.getLineChartLabelForDate(item.enddate) > label) {
break
}
quota += item.quotaconsumed
currentIndex++
}
return { value: quota, nextIndex: currentIndex }
},
getColor (row) {
const quotaType = getQuotaTypeByName(row.name)
if (quotaType) {
return getChartColorObject(quotaType.chartColor)
}
console.log(row)
return getChartColorObject(this.textToDeterministicColor(this.getName(row)))
},
textToDeterministicColor (text) {
console.log(text)
let hash = 0
for (let i = text.length - 1; i >= 0; i--) {
@ -662,7 +665,6 @@ export default {
hash = hash & hash
}
// Use multiple parts of the hash for better color variance
const hash1 = Math.abs(hash)
const hash2 = Math.abs(hash * 73)
const hash3 = Math.abs(hash * 97)
@ -676,11 +678,12 @@ export default {
},
getName (row) {
if (row.name) {
// Translate the usage type's name
return this.$t(row.name)
}
return row.displayname || row.tariffname
},
getYaxisIncrement (max) {
getYAxisIncrement (max) {
if (max < 1) {
return 1
}
@ -702,11 +705,7 @@ export default {
},
exportResourceDetailsToCsv () {
exportUtils.exportDataToCsv({
data: this.dataSourceResourceDetails.map(row => ({
...row,
startdate: dateUtils.parseDayJsObject({ value: row.startdate, keepMoment: false }),
enddate: dateUtils.parseDayJsObject({ value: row.enddate, keepMoment: false })
})),
data: this.dataSourceTariffs,
keys: ['tariffid', 'tariffname', 'startdate', 'enddate', 'quotaconsumed'],
fileName: `detailed-quota-usage-of-resource-${this.selectedResource}-of-type-${this.selectedType}-of-account-${this.$route.params.id}-between-${this.startDate}-and-${this.endDate}`
})
@ -721,16 +720,14 @@ export default {
async handleSelectedTypeChange (value) {
this.selectedType = value
this.selectedResource = ''
this.dataSourceResourceDetails = []
this.dataSourceTariffs = []
document.getElementById('resource-by-type').scrollIntoView({ behavior: 'smooth' })
await this.fetchResourceData()
},
async handleSelectedResourceChange (value) {
if (!value) return
this.selectedResource = value
document.getElementById('details-by-resource').scrollIntoView({ behavior: 'smooth' })
await this.fetchResourceDetailsData()
await this.fetchTariffData()
}
}
}