mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-17 00:12:11 +08:00
add transaction tag filter to frontend
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
<template>
|
||||
<v-card :class="{ 'pa-2 pa-sm-4 pa-md-8': dialogMode }">
|
||||
<template #title>
|
||||
<div class="d-flex align-center justify-center" v-if="dialogMode">
|
||||
<div class="w-100 text-center">
|
||||
<h4 class="text-h4">{{ $t(title) }}</h4>
|
||||
</div>
|
||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
||||
:disabled="loading || !hasAnyAvailableTag" :icon="true">
|
||||
<v-icon :icon="icons.more" />
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-item :prepend-icon="icons.selectAll"
|
||||
:title="$t('Select All')"
|
||||
@click="selectAll"></v-list-item>
|
||||
<v-list-item :prepend-icon="icons.selectNone"
|
||||
:title="$t('Select None')"
|
||||
@click="selectNone"></v-list-item>
|
||||
<v-list-item :prepend-icon="icons.selectInverse"
|
||||
:title="$t('Invert Selection')"
|
||||
@click="selectInvert"></v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
</div>
|
||||
<div class="d-flex align-center" v-else-if="!dialogMode">
|
||||
<span>{{ $t(title) }}</span>
|
||||
<v-spacer/>
|
||||
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
|
||||
:disabled="loading" :icon="true">
|
||||
<v-icon :icon="icons.more" />
|
||||
<v-menu activator="parent">
|
||||
<v-list>
|
||||
<v-list-item :prepend-icon="icons.selectAll"
|
||||
:title="$t('Select All')"
|
||||
@click="selectAll"></v-list-item>
|
||||
<v-list-item :prepend-icon="icons.selectNone"
|
||||
:title="$t('Select None')"
|
||||
@click="selectNone"></v-list-item>
|
||||
<v-list-item :prepend-icon="icons.selectInverse"
|
||||
:title="$t('Invert Selection')"
|
||||
@click="selectInvert"></v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-if="loading">
|
||||
<v-skeleton-loader type="paragraph" :loading="loading"
|
||||
:key="itemIdx" v-for="itemIdx in [ 1, 2, 3 ]"></v-skeleton-loader>
|
||||
</div>
|
||||
|
||||
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-if="!loading && !hasAnyAvailableTag">
|
||||
<span class="text-body-1">{{ $t('No available tag') }}</span>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text :class="{ 'mt-0 mt-sm-2 mt-md-4': dialogMode }" v-else-if="!loading && hasAnyAvailableTag">
|
||||
<v-expansion-panels class="tag-categories" multiple v-model="expandTagCategories">
|
||||
<v-expansion-panel class="border" key="default" value="default">
|
||||
<v-expansion-panel-title class="expand-panel-title-with-bg py-0">
|
||||
<span class="ml-3">{{ $t('Tags') }}</span>
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<v-list rounded density="comfortable" class="pa-0">
|
||||
<template :key="transactionTag.id"
|
||||
v-for="transactionTag in allVisibleTags">
|
||||
<v-list-item>
|
||||
<template #prepend>
|
||||
<v-checkbox :model-value="!filterTagIds[transactionTag.id]"
|
||||
@update:model-value="selectTransactionTag(transactionTag, $event)">
|
||||
<template #label>
|
||||
<v-icon size="24" :icon="icons.tag"/>
|
||||
<span class="ml-3">{{ transactionTag.name }}</span>
|
||||
</template>
|
||||
</v-checkbox>
|
||||
</template>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text class="overflow-y-visible" v-if="dialogMode">
|
||||
<div class="w-100 d-flex justify-center mt-2 mt-sm-4 mt-md-6 gap-4">
|
||||
<v-btn :disabled="!hasAnyAvailableTag" @click="save">{{ $t(applyText) }}</v-btn>
|
||||
<v-btn color="secondary" variant="tonal" @click="cancel">{{ $t('Cancel') }}</v-btn>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapStores } from 'pinia';
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.js';
|
||||
import { useTransactionsStore } from '@/stores/transaction.js';
|
||||
|
||||
import {
|
||||
selectAll,
|
||||
selectNone,
|
||||
selectInvert
|
||||
} from '@/lib/common.js';
|
||||
|
||||
import {
|
||||
mdiSelectAll,
|
||||
mdiSelect,
|
||||
mdiSelectInverse,
|
||||
mdiDotsVertical,
|
||||
mdiPound
|
||||
} from '@mdi/js';
|
||||
|
||||
export default {
|
||||
props: [
|
||||
'dialogMode',
|
||||
'type',
|
||||
'autoSave'
|
||||
],
|
||||
emits: [
|
||||
'settings:change'
|
||||
],
|
||||
data: function () {
|
||||
return {
|
||||
loading: true,
|
||||
expandTagCategories: [ 'default' ],
|
||||
filterTagIds: {},
|
||||
icons: {
|
||||
selectAll: mdiSelectAll,
|
||||
selectNone: mdiSelect,
|
||||
selectInverse: mdiSelectInverse,
|
||||
more: mdiDotsVertical,
|
||||
tag: mdiPound
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapStores(useTransactionTagsStore, useTransactionsStore),
|
||||
title() {
|
||||
return 'Filter Transaction Tags';
|
||||
},
|
||||
applyText() {
|
||||
return 'Apply';
|
||||
},
|
||||
allVisibleTags() {
|
||||
return this.transactionTagsStore.allVisibleTags;
|
||||
},
|
||||
hasAnyAvailableTag() {
|
||||
return this.transactionTagsStore.allVisibleTagsCount > 0;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const self = this;
|
||||
|
||||
self.transactionTagsStore.loadAllTags({
|
||||
force: false
|
||||
}).then(() => {
|
||||
self.loading = false;
|
||||
|
||||
const allTransactionTagIds = {};
|
||||
|
||||
for (let transactionTagId in self.transactionTagsStore.allTransactionTagsMap) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.transactionTagsStore.allTransactionTagsMap, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (self.type === 'transactionListCurrent' && self.transactionsStore.allFilterTagIdsCount > 0) {
|
||||
allTransactionTagIds[transactionTag.id] = true;
|
||||
} else {
|
||||
allTransactionTagIds[transactionTag.id] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.type === 'transactionListCurrent') {
|
||||
for (let transactionTagId in self.transactionsStore.allFilterTagIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.transactionsStore.allFilterTagIds, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (transactionTag) {
|
||||
allTransactionTagIds[transactionTag.id] = false;
|
||||
}
|
||||
}
|
||||
self.filterTagIds = allTransactionTagIds;
|
||||
} else {
|
||||
self.$refs.snackbar.showError('Parameter Invalid');
|
||||
}
|
||||
}).catch(error => {
|
||||
self.loading = false;
|
||||
|
||||
if (!error.processed) {
|
||||
self.$refs.snackbar.showError(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
const self = this;
|
||||
|
||||
const filteredTagIds = {};
|
||||
let isAllSelected = true;
|
||||
let finalTagIds = '';
|
||||
let changed = true;
|
||||
|
||||
for (let transactionTagId in self.filterTagIds) {
|
||||
if (!Object.prototype.hasOwnProperty.call(self.filterTagIds, transactionTagId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const transactionTag = self.transactionTagsStore.allTransactionTagsMap[transactionTagId];
|
||||
|
||||
if (self.filterTagIds[transactionTag.id]) {
|
||||
filteredTagIds[transactionTag.id] = true;
|
||||
isAllSelected = false;
|
||||
} else {
|
||||
if (finalTagIds.length > 0) {
|
||||
finalTagIds += ',';
|
||||
}
|
||||
|
||||
finalTagIds += transactionTag.id;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.type === 'transactionListCurrent') {
|
||||
changed = self.transactionsStore.updateTransactionListFilter({
|
||||
tagIds: isAllSelected ? '' : finalTagIds
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
self.transactionsStore.updateTransactionListInvalidState(true);
|
||||
}
|
||||
}
|
||||
|
||||
self.$emit('settings:change', changed);
|
||||
},
|
||||
cancel() {
|
||||
this.$emit('settings:change', false);
|
||||
},
|
||||
selectTransactionTag(transactionTag, value) {
|
||||
this.filterTagIds[transactionTag.id] = !value;
|
||||
|
||||
if (this.autoSave) {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
selectAll() {
|
||||
selectAll(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
|
||||
if (this.autoSave) {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
selectNone() {
|
||||
selectNone(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
|
||||
if (this.autoSave) {
|
||||
this.save();
|
||||
}
|
||||
},
|
||||
selectInvert() {
|
||||
selectInvert(this.filterTagIds, this.transactionTagsStore.allTransactionTagsMap);
|
||||
|
||||
if (this.autoSave) {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tag-categories .v-expansion-panel-text__wrapper {
|
||||
padding: 0 0 0 20px;
|
||||
}
|
||||
|
||||
.tag-categories .v-expansion-panel--active:not(:first-child),
|
||||
.tag-categories .v-expansion-panel--active + .v-expansion-panel {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
@@ -308,7 +308,61 @@
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</th>
|
||||
<th class="transaction-table-column-tags" v-if="showTagInTransactionListPage">{{ $t('Tags') }}</th>
|
||||
<th class="transaction-table-column-tags" v-if="showTagInTransactionListPage">
|
||||
<v-menu ref="tagFilterMenu" class="transaction-tag-menu"
|
||||
eager location="bottom" max-height="500"
|
||||
@update:model-value="scrollTagMenuToSelectedItem">
|
||||
<template #activator="{ props }">
|
||||
<div class="d-flex align-center cursor-pointer"
|
||||
:class="{ 'readonly': loading, 'text-primary': query.tagIds }" v-bind="props">
|
||||
<span>{{ queryTagName }}</span>
|
||||
<v-icon :icon="icons.dropdownMenu" />
|
||||
</div>
|
||||
</template>
|
||||
<v-list :selected="[queryAllSelectedFilterTagIds]">
|
||||
<v-list-item key="" value="" class="text-sm" density="compact"
|
||||
:class="{ 'list-item-selected': !query.tagIds }"
|
||||
:append-icon="(!query.tagIds ? icons.check : null)">
|
||||
<v-list-item-title class="cursor-pointer"
|
||||
@click="changeTagFilter('')">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon :icon="icons.all" />
|
||||
<span class="text-sm ml-3">{{ $t('All') }}</span>
|
||||
</div>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<v-list-item key="multiple" value="multiple" class="text-sm" density="compact"
|
||||
:class="{ 'list-item-selected': query.tagIds && queryAllFilterTagIdsCount > 1 }"
|
||||
:append-icon="(query.tagIds && queryAllFilterTagIdsCount > 1 ? icons.check : null)"
|
||||
v-if="allVisibleTagsCount > 0">
|
||||
<v-list-item-title class="cursor-pointer"
|
||||
@click="showFilterTagDialog = true">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon :icon="icons.multiple" />
|
||||
<span class="text-sm ml-3">{{ $t('Multiple Tags') }}</span>
|
||||
</div>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
<template :key="transactionTag.id"
|
||||
v-for="transactionTag in allTransactionTags">
|
||||
<v-divider v-if="!transactionTag.hidden" />
|
||||
<v-list-item class="text-sm" density="compact"
|
||||
:value="transactionTag.id"
|
||||
:class="{ 'list-item-selected': query.tagIds === transactionTag.id, 'item-in-multiple-selection': queryAllFilterTagIdsCount > 1 && queryAllFilterTagIds[transactionTag.id] }"
|
||||
:append-icon="(query.tagIds === transactionTag.id ? icons.check : null)"
|
||||
v-if="!transactionTag.hidden">
|
||||
<v-list-item-title class="cursor-pointer"
|
||||
@click="changeTagFilter(transactionTag.id)">
|
||||
<div class="d-flex align-center">
|
||||
<v-icon size="24" :icon="icons.tag"/>
|
||||
<span class="text-sm ml-3">{{ transactionTag.name }}</span>
|
||||
</div>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</th>
|
||||
<th class="transaction-table-column-description">{{ $t('Description') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -427,6 +481,11 @@
|
||||
@settings:change="changeMultipleCategoriesFilter" />
|
||||
</v-dialog>
|
||||
|
||||
<v-dialog width="800" v-model="showFilterTagDialog">
|
||||
<transaction-tag-filter-settings-card type="transactionListCurrent" :dialog-mode="true"
|
||||
@settings:change="changeMultipleTagsFilter" />
|
||||
</v-dialog>
|
||||
|
||||
<confirm-dialog ref="confirmDialog"/>
|
||||
<snack-bar ref="snackbar" />
|
||||
</template>
|
||||
@@ -435,6 +494,7 @@
|
||||
import EditDialog from './list/dialogs/EditDialog.vue';
|
||||
import AccountFilterSettingsCard from '@/views/desktop/common/cards/AccountFilterSettingsCard.vue';
|
||||
import CategoryFilterSettingsCard from '@/views/desktop/common/cards/CategoryFilterSettingsCard.vue';
|
||||
import TransactionTagFilterSettingsCard from '@/views/desktop/common/cards/TransactionTagFilterSettingsCard.vue';
|
||||
|
||||
import { useDisplay } from 'vuetify';
|
||||
|
||||
@@ -495,6 +555,7 @@ import {
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TransactionTagFilterSettingsCard,
|
||||
EditDialog,
|
||||
AccountFilterSettingsCard,
|
||||
CategoryFilterSettingsCard
|
||||
@@ -506,6 +567,7 @@ export default {
|
||||
'initType',
|
||||
'initCategoryIds',
|
||||
'initAccountIds',
|
||||
'initTagIds',
|
||||
'initAmountFilter',
|
||||
'initKeyword'
|
||||
],
|
||||
@@ -533,6 +595,7 @@ export default {
|
||||
showCustomDateRangeDialog: false,
|
||||
showFilterAccountDialog: false,
|
||||
showFilterCategoryDialog: false,
|
||||
showFilterTagDialog: false,
|
||||
icons: {
|
||||
search: mdiMagnify,
|
||||
check: mdiCheck,
|
||||
@@ -606,12 +669,18 @@ export default {
|
||||
queryAllFilterAccountIds() {
|
||||
return this.transactionsStore.allFilterAccountIds;
|
||||
},
|
||||
queryAllFilterTagIds() {
|
||||
return this.transactionsStore.allFilterTagIds;
|
||||
},
|
||||
queryAllFilterCategoryIdsCount() {
|
||||
return this.transactionsStore.allFilterCategoryIdsCount;
|
||||
},
|
||||
queryAllFilterAccountIdsCount() {
|
||||
return this.transactionsStore.allFilterAccountIdsCount;
|
||||
},
|
||||
queryAllFilterTagIdsCount() {
|
||||
return this.transactionsStore.allFilterTagIdsCount;
|
||||
},
|
||||
queryAllSelectedFilterCategoryIds() {
|
||||
if (this.queryAllFilterCategoryIdsCount === 0) {
|
||||
return '';
|
||||
@@ -630,6 +699,15 @@ export default {
|
||||
return 'multiple';
|
||||
}
|
||||
},
|
||||
queryAllSelectedFilterTagIds() {
|
||||
if (this.queryAllFilterTagIdsCount === 0) {
|
||||
return '';
|
||||
} else if (this.queryAllFilterTagIdsCount === 1) {
|
||||
return this.query.tagIds;
|
||||
} else { // this.queryAllFilterTagIdsCount > 1
|
||||
return 'multiple';
|
||||
}
|
||||
},
|
||||
queryCategoryName() {
|
||||
if (this.queryAllFilterCategoryIdsCount > 1) {
|
||||
return this.$t('Multiple Categories');
|
||||
@@ -644,6 +722,13 @@ export default {
|
||||
|
||||
return getNameByKeyValue(this.allAccounts, this.query.accountIds, null, 'name', this.$t('Account'));
|
||||
},
|
||||
queryTagName() {
|
||||
if (this.queryAllFilterTagIdsCount > 1) {
|
||||
return this.$t('Multiple Tags');
|
||||
}
|
||||
|
||||
return getNameByKeyValue(this.allTransactionTags, this.query.tagIds, null, 'name', this.$t('Tags'));
|
||||
},
|
||||
queryAmount() {
|
||||
if (!this.query.amountFilter) {
|
||||
return '';
|
||||
@@ -802,6 +887,9 @@ export default {
|
||||
allTransactionTags() {
|
||||
return this.transactionTagsStore.allTransactionTagsMap;
|
||||
},
|
||||
allVisibleTagsCount() {
|
||||
return this.transactionTagsStore.allVisibleTagsCount;
|
||||
},
|
||||
recentMonthDateRanges() {
|
||||
return this.$locale.getAllRecentMonthDateRanges(this.userStore, true, true);
|
||||
},
|
||||
@@ -820,6 +908,7 @@ export default {
|
||||
type: this.initType,
|
||||
categoryIds: this.initCategoryIds,
|
||||
accountIds: this.initAccountIds,
|
||||
tagIds: this.initTagIds,
|
||||
amountFilter: this.initAmountFilter,
|
||||
keyword: this.initKeyword
|
||||
});
|
||||
@@ -849,6 +938,7 @@ export default {
|
||||
type: to.query.type,
|
||||
categoryIds: to.query.categoryIds,
|
||||
accountIds: to.query.accountIds,
|
||||
tagIds: to.query.tagIds,
|
||||
amountFilter: to.query.amountFilter,
|
||||
keyword: to.query.keyword
|
||||
});
|
||||
@@ -875,6 +965,7 @@ export default {
|
||||
type: parseInt(query.type) > 0 ? parseInt(query.type) : undefined,
|
||||
categoryIds: query.categoryIds,
|
||||
accountIds: query.accountIds,
|
||||
tagIds: query.tagIds,
|
||||
amountFilter: query.amountFilter || '',
|
||||
keyword: query.keyword || ''
|
||||
});
|
||||
@@ -1156,6 +1247,32 @@ export default {
|
||||
this.$router.push(this.getFilterLinkUrl());
|
||||
}
|
||||
},
|
||||
changeTagFilter(tagIds) {
|
||||
if (this.query.tagIds === tagIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
const changed = this.transactionsStore.updateTransactionListFilter({
|
||||
tagIds: tagIds
|
||||
});
|
||||
|
||||
if (changed) {
|
||||
this.loading = true;
|
||||
this.currentPageTransactions = [];
|
||||
this.transactionsStore.clearTransactions();
|
||||
this.$router.push(this.getFilterLinkUrl());
|
||||
}
|
||||
},
|
||||
changeMultipleTagsFilter(changed) {
|
||||
this.showFilterTagDialog = false;
|
||||
|
||||
if (changed) {
|
||||
this.loading = true;
|
||||
this.currentPageTransactions = [];
|
||||
this.transactionsStore.clearTransactions();
|
||||
this.$router.push(this.getFilterLinkUrl());
|
||||
}
|
||||
},
|
||||
changeKeywordFilter(keyword) {
|
||||
if (this.query.keyword === keyword) {
|
||||
return;
|
||||
@@ -1179,7 +1296,8 @@ export default {
|
||||
self.$refs.editDialog.open({
|
||||
type: self.query.type,
|
||||
categoryId: self.queryAllFilterCategoryIdsCount === 1 ? self.query.categoryIds : '',
|
||||
accountId: self.queryAllFilterAccountIdsCount === 1 ? self.query.accountIds : ''
|
||||
accountId: self.queryAllFilterAccountIdsCount === 1 ? self.query.accountIds : '',
|
||||
tagIds: self.query.tagIds || ''
|
||||
}).then(result => {
|
||||
if (result && result.message) {
|
||||
self.$refs.snackbar.showMessage(result.message);
|
||||
@@ -1252,6 +1370,11 @@ export default {
|
||||
this.scrollMenuToSelectedItem(this.$refs.accountFilterMenu);
|
||||
}
|
||||
},
|
||||
scrollTagMenuToSelectedItem(opened) {
|
||||
if (opened) {
|
||||
this.scrollMenuToSelectedItem(this.$refs.tagFilterMenu);
|
||||
}
|
||||
},
|
||||
scrollMenuToSelectedItem(menu) {
|
||||
this.$nextTick(() => {
|
||||
scrollToSelectedItem(menu.contentEl, 'div.v-list', 'div.v-list-item.list-item-selected');
|
||||
@@ -1375,7 +1498,7 @@ export default {
|
||||
}
|
||||
|
||||
.transaction-table .transaction-table-column-tags {
|
||||
width: 80px;
|
||||
width: 90px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
@@ -1409,6 +1532,7 @@ export default {
|
||||
.transaction-category-menu .item-icon,
|
||||
.transaction-amount-menu .item-icon,
|
||||
.transaction-account-menu .item-icon,
|
||||
.transaction-tag-menu .item-icon,
|
||||
.transaction-table .item-icon {
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
@@ -1424,7 +1548,8 @@ export default {
|
||||
|
||||
.transaction-category-menu .has-children-item-selected span,
|
||||
.transaction-category-menu .item-in-multiple-selection span,
|
||||
.transaction-account-menu .item-in-multiple-selection span {
|
||||
.transaction-account-menu .item-in-multiple-selection span,
|
||||
.transaction-tag-menu .item-in-multiple-selection span {
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -488,6 +488,9 @@ export default {
|
||||
allTags() {
|
||||
return this.transactionTagsStore.allVisibleTags;
|
||||
},
|
||||
allTagsMap() {
|
||||
return this.transactionTagsStore.allTransactionTagsMap;
|
||||
},
|
||||
hasAvailableExpenseCategories() {
|
||||
if (!this.allCategories || !this.allCategories[this.allCategoryTypes.Expense] || !this.allCategories[this.allCategoryTypes.Expense].length) {
|
||||
return false;
|
||||
@@ -847,11 +850,13 @@ export default {
|
||||
this.allCategoriesMap,
|
||||
this.allVisibleAccounts,
|
||||
this.allAccountsMap,
|
||||
this.allTagsMap,
|
||||
this.defaultAccountId,
|
||||
{
|
||||
type: options.type,
|
||||
categoryId: options.categoryId,
|
||||
accountId: options.accountId
|
||||
accountId: options.accountId,
|
||||
tagIds: options.tagIds
|
||||
},
|
||||
setContextData,
|
||||
convertContextTime
|
||||
|
||||
Reference in New Issue
Block a user