| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| <template> |
| <div> |
| <filter-quota-data-by-period-view @fetchData="fetchData"/> |
| |
| <div v-if="dataSource.length > 0"> |
| <export-to-csv-button :action="exportDataToCsv" /> |
| <bar-chart :chart-options="getBalancesChartOptions()" :chart-data="getBalancesChartData()"/> |
| <a-table |
| size="small" |
| :loading="loading" |
| :columns="columns" |
| :dataSource="dataSource" |
| :rowKey="record => record.date" |
| :pagination="false" |
| :scroll="{ y: '55vh' }"> |
| <template #title> |
| {{ $t('label.currency') }}: <b>{{ currency }}</b> |
| </template> |
| <template #date="{ text }"> |
| {{ text }} |
| </template> |
| <template #lastBalanceHour="{ text }"> |
| {{ text }} |
| </template> |
| <template #balance="{ text }"> |
| {{ parseFloat(text).toFixed(2) }} |
| </template> |
| </a-table> |
| </div> |
| </div> |
| </template> |
| |
| <script> |
| import { getAPI } from '@/api' |
| import BarChart from '@/components/view/charts/BarChart.vue' |
| import * as dateUtils from '@/utils/date' |
| import { downloadDataAsCsv } from '@/utils/util.js' |
| import FilterQuotaDataByPeriodView from './FilterQuotaDataByPeriodView.vue' |
| import ExportToCsvButton from '@/components/view/buttons/ExportToCsvButton.vue' |
| import * as chartUtils from '@/utils/chart' |
| |
| export default { |
| name: 'QuotaBalance', |
| components: { |
| FilterQuotaDataByPeriodView, |
| BarChart, |
| ExportToCsvButton |
| }, |
| data () { |
| return { |
| loading: false, |
| currency: '', |
| dataSource: [], |
| startDate: undefined, |
| endDate: undefined |
| } |
| }, |
| computed: { |
| columns () { |
| return [ |
| { |
| title: this.$t('label.date'), |
| dataIndex: 'date', |
| width: 'calc(100% / 3)', |
| slots: { customRender: 'date' }, |
| sorter: (a, b) => a.lastBalance.localeCompare(b.lastBalance), |
| defaultSortOrder: 'descend' |
| }, |
| { |
| title: this.$t('label.quota.last.balance'), |
| dataIndex: 'lastBalanceHour', |
| width: 'calc(100% / 3)', |
| slots: { customRender: 'lastBalanceHour' }, |
| sorter: (a, b) => a.lastBalance.localeCompare(b.lastBalance), |
| defaultSortOrder: 'descend' |
| }, |
| { |
| title: this.$t('label.balance'), |
| dataIndex: 'balance', |
| width: 'calc(100% / 3)', |
| slots: { customRender: 'balance' }, |
| sorter: (a, b) => a.balance - b.balance |
| } |
| ] |
| } |
| }, |
| methods: { |
| async fetchData (startDate, endDate) { |
| if (this.loading) return |
| |
| this.startDate = dateUtils.parseDayJsObject({ value: startDate }) |
| this.endDate = dateUtils.parseDayJsObject({ value: endDate }) |
| this.dataSource = [] |
| this.loading = true |
| |
| try { |
| const data = await this.getQuotaBalance() || {} |
| this.currency = data.currency |
| this.dataSource = this.getLastBalanceOfEachDate(data.balances) |
| } finally { |
| this.loading = false |
| } |
| }, |
| async getQuotaBalance () { |
| const params = { |
| accountid: this.$route.params?.id, |
| startdate: this.startDate, |
| enddate: this.endDate |
| } |
| |
| return await getAPI('quotaBalance', params) |
| .then(json => json.quotabalanceresponse.balance) |
| .catch(error => { error && this.$notification.info({ message: this.$t('message.request.no.data') }) }) |
| }, |
| getLastBalanceOfEachDate (data) { |
| if (!data) return [] |
| |
| return data.reduce((reduced, currentItem) => { |
| const lastBalance = dateUtils.parseDayJsObject({ value: currentItem.date, keepMoment: false }) |
| const balance = currentItem.balance |
| const date = dateUtils.toLocaleDate({ date: lastBalance, dateOnly: true }) |
| const lastBalanceHour = dateUtils.toLocaleDate({ date: lastBalance, hourOnly: true }) |
| const found = reduced.find(item => item.date === date) |
| |
| if (!found) { |
| reduced.push({ lastBalance, balance, date, lastBalanceHour }) |
| } else { |
| if (found.lastBalance < lastBalance) { |
| found.balance = balance |
| found.lastBalance = lastBalance |
| found.date = date |
| found.lastBalanceHour = lastBalanceHour |
| } |
| } |
| return reduced |
| }, []) |
| }, |
| exportDataToCsv () { |
| downloadDataAsCsv({ |
| data: this.dataSource, |
| headers: ['date', 'balance'], |
| keys: ['lastBalance', 'balance'], |
| fileName: `quota-balances-of-user-${this.$route.params.id}-between-${this.startDate}-and-${this.endDate}` |
| }) |
| }, |
| getBalancesChartData () { |
| const datasets = [] |
| |
| datasets.push({ |
| label: this.$t('label.balance'), |
| data: this.dataSource.map(row => row.balance), |
| ...chartUtils.getChartColorObject() |
| }) |
| |
| return { |
| labels: this.dataSource.map(row => row.date), |
| datasets |
| } |
| }, |
| getBalancesChartOptions () { |
| return { |
| scales: { |
| xAxis: { |
| type: 'time', |
| time: { |
| unit: chartUtils.getUnitToTimeCartesianAxis('day', this.dataSource.length), |
| displayFormats: chartUtils.defaultDisplayFormats |
| } |
| } |
| }, |
| plugins: { |
| tooltip: { |
| callbacks: { |
| title: (tooltipItem) => dateUtils.dayjs(tooltipItem[0].label).format(chartUtils.defaultDisplayFormats.day), |
| label: (tooltipItem) => parseFloat(tooltipItem.raw).toFixed(2) |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| </script> |
| |
| <style lang="scss" scoped> |
| @import '@/style/common/common.scss'; |
| </style> |