Formatted frontend code.
Build and Deploy Web App / build-and-deploy (push) Successful in 21s
Details
Build and Deploy Web App / build-and-deploy (push) Successful in 21s
Details
This commit is contained in:
parent
9cb2d562d8
commit
71a783669f
|
|
@ -37,7 +37,7 @@ watch(balancesIncludeSubcategories, async () => {
|
||||||
if (!category.value) return
|
if (!category.value) return
|
||||||
balances.value = await new TransactionApiClient(getSelectedProfile(route)).getCategoryBalances(
|
balances.value = await new TransactionApiClient(getSelectedProfile(route)).getCategoryBalances(
|
||||||
category.value.id,
|
category.value.id,
|
||||||
balancesIncludeSubcategories.value
|
balancesIncludeSubcategories.value,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -60,7 +60,10 @@ async function loadCategory(id: number) {
|
||||||
parentCategory.value = await api.getCategory(category.value.parentId)
|
parentCategory.value = await api.getCategory(category.value.parentId)
|
||||||
}
|
}
|
||||||
childCategories.value = await api.getChildCategories(category.value.id)
|
childCategories.value = await api.getChildCategories(category.value.id)
|
||||||
balances.value = await api.getCategoryBalances(category.value.id, balancesIncludeSubcategories.value)
|
balances.value = await api.getCategoryBalances(
|
||||||
|
category.value.id,
|
||||||
|
balancesIncludeSubcategories.value,
|
||||||
|
)
|
||||||
await fetchPage(1)
|
await fetchPage(1)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
@ -87,16 +90,32 @@ async function fetchPage(pg: number) {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<AppPage v-if="category" :title="'Category - ' + category.name">
|
<AppPage
|
||||||
|
v-if="category"
|
||||||
|
:title="'Category - ' + category.name"
|
||||||
|
>
|
||||||
<!-- Initial subtext with color & parent (if available). -->
|
<!-- Initial subtext with color & parent (if available). -->
|
||||||
<div>
|
<div>
|
||||||
<span class="category-color-indicator" :style="{ 'background-color': '#' + category.color }"></span>
|
<span
|
||||||
<span v-if="parentCategory" class="text-muted" style="vertical-align: middle">
|
class="category-color-indicator"
|
||||||
|
:style="{ 'background-color': '#' + category.color }"
|
||||||
|
></span>
|
||||||
|
<span
|
||||||
|
v-if="parentCategory"
|
||||||
|
class="text-muted"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
>
|
||||||
A subcategory of
|
A subcategory of
|
||||||
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/categories/${parentCategory.id}`">{{
|
<RouterLink
|
||||||
parentCategory.name }}</RouterLink>.
|
:to="`/profiles/${getSelectedProfile(route)}/categories/${parentCategory.id}`"
|
||||||
|
>{{ parentCategory.name }}</RouterLink
|
||||||
|
>.
|
||||||
</span>
|
</span>
|
||||||
<span v-if="!parentCategory" class="text-muted" style="vertical-align: middle">
|
<span
|
||||||
|
v-if="!parentCategory"
|
||||||
|
class="text-muted"
|
||||||
|
style="vertical-align: middle"
|
||||||
|
>
|
||||||
This is a top-level category.
|
This is a top-level category.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -108,8 +127,12 @@ async function fetchPage(pg: number) {
|
||||||
<div v-if="childCategories.length > 0">
|
<div v-if="childCategories.length > 0">
|
||||||
<h3>Subcategories</h3>
|
<h3>Subcategories</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="child in childCategories" :key="child.id">
|
<li
|
||||||
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/categories/${child.id}`">{{ child.name }}
|
v-for="child in childCategories"
|
||||||
|
:key="child.id"
|
||||||
|
>
|
||||||
|
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/categories/${child.id}`"
|
||||||
|
>{{ child.name }}
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -118,22 +141,36 @@ async function fetchPage(pg: number) {
|
||||||
<!-- Display total balances. -->
|
<!-- Display total balances. -->
|
||||||
<div v-if="balances.length > 0">
|
<div v-if="balances.length > 0">
|
||||||
<h3>Balances</h3>
|
<h3>Balances</h3>
|
||||||
<div v-for="balance in balances" :key="balance.currency.code">
|
<div
|
||||||
|
v-for="balance in balances"
|
||||||
|
:key="balance.currency.code"
|
||||||
|
>
|
||||||
USD:
|
USD:
|
||||||
<AppBadge>Debits:
|
<AppBadge
|
||||||
|
>Debits:
|
||||||
<span class="text-positive">{{ formatMoney(balance.debits, balance.currency) }}</span>
|
<span class="text-positive">{{ formatMoney(balance.debits, balance.currency) }}</span>
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
<AppBadge>Credits:
|
<AppBadge
|
||||||
|
>Credits:
|
||||||
<span class="text-negative">{{ formatMoney(balance.credits, balance.currency) }}</span>
|
<span class="text-negative">{{ formatMoney(balance.credits, balance.currency) }}</span>
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
<AppBadge>Balance:
|
<AppBadge
|
||||||
<span :class="{ 'text-positive': balance.balance > 0, 'text-negative': balance.balance < 0 }">{{
|
>Balance:
|
||||||
formatMoney(balance.balance, balance.currency) }}</span>
|
<span
|
||||||
|
:class="{ 'text-positive': balance.balance > 0, 'text-negative': balance.balance < 0 }"
|
||||||
|
>{{ formatMoney(balance.balance, balance.currency) }}</span
|
||||||
|
>
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
</div>
|
</div>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Include Subcategories" v-if="childCategories.length > 0">
|
<FormControl
|
||||||
<input type="checkbox" v-model="balancesIncludeSubcategories" />
|
label="Include Subcategories"
|
||||||
|
v-if="childCategories.length > 0"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="balancesIncludeSubcategories"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<!--
|
<!--
|
||||||
<FormControl label="After">
|
<FormControl label="After">
|
||||||
|
|
@ -151,9 +188,20 @@ async function fetchPage(pg: number) {
|
||||||
<p class="text-muted font-size-small mt-0">
|
<p class="text-muted font-size-small mt-0">
|
||||||
Below is a list of all transactions recorded with this category, or any subcategory.
|
Below is a list of all transactions recorded with this category, or any subcategory.
|
||||||
</p>
|
</p>
|
||||||
<PaginationControls :page="relatedTransactionsPage" @update="(pr) => fetchPage(pr.page)" class="align-right" />
|
<PaginationControls
|
||||||
<TransactionCard v-for="txn in relatedTransactionsPage.items" :key="txn.id" :tx="txn" />
|
:page="relatedTransactionsPage"
|
||||||
<p v-if="relatedTransactionsPage.totalElements === 0" class="text-muted font-italic">
|
@update="(pr) => fetchPage(pr.page)"
|
||||||
|
class="align-right"
|
||||||
|
/>
|
||||||
|
<TransactionCard
|
||||||
|
v-for="txn in relatedTransactionsPage.items"
|
||||||
|
:key="txn.id"
|
||||||
|
:tx="txn"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
v-if="relatedTransactionsPage.totalElements === 0"
|
||||||
|
class="text-muted font-italic"
|
||||||
|
>
|
||||||
There are no transactions linked to this category.
|
There are no transactions linked to this category.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -233,42 +233,83 @@ function loadAllParamValues(key: string): string[] {
|
||||||
<AppPage title="Transactions">
|
<AppPage title="Transactions">
|
||||||
<AppForm>
|
<AppForm>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Search" hint="Free-form text search against description, tags, vendor, category, account.">
|
<FormControl
|
||||||
<input v-model="searchQuery" type="text" placeholder="Search for transactions..." />
|
label="Search"
|
||||||
|
hint="Free-form text search against description, tags, vendor, category, account."
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
type="text"
|
||||||
|
placeholder="Search for transactions..."
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<div class="vueselect-control">
|
<div class="vueselect-control">
|
||||||
<h5>Tag</h5>
|
<h5>Tag</h5>
|
||||||
<VueSelect v-model="tagFilters" :options="tagOptions" placeholder="Select tags" is-multi />
|
<VueSelect
|
||||||
|
v-model="tagFilters"
|
||||||
|
:options="tagOptions"
|
||||||
|
placeholder="Select tags"
|
||||||
|
is-multi
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="vueselect-control">
|
<div class="vueselect-control">
|
||||||
<h5>Vendor</h5>
|
<h5>Vendor</h5>
|
||||||
<VueSelect v-model="vendorFilters" :options="vendorOptions" placeholder="Select vendors" is-multi />
|
<VueSelect
|
||||||
|
v-model="vendorFilters"
|
||||||
|
:options="vendorOptions"
|
||||||
|
placeholder="Select vendors"
|
||||||
|
is-multi
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="vueselect-control">
|
<div class="vueselect-control">
|
||||||
<h5>Category</h5>
|
<h5>Category</h5>
|
||||||
<VueSelect v-model="categoryFilters" :options="categoryOptions" placeholder="Select categories" is-multi />
|
<VueSelect
|
||||||
|
v-model="categoryFilters"
|
||||||
|
:options="categoryOptions"
|
||||||
|
placeholder="Select categories"
|
||||||
|
is-multi
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="vueselect-control">
|
<div class="vueselect-control">
|
||||||
<h5>Account</h5>
|
<h5>Account</h5>
|
||||||
<VueSelect v-model="accountFilters" :options="accountOptions" placeholder="Select accounts" is-multi />
|
<VueSelect
|
||||||
|
v-model="accountFilters"
|
||||||
|
:options="accountOptions"
|
||||||
|
placeholder="Select accounts"
|
||||||
|
is-multi
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Max Amount">
|
<FormControl label="Max Amount">
|
||||||
<input v-model="maxAmountFilter" type="number" min="0" step="1" />
|
<input
|
||||||
|
v-model="maxAmountFilter"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="1"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl label="Min Amount">
|
<FormControl label="Min Amount">
|
||||||
<input v-model="minAmountFilter" type="number" min="0" step="1" />
|
<input
|
||||||
|
v-model="minAmountFilter"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
step="1"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Sort By">
|
<FormControl label="Sort By">
|
||||||
<select v-model="selectedSort">
|
<select v-model="selectedSort">
|
||||||
<option v-for="sortOpt in SORT_PROPERTIES" :key="sortOpt.property" :value="sortOpt.property">
|
<option
|
||||||
|
v-for="sortOpt in SORT_PROPERTIES"
|
||||||
|
:key="sortOpt.property"
|
||||||
|
:value="sortOpt.property"
|
||||||
|
>
|
||||||
{{ sortOpt.label }}
|
{{ sortOpt.label }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
@ -281,19 +322,42 @@ function loadAllParamValues(key: string): string[] {
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<ButtonBar>
|
<ButtonBar>
|
||||||
<AppButton size="sm" icon="home" @click="goToHome()">Back to Homepage</AppButton>
|
<AppButton
|
||||||
<AppButton size="sm" icon="trash" @click="clearFilters()">Clear Filters</AppButton>
|
size="sm"
|
||||||
<AppButton size="sm" icon="file-export" @click="exportToFile()">Export to CSV</AppButton>
|
icon="home"
|
||||||
|
@click="goToHome()"
|
||||||
|
>Back to Homepage</AppButton
|
||||||
|
>
|
||||||
|
<AppButton
|
||||||
|
size="sm"
|
||||||
|
icon="trash"
|
||||||
|
@click="clearFilters()"
|
||||||
|
>Clear Filters</AppButton
|
||||||
|
>
|
||||||
|
<AppButton
|
||||||
|
size="sm"
|
||||||
|
icon="file-export"
|
||||||
|
@click="exportToFile()"
|
||||||
|
>Export to CSV</AppButton
|
||||||
|
>
|
||||||
</ButtonBar>
|
</ButtonBar>
|
||||||
</AppForm>
|
</AppForm>
|
||||||
|
|
||||||
<PaginationControls :page="page" @update="(pr) => fetchPage(pr.page, pr.size)" class="align-right" />
|
<PaginationControls
|
||||||
|
:page="page"
|
||||||
|
@update="(pr) => fetchPage(pr.page, pr.size)"
|
||||||
|
class="align-right"
|
||||||
|
/>
|
||||||
<AppBadge size="sm">
|
<AppBadge size="sm">
|
||||||
{{ page.totalElements }} search
|
{{ page.totalElements }} search
|
||||||
{{ page.totalElements == 1 ? 'result' : 'results' }}
|
{{ page.totalElements == 1 ? 'result' : 'results' }}
|
||||||
in {{ lastFetchTime }} milliseconds
|
in {{ lastFetchTime }} milliseconds
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
<TransactionCard v-for="txn in page.items" :key="txn.id" :tx="txn" />
|
<TransactionCard
|
||||||
|
v-for="txn in page.items"
|
||||||
|
:key="txn.id"
|
||||||
|
:tx="txn"
|
||||||
|
/>
|
||||||
</AppPage>
|
</AppPage>
|
||||||
</template>
|
</template>
|
||||||
<style lang="css" scoped>
|
<style lang="css" scoped>
|
||||||
|
|
|
||||||
|
|
@ -56,27 +56,47 @@ function exportAccounts() {
|
||||||
<template>
|
<template>
|
||||||
<HomeModule title="Accounts">
|
<HomeModule title="Accounts">
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
<AccountCard v-for="a in accounts" :account="a" :key="a.id" />
|
<AccountCard
|
||||||
|
v-for="a in accounts"
|
||||||
|
:account="a"
|
||||||
|
:key="a.id"
|
||||||
|
/>
|
||||||
<p v-if="accounts.length === 0">
|
<p v-if="accounts.length === 0">
|
||||||
You haven't added any accounts. Add one to start tracking your finances.
|
You haven't added any accounts. Add one to start tracking your finances.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<AppBadge v-for="bal in totalBalances" :key="bal.currency.code">
|
<AppBadge
|
||||||
|
v-for="bal in totalBalances"
|
||||||
|
:key="bal.currency.code"
|
||||||
|
>
|
||||||
{{ bal.currency.code }} Total:
|
{{ bal.currency.code }} Total:
|
||||||
<span class="font-mono">{{ formatMoney(bal.balance, bal.currency) }}</span>
|
<span class="font-mono">{{ formatMoney(bal.balance, bal.currency) }}</span>
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
<AppBadge v-for="debt in totalOwed" :key="debt.currency.code">
|
<AppBadge
|
||||||
|
v-for="debt in totalOwed"
|
||||||
|
:key="debt.currency.code"
|
||||||
|
>
|
||||||
{{ debt.currency.code }} Debt:
|
{{ debt.currency.code }} Debt:
|
||||||
<span class="font-mono" :class="{ 'text-negative': debt.balance > 0 }">{{ formatMoney(debt.balance,
|
<span
|
||||||
debt.currency) }}</span>
|
class="font-mono"
|
||||||
|
:class="{ 'text-negative': debt.balance > 0 }"
|
||||||
|
>{{ formatMoney(debt.balance, debt.currency) }}</span
|
||||||
|
>
|
||||||
</AppBadge>
|
</AppBadge>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:actions>
|
<template v-slot:actions>
|
||||||
<AppButton icon="plus" @click="router.push(`/profiles/${getSelectedProfile(route)}/add-account`)">Add Account
|
<AppButton
|
||||||
|
icon="plus"
|
||||||
|
@click="router.push(`/profiles/${getSelectedProfile(route)}/add-account`)"
|
||||||
|
>Add Account
|
||||||
</AppButton>
|
</AppButton>
|
||||||
<AppButton icon="download" size="sm" @click="exportAccounts()">
|
<AppButton
|
||||||
|
icon="download"
|
||||||
|
size="sm"
|
||||||
|
@click="exportAccounts()"
|
||||||
|
>
|
||||||
Export
|
Export
|
||||||
</AppButton>
|
</AppButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,7 @@ import HomeModule from '@/components/HomeModule.vue'
|
||||||
import { computed, onMounted, ref } from 'vue'
|
import { computed, onMounted, ref } from 'vue'
|
||||||
import 'chartjs-adapter-date-fns'
|
import 'chartjs-adapter-date-fns'
|
||||||
import type { Currency } from '@/api/data'
|
import type { Currency } from '@/api/data'
|
||||||
import {
|
import { AnalyticsApiClient } from '@/api/analytics'
|
||||||
AnalyticsApiClient,
|
|
||||||
} from '@/api/analytics'
|
|
||||||
import type { TimeFrame } from './analytics/util'
|
import type { TimeFrame } from './analytics/util'
|
||||||
import FormGroup from '@/components/common/form/FormGroup.vue'
|
import FormGroup from '@/components/common/form/FormGroup.vue'
|
||||||
import FormControl from '@/components/common/form/FormControl.vue'
|
import FormControl from '@/components/common/form/FormControl.vue'
|
||||||
|
|
@ -60,30 +58,53 @@ onMounted(async () => {
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Chart">
|
<FormControl label="Chart">
|
||||||
<select v-model="selectedChart">
|
<select v-model="selectedChart">
|
||||||
<option v-for="ct in AnalyticsChartTypes" :key="ct.id" :value="ct">
|
<option
|
||||||
|
v-for="ct in AnalyticsChartTypes"
|
||||||
|
:key="ct.id"
|
||||||
|
:value="ct"
|
||||||
|
>
|
||||||
{{ ct.name }}
|
{{ ct.name }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
<BalanceTimeSeriesChart v-if="currency && selectedChart.id === 'account-balances'" title="Account Balances"
|
<BalanceTimeSeriesChart
|
||||||
:currency="currency" :time-frame="timeFrame" :api="analyticsApi" />
|
v-if="currency && selectedChart.id === 'account-balances'"
|
||||||
|
title="Account Balances"
|
||||||
|
:currency="currency"
|
||||||
|
:time-frame="timeFrame"
|
||||||
|
:api="analyticsApi"
|
||||||
|
/>
|
||||||
|
|
||||||
<CategorySpendPieChart v-if="currency && selectedChart.id === 'category-spend'" :currency="currency"
|
<CategorySpendPieChart
|
||||||
:api="analyticsApi" :time-frame="timeFrame" />
|
v-if="currency && selectedChart.id === 'category-spend'"
|
||||||
|
:currency="currency"
|
||||||
|
:api="analyticsApi"
|
||||||
|
:time-frame="timeFrame"
|
||||||
|
/>
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormControl label="Currency">
|
<FormControl label="Currency">
|
||||||
<select v-model="currency" :disabled="availableCurrencies.length < 2">
|
<select
|
||||||
<option v-for="currency in availableCurrencies" :key="currency.code" :value="currency">
|
v-model="currency"
|
||||||
|
:disabled="availableCurrencies.length < 2"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="currency in availableCurrencies"
|
||||||
|
:key="currency.code"
|
||||||
|
:value="currency"
|
||||||
|
>
|
||||||
{{ currency.code }}
|
{{ currency.code }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormControl label="Time Frame">
|
<FormControl label="Time Frame">
|
||||||
<select v-model="timeFrame">
|
<select v-model="timeFrame">
|
||||||
<option :value="{}" selected>
|
<option
|
||||||
|
:value="{}"
|
||||||
|
selected
|
||||||
|
>
|
||||||
All Time
|
All Time
|
||||||
</option>
|
</option>
|
||||||
<option :value="{ start: sub(new Date(), { days: 30 }) }">Last 30 days</option>
|
<option :value="{ start: sub(new Date(), { days: 30 }) }">Last 30 days</option>
|
||||||
|
|
|
||||||
|
|
@ -61,14 +61,14 @@ watch(
|
||||||
() => {
|
() => {
|
||||||
buildChartData()
|
buildChartData()
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
async function buildChartData() {
|
async function buildChartData() {
|
||||||
const balanceAnalytics = await props.api.getBalanceTimeSeries(
|
const balanceAnalytics = await props.api.getBalanceTimeSeries(
|
||||||
props.currency.code,
|
props.currency.code,
|
||||||
props.timeFrame.start ? props.timeFrame.start.getTime() : null,
|
props.timeFrame.start ? props.timeFrame.start.getTime() : null,
|
||||||
props.timeFrame.end ? props.timeFrame.end.getTime() : null
|
props.timeFrame.end ? props.timeFrame.end.getTime() : null,
|
||||||
)
|
)
|
||||||
|
|
||||||
const datasets: ChartDataset<'line'>[] = []
|
const datasets: ChartDataset<'line'>[] = []
|
||||||
|
|
@ -101,6 +101,10 @@ async function buildChartData() {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Line v-if="chartData && chartOptions" :data="chartData" :options="chartOptions" />
|
<Line
|
||||||
|
v-if="chartData && chartOptions"
|
||||||
|
:data="chartData"
|
||||||
|
:options="chartOptions"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ watch(
|
||||||
() => {
|
() => {
|
||||||
buildChartData()
|
buildChartData()
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
async function buildChartData() {
|
async function buildChartData() {
|
||||||
|
|
@ -41,7 +41,7 @@ async function buildChartData() {
|
||||||
props.currency.code,
|
props.currency.code,
|
||||||
props.timeFrame.start ? props.timeFrame.start.getTime() : null,
|
props.timeFrame.start ? props.timeFrame.start.getTime() : null,
|
||||||
props.timeFrame.end ? props.timeFrame.end.getTime() : null,
|
props.timeFrame.end ? props.timeFrame.end.getTime() : null,
|
||||||
null
|
null,
|
||||||
)
|
)
|
||||||
if (categorySpendData.length === 0) {
|
if (categorySpendData.length === 0) {
|
||||||
chartData.value = undefined
|
chartData.value = undefined
|
||||||
|
|
@ -69,11 +69,13 @@ async function buildChartData() {
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Pie id="pie" v-if="chartData && chartOptions" :data="chartData" :options="chartOptions" />
|
<Pie
|
||||||
<p v-if="!chartData">
|
id="pie"
|
||||||
No category spending data is available for this selection of filters.
|
v-if="chartData && chartOptions"
|
||||||
</p>
|
:data="chartData"
|
||||||
|
:options="chartOptions"
|
||||||
|
/>
|
||||||
|
<p v-if="!chartData">No category spending data is available for this selection of filters.</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue