mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-17 16:24:25 +08:00
Upgrade to vue3 (#16)
* upgrade to vue 3.x and framework7 8.x * change calendar plugin to vue-datepicker * disable export button when user does not hava any transaction * implement new pin code input * append thousands separator in amount in exchange rates page
This commit is contained in:
@@ -9,96 +9,93 @@
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
|
||||
<f7-card class="skeleton-text" v-if="loading">
|
||||
<f7-card-header>
|
||||
<f7-accordion-toggle class="full-line">
|
||||
<small class="card-header-content">
|
||||
<span>Account Category</span>
|
||||
</small>
|
||||
<f7-icon class="card-chevron-icon float-right" f7="chevron_up"></f7-icon>
|
||||
</f7-accordion-toggle>
|
||||
</f7-card-header>
|
||||
<f7-block class="combination-list-wrapper margin-vertical skeleton-text"
|
||||
:key="blockIdx" v-for="blockIdx in [ 1, 2, 3 ]" v-if="loading">
|
||||
<f7-accordion-item>
|
||||
<f7-block-title>
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers media-list
|
||||
class="combination-list-header combination-list-opened">
|
||||
<f7-list-item>
|
||||
<template #title>
|
||||
<span>Account Category</span>
|
||||
<f7-icon class="combination-list-chevron-icon" f7="chevron_up"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-toggle>
|
||||
</f7-block-title>
|
||||
<f7-accordion-content style="height: auto">
|
||||
<f7-list strong inset dividers accordion-list class="combination-list-content">
|
||||
<f7-list-item checkbox class="disabled" title="Account Name"
|
||||
:key="itemIdx" v-for="itemIdx in (blockIdx === 1 ? [ 1 ] : [ 1, 2 ])">
|
||||
<template #media>
|
||||
<f7-icon f7="app_fill"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-accordion-item>
|
||||
</f7-block>
|
||||
|
||||
<f7-card-content class="no-safe-areas" :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item checkbox class="disabled" title="Account Name">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
<f7-block class="combination-list-wrapper margin-vertical"
|
||||
:key="accountCategory.id"
|
||||
v-for="accountCategory in allAccountCategories"
|
||||
v-else-if="!loading">
|
||||
<f7-accordion-item :opened="collapseStates[accountCategory.id].opened"
|
||||
v-show="hasShownAccount(accountCategory)"
|
||||
@accordion:open="collapseStates[accountCategory.id].opened = true"
|
||||
@accordion:close="collapseStates[accountCategory.id].opened = false">
|
||||
<f7-block-title>
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers media-list
|
||||
class="combination-list-header"
|
||||
:class="collapseStates[accountCategory.id].opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||
<f7-list-item>
|
||||
<template #title>
|
||||
<span>{{ $t(accountCategory.name) }}</span>
|
||||
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[accountCategory.id].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-toggle>
|
||||
</f7-block-title>
|
||||
<f7-accordion-content :style="{ height: collapseStates[accountCategory.id].opened ? 'auto' : '' }">
|
||||
<f7-list strong inset dividers accordion-list class="combination-list-content"
|
||||
v-if="categorizedAccounts[accountCategory.id]">
|
||||
<f7-list-item checkbox
|
||||
:title="account.name"
|
||||
:value="account.id"
|
||||
:checked="isAccountOrSubAccountsAllChecked(account, filterAccountIds)"
|
||||
:indeterminate="isAccountOrSubAccountsHasButNotAllChecked(account, filterAccountIds)"
|
||||
:key="account.id"
|
||||
v-for="account in categorizedAccounts[accountCategory.id].accounts"
|
||||
v-show="!account.hidden"
|
||||
@change="selectAccountOrSubAccounts">
|
||||
<template #media>
|
||||
<ItemIcon icon-type="account" :icon-id="account.icon" :color="account.color"></ItemIcon>
|
||||
</template>
|
||||
|
||||
<f7-card class="skeleton-text" v-if="loading">
|
||||
<f7-card-header>
|
||||
<f7-accordion-toggle class="full-line">
|
||||
<small class="card-header-content">
|
||||
<span>Account Category 2</span>
|
||||
</small>
|
||||
<f7-icon class="card-chevron-icon float-right" f7="chevron_up"></f7-icon>
|
||||
</f7-accordion-toggle>
|
||||
</f7-card-header>
|
||||
|
||||
<f7-card-content class="no-safe-areas" :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item checkbox class="disabled" title="Account Name">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Account Name 2">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
|
||||
<f7-block class="no-padding no-margin" v-if="!loading">
|
||||
<f7-card v-for="accountCategory in allAccountCategories" :key="accountCategory.id" v-show="hasShownAccount(accountCategory)">
|
||||
<f7-accordion-item :opened="collapseStates[accountCategory.id].opened"
|
||||
@accordion:open="collapseStates[accountCategory.id].opened = true"
|
||||
@accordion:close="collapseStates[accountCategory.id].opened = false">
|
||||
<f7-card-header>
|
||||
<f7-accordion-toggle class="full-line">
|
||||
<small class="card-header-content">
|
||||
<span>{{ $t(accountCategory.name) }}</span>
|
||||
</small>
|
||||
<f7-icon class="card-chevron-icon float-right" :f7="collapseStates[accountCategory.id].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</f7-accordion-toggle>
|
||||
</f7-card-header>
|
||||
<f7-card-content class="no-safe-areas" :padding="false" accordion-list>
|
||||
<f7-accordion-content :style="{ height: collapseStates[accountCategory.id].opened ? 'auto' : '' }">
|
||||
<f7-list v-if="categorizedAccounts[accountCategory.id]">
|
||||
<f7-list-item checkbox v-for="account in categorizedAccounts[accountCategory.id].accounts"
|
||||
v-show="!account.hidden"
|
||||
:key="account.id"
|
||||
:title="account.name"
|
||||
:value="account.id"
|
||||
:checked="account | accountOrSubAccountsAllChecked(filterAccountIds)"
|
||||
:indeterminate="account | accountOrSubAccountsHasButNotAllChecked(filterAccountIds)"
|
||||
@change="selectAccountOrSubAccounts">
|
||||
<f7-icon slot="media"
|
||||
:icon="account.icon | accountIcon"
|
||||
:style="account.color | accountIconStyle('var(--default-icon-color)')">
|
||||
</f7-icon>
|
||||
|
||||
<ul slot="root" v-if="account.type === $constants.account.allAccountTypes.MultiSubAccounts" class="padding-left">
|
||||
<f7-list-item checkbox v-for="subAccount in account.subAccounts"
|
||||
v-show="!subAccount.hidden"
|
||||
:key="subAccount.id"
|
||||
:title="subAccount.name"
|
||||
:value="subAccount.id"
|
||||
:checked="subAccount | accountChecked(filterAccountIds) "
|
||||
@change="selectAccount">
|
||||
<f7-icon slot="media"
|
||||
:icon="subAccount.icon | accountIcon"
|
||||
:style="subAccount.color | accountIconStyle('var(--default-icon-color)')">
|
||||
</f7-icon>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-card-content>
|
||||
</f7-accordion-item>
|
||||
</f7-card>
|
||||
<template #root>
|
||||
<ul v-if="account.type === $constants.account.allAccountTypes.MultiSubAccounts" class="padding-left">
|
||||
<f7-list-item checkbox
|
||||
:title="subAccount.name"
|
||||
:value="subAccount.id"
|
||||
:checked="isAccountChecked(subAccount, filterAccountIds)"
|
||||
:key="subAccount.id"
|
||||
v-for="subAccount in account.subAccounts"
|
||||
v-show="!subAccount.hidden"
|
||||
@change="selectAccount">
|
||||
<template #media>
|
||||
<ItemIcon icon-type="account" :icon-id="subAccount.icon" :color="subAccount.color"></ItemIcon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-accordion-item>
|
||||
</f7-block>
|
||||
|
||||
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||
@@ -116,6 +113,10 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'f7route',
|
||||
'f7router'
|
||||
],
|
||||
data: function () {
|
||||
const self = this;
|
||||
|
||||
@@ -152,7 +153,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
const self = this;
|
||||
const query = self.$f7route.query;
|
||||
const query = self.f7route.query;
|
||||
|
||||
self.modifyDefault = !!query.modifyDefault;
|
||||
|
||||
@@ -188,11 +189,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn() {
|
||||
this.$routeBackOnError('loadingError');
|
||||
this.$routeBackOnError(this.f7router, 'loadingError');
|
||||
},
|
||||
save() {
|
||||
const self = this;
|
||||
const router = self.$f7router;
|
||||
const router = self.f7router;
|
||||
|
||||
const filteredAccountIds = {};
|
||||
|
||||
@@ -286,6 +287,39 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
isAccountChecked(account, filterAccountIds) {
|
||||
return !filterAccountIds[account.id];
|
||||
},
|
||||
isAccountOrSubAccountsAllChecked(account, filterAccountIds) {
|
||||
if (!account.subAccounts) {
|
||||
return !filterAccountIds[account.id];
|
||||
}
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
if (filterAccountIds[subAccount.id]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
isAccountOrSubAccountsHasButNotAllChecked(account, filterAccountIds) {
|
||||
if (!account.subAccounts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
if (!filterAccountIds[subAccount.id]) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return checkedCount > 0 && checkedCount < account.subAccounts.length;
|
||||
},
|
||||
hasShownAccount(accountCategory) {
|
||||
if (!this.categorizedAccounts[accountCategory.id] ||
|
||||
!this.categorizedAccounts[accountCategory.id].accounts ||
|
||||
@@ -320,41 +354,6 @@ export default {
|
||||
|
||||
return collapseStates;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
accountChecked(account, filterAccountIds) {
|
||||
return !filterAccountIds[account.id];
|
||||
},
|
||||
accountOrSubAccountsAllChecked(account, filterAccountIds) {
|
||||
if (!account.subAccounts) {
|
||||
return !filterAccountIds[account.id];
|
||||
}
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
if (filterAccountIds[subAccount.id]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
accountOrSubAccountsHasButNotAllChecked(account, filterAccountIds) {
|
||||
if (!account.subAccounts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < account.subAccounts.length; i++) {
|
||||
const subAccount = account.subAccounts[i];
|
||||
if (!filterAccountIds[subAccount.id]) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return checkedCount > 0 && checkedCount < account.subAccounts.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -9,98 +9,101 @@
|
||||
</f7-nav-right>
|
||||
</f7-navbar>
|
||||
|
||||
<f7-card class="skeleton-text" v-if="loading">
|
||||
<f7-card-header>
|
||||
<f7-accordion-toggle class="full-line">
|
||||
<small class="card-header-content">
|
||||
<span>Transaction Category</span>
|
||||
</small>
|
||||
<f7-icon class="card-chevron-icon float-right" f7="chevron_up"></f7-icon>
|
||||
</f7-accordion-toggle>
|
||||
</f7-card-header>
|
||||
<f7-card-content class="no-safe-areas" :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item checkbox class="disabled" title="Category Name">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
<ul slot="root" class="padding-left">
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
<f7-block class="combination-list-wrapper margin-vertical skeleton-text"
|
||||
:key="blockIdx" v-for="blockIdx in [ 1, 2 ]" v-if="loading">
|
||||
<f7-accordion-item>
|
||||
<f7-block-title>
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers media-list
|
||||
class="combination-list-header combination-list-opened">
|
||||
<f7-list-item>
|
||||
<template #title>
|
||||
<span>Transaction Category</span>
|
||||
<f7-icon class="combination-list-chevron-icon" f7="chevron_up"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name 2">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name 3">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Category Name 2">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
<ul slot="root" class="padding-left">
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name 2">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name 3">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
</f7-list>
|
||||
</f7-accordion-toggle>
|
||||
</f7-block-title>
|
||||
<f7-accordion-content style="height: auto">
|
||||
<f7-list strong inset dividers accordion-list class="combination-list-content">
|
||||
<f7-list-item checkbox class="disabled" title="Category Name"
|
||||
:key="itemIdx" v-for="itemIdx in [ 1, 2 ]">
|
||||
<template #media>
|
||||
<f7-icon f7="app_fill"></f7-icon>
|
||||
</template>
|
||||
<template #root>
|
||||
<ul class="padding-left">
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name"
|
||||
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
|
||||
<template #media>
|
||||
<f7-icon f7="app_fill"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-accordion-item>
|
||||
</f7-block>
|
||||
|
||||
<f7-block class="no-padding no-margin" v-if="!loading">
|
||||
<f7-card v-for="(categories, categoryType) in allTransactionCategories" :key="categoryType">
|
||||
<f7-accordion-item :opened="collapseStates[categoryType].opened"
|
||||
@accordion:open="collapseStates[categoryType].opened = true"
|
||||
@accordion:close="collapseStates[categoryType].opened = false">
|
||||
<f7-card-header>
|
||||
<f7-accordion-toggle class="full-line">
|
||||
<small class="card-header-content">
|
||||
<span>{{ categoryType | categoryTypeName($constants.category.allCategoryTypes) | localized }}</span>
|
||||
</small>
|
||||
<f7-icon class="card-chevron-icon float-right" :f7="collapseStates[categoryType].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</f7-accordion-toggle>
|
||||
</f7-card-header>
|
||||
<f7-card-content class="no-safe-areas" :padding="false" accordion-list>
|
||||
<f7-accordion-content :style="{ height: collapseStates[categoryType].opened ? 'auto' : '' }">
|
||||
<f7-list>
|
||||
<f7-list-item checkbox v-for="category in categories"
|
||||
v-show="!category.hidden"
|
||||
:key="category.id"
|
||||
:title="category.name"
|
||||
:value="category.id"
|
||||
:checked="category | subCategoriesAllChecked(filterCategoryIds)"
|
||||
:indeterminate="category | subCategoriesHasButNotAllChecked(filterCategoryIds)"
|
||||
@change="selectSubCategories">
|
||||
<f7-icon slot="media"
|
||||
:icon="category.icon | categoryIcon"
|
||||
:style="category.color | categoryIconStyle('var(--default-icon-color)')">
|
||||
</f7-icon>
|
||||
<f7-block class="combination-list-wrapper margin-vertical"
|
||||
:key="categoryType"
|
||||
v-for="(categories, categoryType) in allTransactionCategories"
|
||||
v-else-if="!loading">
|
||||
<f7-accordion-item :opened="collapseStates[categoryType].opened"
|
||||
@accordion:open="collapseStates[categoryType].opened = true"
|
||||
@accordion:close="collapseStates[categoryType].opened = false">
|
||||
<f7-block-title>
|
||||
<f7-accordion-toggle>
|
||||
<f7-list strong inset dividers media-list
|
||||
class="combination-list-header"
|
||||
:class="collapseStates[categoryType].opened ? 'combination-list-opened' : 'combination-list-closed'">
|
||||
<f7-list-item>
|
||||
<template #title>
|
||||
<span>{{ getCategoryTypeName(categoryType) }}</span>
|
||||
<f7-icon class="combination-list-chevron-icon" :f7="collapseStates[categoryType].opened ? 'chevron_up' : 'chevron_down'"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-toggle>
|
||||
</f7-block-title>
|
||||
<f7-accordion-content :style="{ height: collapseStates[categoryType].opened ? 'auto' : '' }">
|
||||
<f7-list strong inset dividers accordion-list class="combination-list-content">
|
||||
<f7-list-item checkbox
|
||||
:title="category.name"
|
||||
:value="category.id"
|
||||
:checked="isSubCategoriesAllChecked(category, filterCategoryIds)"
|
||||
:indeterminate="isSubCategoriesHasButNotAllChecked(category, filterCategoryIds)"
|
||||
:key="category.id"
|
||||
v-for="category in categories"
|
||||
v-show="!category.hidden"
|
||||
@change="selectSubCategories">
|
||||
<template #media>
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
</template>
|
||||
|
||||
<ul slot="root" v-if="category.subCategories.length" class="padding-left">
|
||||
<f7-list-item checkbox v-for="subCategory in category.subCategories"
|
||||
v-show="!subCategory.hidden"
|
||||
:key="subCategory.id"
|
||||
:title="subCategory.name"
|
||||
:value="subCategory.id"
|
||||
:checked="subCategory | categoryChecked(filterCategoryIds) "
|
||||
@change="selectCategory">
|
||||
<f7-icon slot="media"
|
||||
:icon="subCategory.icon | categoryIcon"
|
||||
:style="subCategory.color | categoryIconStyle('var(--default-icon-color)')">
|
||||
</f7-icon>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-card-content>
|
||||
</f7-accordion-item>
|
||||
</f7-card>
|
||||
<template #root>
|
||||
<ul v-if="category.subCategories.length" class="padding-left">
|
||||
<f7-list-item checkbox
|
||||
:title="subCategory.name"
|
||||
:value="subCategory.id"
|
||||
:checked="isCategoryChecked(subCategory, filterCategoryIds)"
|
||||
:key="subCategory.id"
|
||||
v-for="subCategory in category.subCategories"
|
||||
v-show="!subCategory.hidden"
|
||||
@change="selectCategory">
|
||||
<template #media>
|
||||
<ItemIcon icon-type="category" :icon-id="subCategory.icon" :color="subCategory.color"></ItemIcon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</ul>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-accordion-content>
|
||||
</f7-accordion-item>
|
||||
</f7-block>
|
||||
|
||||
<f7-actions close-by-outside-click close-on-escape :opened="showMoreActionSheet" @actions:closed="showMoreActionSheet = false">
|
||||
@@ -118,6 +121,10 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'f7route',
|
||||
'f7router'
|
||||
],
|
||||
data: function () {
|
||||
const self = this;
|
||||
|
||||
@@ -151,7 +158,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
const self = this;
|
||||
const query = self.$f7route.query;
|
||||
const query = self.f7route.query;
|
||||
|
||||
self.modifyDefault = !!query.modifyDefault;
|
||||
|
||||
@@ -187,11 +194,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onPageAfterIn() {
|
||||
this.$routeBackOnError('loadingError');
|
||||
this.$routeBackOnError(this.f7router, 'loadingError');
|
||||
},
|
||||
save() {
|
||||
const self = this;
|
||||
const router = self.$f7router;
|
||||
const router = self.f7router;
|
||||
|
||||
const filteredCategoryIds = {};
|
||||
|
||||
@@ -277,6 +284,43 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
getCategoryTypeName(categoryType) {
|
||||
switch (categoryType) {
|
||||
case this.$constants.category.allCategoryTypes.Income.toString():
|
||||
return this.$t('Income Categories');
|
||||
case this.$constants.category.allCategoryTypes.Expense.toString():
|
||||
return this.$t('Expense Categories');
|
||||
case this.$constants.category.allCategoryTypes.Transfer.toString():
|
||||
return this.$t('Transfer Categories');
|
||||
default:
|
||||
return this.$t('Transaction Categories');
|
||||
}
|
||||
},
|
||||
isCategoryChecked(category, filterCategoryIds) {
|
||||
return !filterCategoryIds[category.id];
|
||||
},
|
||||
isSubCategoriesAllChecked(category, filterCategoryIds) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
const subCategory = category.subCategories[i];
|
||||
if (filterCategoryIds[subCategory.id]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
isSubCategoriesHasButNotAllChecked(category, filterCategoryIds) {
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
const subCategory = category.subCategories[i];
|
||||
if (!filterCategoryIds[subCategory.id]) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return checkedCount > 0 && checkedCount < category.subCategories.length;
|
||||
},
|
||||
getCollapseStates() {
|
||||
const collapseStates = {};
|
||||
|
||||
@@ -294,45 +338,6 @@ export default {
|
||||
|
||||
return collapseStates;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
categoryTypeName(categoryType, allCategoryTypes) {
|
||||
switch (categoryType) {
|
||||
case allCategoryTypes.Income.toString():
|
||||
return 'Income Categories';
|
||||
case allCategoryTypes.Expense.toString():
|
||||
return 'Expense Categories';
|
||||
case allCategoryTypes.Transfer.toString():
|
||||
return 'Transfer Categories';
|
||||
default:
|
||||
return 'Transaction Categories';
|
||||
}
|
||||
},
|
||||
categoryChecked(category, filterCategoryIds) {
|
||||
return !filterCategoryIds[category.id];
|
||||
},
|
||||
subCategoriesAllChecked(category, filterCategoryIds) {
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
const subCategory = category.subCategories[i];
|
||||
if (filterCategoryIds[subCategory.id]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
subCategoriesHasButNotAllChecked(category, filterCategoryIds) {
|
||||
let checkedCount = 0;
|
||||
|
||||
for (let i = 0; i < category.subCategories.length; i++) {
|
||||
const subCategory = category.subCategories[i];
|
||||
if (!filterCategoryIds[subCategory.id]) {
|
||||
checkedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return checkedCount > 0 && checkedCount < category.subCategories.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -2,54 +2,50 @@
|
||||
<f7-page>
|
||||
<f7-navbar :title="$t('Statistics Settings')" :back-link="$t('Back')"></f7-navbar>
|
||||
|
||||
<f7-card>
|
||||
<f7-card-content class="no-safe-areas" :padding="false">
|
||||
<f7-list>
|
||||
<f7-list-item
|
||||
:title="$t('Default Chart Type')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', searchbar: true, searchbarPlaceholder: $t('Default Chart Type'), searchbarDisableText: $t('Cancel'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }">
|
||||
<select v-model="defaultChartType">
|
||||
<option :value="$constants.statistics.allChartTypes.Pie">{{ $t('Pie Chart') }}</option>
|
||||
<option :value="$constants.statistics.allChartTypes.Bar">{{ $t('Bar Chart') }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
<f7-list strong inset dividers class="margin-top">
|
||||
<f7-list-item
|
||||
:title="$t('Default Chart Type')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
<select v-model="defaultChartType">
|
||||
<option :value="$constants.statistics.allChartTypes.Pie">{{ $t('Pie Chart') }}</option>
|
||||
<option :value="$constants.statistics.allChartTypes.Bar">{{ $t('Bar Chart') }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
:title="$t('Default Chart Data Type')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', searchbar: true, searchbarPlaceholder: $t('Default Chart Data Type'), searchbarDisableText: $t('Cancel'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }">
|
||||
<select v-model="defaultChartDataType">
|
||||
<option v-for="chartDataType in allChartDataTypes"
|
||||
:key="chartDataType.type"
|
||||
:value="chartDataType.type">{{ $t(chartDataType.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
<f7-list-item
|
||||
:title="$t('Default Chart Data Type')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Chart Data Type'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
<select v-model="defaultChartDataType">
|
||||
<option :value="chartDataType.type"
|
||||
:key="chartDataType.type"
|
||||
v-for="chartDataType in allChartDataTypes">{{ $t(chartDataType.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
:title="$t('Default Date Range')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', searchbar: true, searchbarPlaceholder: $t('Default Date Range'), searchbarDisableText: $t('Cancel'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }">
|
||||
<select v-model="defaultDateRange">
|
||||
<option v-for="dateRange in allDateRanges"
|
||||
:key="dateRange.type"
|
||||
:value="dateRange.type">{{ $t(dateRange.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
<f7-list-item
|
||||
:title="$t('Default Date Range')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Date Range'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
<select v-model="defaultDateRange">
|
||||
<option :value="dateRange.type"
|
||||
:key="dateRange.type"
|
||||
v-for="dateRange in allDateRanges">{{ $t(dateRange.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Default Account Filter')" link="/statistic/filter/account?modifyDefault=1"></f7-list-item>
|
||||
<f7-list-item :title="$t('Default Account Filter')" link="/statistic/filter/account?modifyDefault=1"></f7-list-item>
|
||||
|
||||
<f7-list-item :title="$t('Default Transaction Category Filter')" link="/statistic/filter/category?modifyDefault=1"></f7-list-item>
|
||||
<f7-list-item :title="$t('Default Transaction Category Filter')" link="/statistic/filter/category?modifyDefault=1"></f7-list-item>
|
||||
|
||||
<f7-list-item
|
||||
:title="$t('Default Sort By')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', searchbar: true, searchbarPlaceholder: $t('Default Sort By'), searchbarDisableText: $t('Cancel'), closeOnSelect: true, popupCloseLinkText: $t('Done'), scrollToSelectedItem: true }">
|
||||
<select v-model="defaultSortingType">
|
||||
<option v-for="sortingType in allSortingTypes"
|
||||
:key="sortingType.type"
|
||||
:value="sortingType.type">{{ $t(sortingType.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
</f7-card>
|
||||
<f7-list-item
|
||||
:title="$t('Default Sort By')"
|
||||
smart-select :smart-select-params="{ openIn: 'popup', popupPush: true, closeOnSelect: true, scrollToSelectedItem: true, searchbar: true, searchbarPlaceholder: $t('Sort By'), searchbarDisableText: $t('Cancel'), appendSearchbarNotFound: $t('No results'), popupCloseLinkText: $t('Done') }">
|
||||
<select v-model="defaultSortingType">
|
||||
<option :value="sortingType.type"
|
||||
:key="sortingType.type"
|
||||
v-for="sortingType in allSortingTypes">{{ $t(sortingType.name) }}</option>
|
||||
</select>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-page>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<f7-nav-left :back-link="$t('Back')"></f7-nav-left>
|
||||
<f7-nav-title>
|
||||
<f7-link popover-open=".chart-data-type-popover-menu">
|
||||
<span>{{ query.chartDataType | optionName(allChartDataTypes, 'type', 'name', 'Statistics') | localized }}</span>
|
||||
<span>{{ queryChartDataTypeName }}</span>
|
||||
<f7-icon size="14px" :f7="showChartDataTypePopover ? 'arrowtriangle_up_fill' : 'arrowtriangle_down_fill'"></f7-icon>
|
||||
</f7-link>
|
||||
</f7-nav-title>
|
||||
@@ -15,11 +15,14 @@
|
||||
|
||||
<f7-popover class="chart-data-type-popover-menu" :opened="showChartDataTypePopover"
|
||||
@popover:open="showChartDataTypePopover = true" @popover:close="showChartDataTypePopover = false">
|
||||
<f7-list>
|
||||
<f7-list-item
|
||||
v-for="dataType in allChartDataTypes" :key="dataType.type"
|
||||
:title="$t(dataType.name)" @click="setChartDataType(dataType.type)">
|
||||
<f7-icon slot="after" class="list-item-checked-icon" f7="checkmark_alt" v-if="query.chartDataType === dataType.type"></f7-icon>
|
||||
<f7-list dividers>
|
||||
<f7-list-item :title="$t(dataType.name)"
|
||||
:key="dataType.type"
|
||||
v-for="dataType in allChartDataTypes"
|
||||
@click="setChartDataType(dataType.type)">
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.chartDataType === dataType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
@@ -28,7 +31,7 @@
|
||||
<f7-card-header class="no-border display-block">
|
||||
<div class="statistics-chart-header full-line text-align-right">
|
||||
<span style="margin-right: 4px;">{{ $t('Sort By') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ query.sortingType | optionName(allSortingTypes, 'type', 'name', 'System Default') | localized }}</f7-link>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</f7-card-header>
|
||||
<f7-card-content class="pie-chart-container" style="margin-top: -6px" :padding="false">
|
||||
@@ -61,10 +64,10 @@
|
||||
@click="clickPieChartItem"
|
||||
>
|
||||
<text class="statistics-pie-chart-total-amount-title" v-if="statisticsData.items && statisticsData.items.length">
|
||||
{{ query.chartDataType | totalAmountName(allChartDataTypes) | localized }}
|
||||
{{ totalAmountName }}
|
||||
</text>
|
||||
<text class="statistics-pie-chart-total-amount-value" v-if="statisticsData.items && statisticsData.items.length">
|
||||
{{ statisticsData.totalAmount | currency(defaultCurrency) | finalAmount(showAccountBalance, query.chartDataType, allChartDataTypes) | textLimit(16) }}
|
||||
{{ getDisplayAmount(statisticsData.totalAmount, defaultCurrency, 16) }}
|
||||
</text>
|
||||
<text class="statistics-pie-chart-total-no-data" cy="50%" v-if="!statisticsData.items || !statisticsData.items.length">
|
||||
{{ $t('No data') }}
|
||||
@@ -77,128 +80,91 @@
|
||||
<f7-card-header class="no-border display-block">
|
||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||
<div>
|
||||
{{ query.chartDataType | totalAmountName(allChartDataTypes) | localized }}
|
||||
{{ totalAmountName }}
|
||||
</div>
|
||||
<div class="align-self-flex-end">
|
||||
<span style="margin-right: 4px;">{{ $t('Sort By') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ query.sortingType | optionName(allSortingTypes, 'type', 'name', 'System Default') | localized }}</f7-link>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="display-flex full-line">
|
||||
<div :class="{ 'statistics-list-item-overview-amount': true, 'text-color-teal': query.chartDataType === allChartDataTypes.ExpenseByAccount.type || query.chartDataType === allChartDataTypes.ExpenseByPrimaryCategory.type || query.chartDataType === allChartDataTypes.ExpenseBySecondaryCategory.type, 'text-color-red': query.chartDataType === allChartDataTypes.IncomeByAccount.type || query.chartDataType === allChartDataTypes.IncomeByPrimaryCategory.type || query.chartDataType === allChartDataTypes.IncomeBySecondaryCategory.type }">
|
||||
<span v-if="!loading && statisticsData && statisticsData.items && statisticsData.items.length">
|
||||
{{ statisticsData.totalAmount | currency(defaultCurrency) | finalAmount(showAccountBalance, query.chartDataType, allChartDataTypes) }}
|
||||
{{ getDisplayAmount(statisticsData.totalAmount, defaultCurrency) }}
|
||||
</span>
|
||||
<span v-else-if="loading || !statisticsData || !statisticsData.items || !statisticsData.items.length">
|
||||
{{ '---' | currency(defaultCurrency, true) }}
|
||||
<span :class="{ 'skeleton-text': loading }" v-else-if="loading || !statisticsData || !statisticsData.items || !statisticsData.items.length">
|
||||
***.**
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</f7-card-header>
|
||||
<f7-card-content class="no-safe-areas" style="margin-top: -14px" :padding="false">
|
||||
<f7-card-content style="margin-top: -14px" :padding="false">
|
||||
<f7-list class="statistics-list-item skeleton-text" v-if="loading">
|
||||
<f7-list-item link="#">
|
||||
<div slot="media" class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
<f7-list-item link="#" :key="itemIdx" v-for="itemIdx in [ 1, 2, 3 ]">
|
||||
<template #media>
|
||||
<div class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<f7-icon f7="app_fill"></f7-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="title" class="statistics-list-item-text">
|
||||
<span>Category Name 1</span>
|
||||
<small class="statistics-percent">33.33</small>
|
||||
</div>
|
||||
|
||||
<div slot="after">
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="statistics-list-item-text">
|
||||
<span>Category Name</span>
|
||||
<small class="statistics-percent">33.33</small>
|
||||
</div>
|
||||
</template>
|
||||
<template #after>
|
||||
<span>0.00 USD</span>
|
||||
</div>
|
||||
|
||||
<div slot="inner-end" class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar></f7-progressbar>
|
||||
</template>
|
||||
<template #inner-end>
|
||||
<div class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar></f7-progressbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</f7-list-item>
|
||||
<f7-list-item link="#">
|
||||
<div slot="media" class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="title" class="statistics-list-item-text">
|
||||
<span>Category Name 2</span>
|
||||
<small class="statistics-percent">33.33</small>
|
||||
</div>
|
||||
|
||||
<div slot="after">
|
||||
<span>0.00 USD</span>
|
||||
</div>
|
||||
|
||||
<div slot="inner-end" class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar></f7-progressbar>
|
||||
</div>
|
||||
</div>
|
||||
</f7-list-item>
|
||||
<f7-list-item link="#">
|
||||
<div slot="media" class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<f7-icon slot="media" f7="app_fill"></f7-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div slot="title" class="statistics-list-item-text">
|
||||
<span>Category Name 3</span>
|
||||
<small class="statistics-percent">33.33</small>
|
||||
</div>
|
||||
|
||||
<div slot="after">
|
||||
<span>0.00 USD</span>
|
||||
</div>
|
||||
|
||||
<div slot="inner-end" class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar></f7-progressbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-list v-else-if="!loading && (!statisticsData || !statisticsData.items || !statisticsData.items.length)">
|
||||
<f7-list-item :title="$t('No transaction data')"></f7-list-item>
|
||||
</f7-list>
|
||||
|
||||
<f7-list v-else-if="!loading && statisticsData && statisticsData.items && statisticsData.items.length">
|
||||
<f7-list-item v-for="(item, idx) in statisticsData.items" :key="idx"
|
||||
class="statistics-list-item"
|
||||
:link="item | itemLinkUrl(query, allChartDataTypes)"
|
||||
<f7-list-item class="statistics-list-item"
|
||||
:link="getItemLinkUrl(item)"
|
||||
:key="idx"
|
||||
v-for="(item, idx) in statisticsData.items"
|
||||
v-show="!item.hidden"
|
||||
>
|
||||
<div slot="media" class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<f7-icon v-if="item.icon"
|
||||
:icon="item.icon | icon(item.type)"
|
||||
:style="item.color | iconStyle(item.type, 'var(--category-icon-color)')">
|
||||
</f7-icon>
|
||||
<f7-icon v-else-if="!item.icon"
|
||||
f7="pencil_ellipsis_rectangle">
|
||||
</f7-icon>
|
||||
<template #media>
|
||||
<div class="display-flex no-padding-horizontal">
|
||||
<div class="display-flex align-items-center statistics-icon">
|
||||
<ItemIcon icon-type="category" :icon-id="item.icon" :color="item.color" v-if="item.icon"></ItemIcon>
|
||||
<f7-icon f7="pencil_ellipsis_rectangle" v-else-if="!item.icon"></f7-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div slot="title" class="statistics-list-item-text">
|
||||
<span>{{ item.name }}</span>
|
||||
<small class="statistics-percent" v-if="item.percent >= 0">{{ item.percent | percent(2, '<0.01') }}</small>
|
||||
</div>
|
||||
|
||||
<div slot="after">
|
||||
<span>{{ item.totalAmount | currency(item.currency || defaultCurrency) | finalAmount(showAccountBalance, query.chartDataType, allChartDataTypes) }}</span>
|
||||
</div>
|
||||
|
||||
<div slot="inner-end" class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar :progress="item.percent >= 0 ? item.percent : 0" :style="{ '--f7-progressbar-progress-color': (item.color ? '#' + item.color : '') } "></f7-progressbar>
|
||||
<template #title>
|
||||
<div class="statistics-list-item-text">
|
||||
<span>{{ item.name }}</span>
|
||||
<small class="statistics-percent" v-if="item.percent >= 0">{{ $utilities.formatPercent(item.percent, 2, '<0.01') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #after>
|
||||
<span>{{ getDisplayAmount(item.totalAmount, (item.currency || defaultCurrency)) }}</span>
|
||||
</template>
|
||||
|
||||
<template #inner-end>
|
||||
<div class="statistics-item-end">
|
||||
<div class="statistics-percent-line">
|
||||
<f7-progressbar :progress="item.percent >= 0 ? item.percent : 0" :style="{ '--f7-progressbar-progress-color': (item.color ? '#' + item.color : '') } "></f7-progressbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-card-content>
|
||||
@@ -207,13 +173,15 @@
|
||||
<f7-popover class="sorting-type-popover-menu" :opened="showSortingTypePopover"
|
||||
@popover:open="scrollPopoverToSelectedItem"
|
||||
@popover:opened="showSortingTypePopover = true" @popover:closed="showSortingTypePopover = false">
|
||||
<f7-list>
|
||||
<f7-list-item v-for="sortingType in allSortingTypes"
|
||||
:key="sortingType.type"
|
||||
<f7-list dividers>
|
||||
<f7-list-item :title="$t(sortingType.name)"
|
||||
:class="{ 'list-item-selected': query.sortingType === sortingType.type }"
|
||||
:title="$t(sortingType.name)"
|
||||
:key="sortingType.type"
|
||||
v-for="sortingType in allSortingTypes"
|
||||
@click="setSortingType(sortingType.type)">
|
||||
<f7-icon slot="after" class="list-item-checked-icon" f7="checkmark_alt" v-if="query.sortingType === sortingType.type"></f7-icon>
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.sortingType === sortingType.type"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
@@ -239,28 +207,31 @@
|
||||
<f7-popover class="date-popover-menu" :opened="showDatePopover"
|
||||
@popover:open="scrollPopoverToSelectedItem"
|
||||
@popover:opened="showDatePopover = true" @popover:closed="showDatePopover = false">
|
||||
<f7-list>
|
||||
<f7-list-item v-for="dateRange in allDateRanges"
|
||||
:key="dateRange.type"
|
||||
<f7-list dividers>
|
||||
<f7-list-item :title="$t(dateRange.name)"
|
||||
:class="{ 'list-item-selected': query.dateType === dateRange.type }"
|
||||
:title="$t(dateRange.name)"
|
||||
:key="dateRange.type"
|
||||
v-for="dateRange in allDateRanges"
|
||||
@click="setDateFilter(dateRange.type)">
|
||||
<f7-icon slot="after" class="list-item-checked-icon" f7="checkmark_alt" v-if="query.dateType === dateRange.type"></f7-icon>
|
||||
<div slot="footer"
|
||||
v-if="dateRange.type === allDateRanges.Custom.type && query.dateType === allDateRanges.Custom.type && query.startTime && query.endTime">
|
||||
<span>{{ query.startTime | moment($t('format.datetime.long-without-second')) }}</span>
|
||||
<span> - </span>
|
||||
<br/>
|
||||
<span>{{ query.endTime | moment($t('format.datetime.long-without-second')) }}</span>
|
||||
</div>
|
||||
<template #after>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.dateType === dateRange.type"></f7-icon>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div v-if="dateRange.type === allDateRanges.Custom.type && query.dateType === allDateRanges.Custom.type && query.startTime && query.endTime">
|
||||
<span>{{ $utilities.formatUnixTime(query.startTime, $t('format.datetime.long-without-second')) }}</span>
|
||||
<span> - </span>
|
||||
<br/>
|
||||
<span>{{ $utilities.formatUnixTime(query.endTime, $t('format.datetime.long-without-second')) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
</f7-popover>
|
||||
|
||||
<date-range-selection-sheet :title="$t('Custom Date Range')"
|
||||
:show.sync="showCustomDateRangeSheet"
|
||||
:min-time="query.startTime"
|
||||
:max-time="query.endTime"
|
||||
v-model:show="showCustomDateRangeSheet"
|
||||
@dateRange:change="setCustomDateFilter">
|
||||
</date-range-selection-sheet>
|
||||
|
||||
@@ -281,6 +252,9 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'f7router'
|
||||
],
|
||||
data() {
|
||||
const self = this;
|
||||
|
||||
@@ -305,6 +279,14 @@ export default {
|
||||
query() {
|
||||
return this.$store.state.transactionStatisticsFilter;
|
||||
},
|
||||
queryChartDataTypeName() {
|
||||
const queryChartDataTypeName = this.$utilities.getNameByKeyValue(this.allChartDataTypes, this.query.chartDataType, 'type', 'name', 'Statistics');
|
||||
return this.$t(queryChartDataTypeName);
|
||||
},
|
||||
querySortingTypeName() {
|
||||
const querySortingTypeName = this.$utilities.getNameByKeyValue(this.allSortingTypes, this.query.sortingType, 'type', 'name', 'System Default');
|
||||
return this.$t(querySortingTypeName);
|
||||
},
|
||||
allChartDataTypes() {
|
||||
return this.$constants.statistics.allChartDataTypes;
|
||||
},
|
||||
@@ -314,6 +296,23 @@ export default {
|
||||
allDateRanges() {
|
||||
return this.$constants.datetime.allDateRanges;
|
||||
},
|
||||
totalAmountName() {
|
||||
if (this.query.chartDataType === this.allChartDataTypes.IncomeByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.IncomeByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.IncomeBySecondaryCategory.type) {
|
||||
return this.$t('Total Income');
|
||||
} else if (this.query.chartDataType === this.allChartDataTypes.ExpenseByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
return this.$t('Total Expense');
|
||||
} else if (this.query.chartDataType === this.allChartDataTypes.AccountTotalAssets.type) {
|
||||
return this.$t('Total Assets');
|
||||
} else if (this.query.chartDataType === this.allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
return this.$t('Total Liabilities');
|
||||
}
|
||||
|
||||
return this.$t('Total Amount');
|
||||
},
|
||||
statisticsData() {
|
||||
const self = this;
|
||||
let combinedData = {
|
||||
@@ -466,7 +465,7 @@ export default {
|
||||
this.reload(null);
|
||||
}
|
||||
|
||||
this.$routeBackOnError('loadingError');
|
||||
this.$routeBackOnError(this.f7router, 'loadingError');
|
||||
},
|
||||
reload(done) {
|
||||
const self = this;
|
||||
@@ -649,16 +648,16 @@ export default {
|
||||
return `${displayStartTime} ~ ${displayEndTime}`;
|
||||
},
|
||||
clickPieChartItem(item) {
|
||||
this.$f7router.navigate(this.$options.filters.itemLinkUrl(item, this.query, this.allChartDataTypes));
|
||||
this.f7router.navigate(this.getItemLinkUrl(item));
|
||||
},
|
||||
filterAccounts() {
|
||||
this.$f7router.navigate('/statistic/filter/account');
|
||||
this.f7router.navigate('/statistic/filter/account');
|
||||
},
|
||||
filterCategories() {
|
||||
this.$f7router.navigate('/statistic/filter/category');
|
||||
this.f7router.navigate('/statistic/filter/category');
|
||||
},
|
||||
settings() {
|
||||
this.$f7router.navigate('/statistic/settings');
|
||||
this.f7router.navigate('/statistic/settings');
|
||||
},
|
||||
scrollPopoverToSelectedItem(event) {
|
||||
if (!event || !event.$el || !event.$el.length) {
|
||||
@@ -680,48 +679,53 @@ export default {
|
||||
}
|
||||
|
||||
container.scrollTop(targetPos);
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
finalAmount(amount, isShowAccountBalance, dataType, allChartDataTypes) {
|
||||
if (!isShowAccountBalance && (dataType === allChartDataTypes.AccountTotalAssets.type || dataType === allChartDataTypes.AccountTotalLiabilities.type)) {
|
||||
},
|
||||
getDisplayAmount(amount, currency, textLimit) {
|
||||
amount = this.$locale.getDisplayCurrency(amount, currency);
|
||||
|
||||
if (!this.showAccountBalance
|
||||
&& (this.query.chartDataType === this.allChartDataTypes.AccountTotalAssets.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.AccountTotalLiabilities.type)
|
||||
) {
|
||||
return '***';
|
||||
}
|
||||
|
||||
if (textLimit) {
|
||||
this.$utilities.limitText(amount, textLimit);
|
||||
}
|
||||
|
||||
return amount;
|
||||
},
|
||||
totalAmountName(dataType, allChartDataTypes) {
|
||||
if (dataType === allChartDataTypes.IncomeByAccount.type || dataType === allChartDataTypes.IncomeByPrimaryCategory.type || dataType === allChartDataTypes.IncomeBySecondaryCategory.type) {
|
||||
return 'Total Income';
|
||||
} else if (dataType === allChartDataTypes.ExpenseByAccount.type || dataType === allChartDataTypes.ExpenseByPrimaryCategory.type || dataType === allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
return 'Total Expense';
|
||||
} else if (dataType === allChartDataTypes.AccountTotalAssets.type) {
|
||||
return 'Total Assets';
|
||||
} else if (dataType === allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
return 'Total Liabilities';
|
||||
}
|
||||
|
||||
return 'Total Amount';
|
||||
},
|
||||
itemLinkUrl(item, query, allChartDataTypes) {
|
||||
getItemLinkUrl(item) {
|
||||
const querys = [];
|
||||
|
||||
if (query.chartDataType === allChartDataTypes.IncomeByAccount.type || query.chartDataType === allChartDataTypes.IncomeByPrimaryCategory.type || query.chartDataType === allChartDataTypes.IncomeBySecondaryCategory.type) {
|
||||
if (this.query.chartDataType === this.allChartDataTypes.IncomeByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.IncomeByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.IncomeBySecondaryCategory.type) {
|
||||
querys.push('type=2');
|
||||
} else if (query.chartDataType === allChartDataTypes.ExpenseByAccount.type || query.chartDataType === allChartDataTypes.ExpenseByPrimaryCategory.type || query.chartDataType === allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
} else if (this.query.chartDataType === this.allChartDataTypes.ExpenseByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
querys.push('type=3');
|
||||
}
|
||||
|
||||
if (query.chartDataType === allChartDataTypes.IncomeByAccount.type || query.chartDataType === allChartDataTypes.ExpenseByAccount.type || query.chartDataType === allChartDataTypes.AccountTotalAssets.type || query.chartDataType === allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
if (this.query.chartDataType === this.allChartDataTypes.IncomeByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseByAccount.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.AccountTotalAssets.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
querys.push('accountId=' + item.id);
|
||||
} else if (query.chartDataType === allChartDataTypes.IncomeByPrimaryCategory.type || query.chartDataType === allChartDataTypes.IncomeBySecondaryCategory.type || query.chartDataType === allChartDataTypes.ExpenseByPrimaryCategory.type || query.chartDataType === allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
} else if (this.query.chartDataType === this.allChartDataTypes.IncomeByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.IncomeBySecondaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseByPrimaryCategory.type
|
||||
|| this.query.chartDataType === this.allChartDataTypes.ExpenseBySecondaryCategory.type) {
|
||||
querys.push('categoryId=' + item.id);
|
||||
}
|
||||
|
||||
if (query.chartDataType !== allChartDataTypes.AccountTotalAssets.type && query.chartDataType !== allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
querys.push('dateType=' + query.dateType);
|
||||
querys.push('minTime=' + query.startTime);
|
||||
querys.push('maxTime=' + query.endTime);
|
||||
if (this.query.chartDataType !== this.allChartDataTypes.AccountTotalAssets.type
|
||||
&& this.query.chartDataType !== this.allChartDataTypes.AccountTotalLiabilities.type) {
|
||||
querys.push('dateType=' + this.query.dateType);
|
||||
querys.push('minTime=' + this.query.startTime);
|
||||
querys.push('maxTime=' + this.query.endTime);
|
||||
}
|
||||
|
||||
return '/transaction/list?' + querys.join('&');
|
||||
@@ -808,7 +812,7 @@ export default {
|
||||
--f7-progressbar-bg-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.theme-dark .statistics-percent-line .progressbar {
|
||||
.dark .statistics-percent-line .progressbar {
|
||||
--f7-progressbar-bg-color: #161616;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user