mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-21 10:14:26 +08:00
support tag group for transaction tags in the import transaction tool
This commit is contained in:
@@ -757,7 +757,6 @@ export const useTransactionTagsStore = defineStore('transactionTags', () => {
|
|||||||
// states
|
// states
|
||||||
allTransactionTagGroups,
|
allTransactionTagGroups,
|
||||||
allTransactionTagGroupsMap,
|
allTransactionTagGroupsMap,
|
||||||
allTransactionTags,
|
|
||||||
allTransactionTagsMap,
|
allTransactionTagsMap,
|
||||||
allTransactionTagsByGroupMap,
|
allTransactionTagsByGroupMap,
|
||||||
transactionTagGroupListStateInvalid,
|
transactionTagGroupListStateInvalid,
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
<v-autocomplete density="compact" variant="underlined"
|
<v-autocomplete density="compact" variant="underlined"
|
||||||
item-title="name" item-value="id"
|
item-title="name" item-value="id"
|
||||||
persistent-placeholder chips
|
persistent-placeholder chips
|
||||||
:disabled="loading" :items="allTags"
|
:disabled="loading" :items="allTagsWithGroupHeader"
|
||||||
:no-data-text="tt('No available tag')"
|
:no-data-text="tt('No available tag')"
|
||||||
v-model="newRule.targetId"
|
v-model="newRule.targetId"
|
||||||
v-if="newRule.dataType == 'tag'">
|
v-if="newRule.dataType == 'tag'">
|
||||||
@@ -172,8 +172,12 @@
|
|||||||
<v-chip :prepend-icon="mdiPound" :text="item.title" v-bind="props" v-if="newRule.targetId"/>
|
<v-chip :prepend-icon="mdiPound" :text="item.title" v-bind="props" v-if="newRule.targetId"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #subheader="{ props }">
|
||||||
|
<v-list-subheader>{{ props['title'] }}</v-list-subheader>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #item="{ props, item }">
|
<template #item="{ props, item }">
|
||||||
<v-list-item :value="item.value" v-bind="props" v-if="!item.raw.hidden">
|
<v-list-item :value="item.value" v-bind="props" v-if="item.raw instanceof TransactionTag && !item.raw.hidden">
|
||||||
<template #title>
|
<template #title>
|
||||||
<v-list-item-title>
|
<v-list-item-title>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
@@ -215,6 +219,7 @@ import SnackBar from '@/components/desktop/SnackBar.vue';
|
|||||||
import { ref, computed, useTemplateRef } from 'vue';
|
import { ref, computed, useTemplateRef } from 'vue';
|
||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { useTransactionTagSelectionBase } from '@/components/base/TransactionTagSelectionBase.ts';
|
||||||
|
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
@@ -228,7 +233,7 @@ import { KnownFileType } from '@/core/file.ts';
|
|||||||
|
|
||||||
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
||||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||||
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getTransactionPrimaryCategoryName,
|
getTransactionPrimaryCategoryName,
|
||||||
@@ -257,6 +262,8 @@ interface BatchReplaceAllTypesDialogResponse {
|
|||||||
|
|
||||||
const { tt, getCategorizedAccountsWithDisplayBalance } = useI18n();
|
const { tt, getCategorizedAccountsWithDisplayBalance } = useI18n();
|
||||||
|
|
||||||
|
const { allTagsWithGroupHeader } = useTransactionTagSelectionBase({ modelValue: [] }, false);
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const accountsStore = useAccountsStore();
|
const accountsStore = useAccountsStore();
|
||||||
const transactionCategoriesStore = useTransactionCategoriesStore();
|
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||||
@@ -284,7 +291,7 @@ const allAccounts = computed<Account[]>(() => accountsStore.allPlainAccounts);
|
|||||||
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
|
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
|
||||||
const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value, customAccountCategoryOrder.value));
|
const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value, customAccountCategoryOrder.value));
|
||||||
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
||||||
const allTags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
const allTagsMap = computed<Record<string, TransactionTag>>(() => transactionTagsStore.allTransactionTagsMap);
|
||||||
|
|
||||||
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
||||||
const hasVisibleIncomeCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleIncomeCategories);
|
const hasVisibleIncomeCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleIncomeCategories);
|
||||||
@@ -352,13 +359,7 @@ function getRuleTargetValueDisplayName(rule: ImportTransactionReplaceRule): stri
|
|||||||
case 'account':
|
case 'account':
|
||||||
return getAccountDisplayName(rule.targetId);
|
return getAccountDisplayName(rule.targetId);
|
||||||
case 'tag':
|
case 'tag':
|
||||||
for (const tag of allTags.value) {
|
return allTagsMap.value[rule.targetId]?.name ?? '';
|
||||||
if (tag.id === rule.targetId) {
|
|
||||||
return tag.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,7 @@
|
|||||||
:disabled="loading || removeTag"
|
:disabled="loading || removeTag"
|
||||||
:label="tt('Target Tag')"
|
:label="tt('Target Tag')"
|
||||||
:placeholder="tt('Target Tag')"
|
:placeholder="tt('Target Tag')"
|
||||||
:items="allTags"
|
:items="allTagsWithGroupHeader"
|
||||||
:no-data-text="tt('No available tag')"
|
:no-data-text="tt('No available tag')"
|
||||||
v-model="targetItem"
|
v-model="targetItem"
|
||||||
>
|
>
|
||||||
@@ -176,8 +176,12 @@
|
|||||||
<v-chip :prepend-icon="mdiPound" :text="item.title" v-bind="props"/>
|
<v-chip :prepend-icon="mdiPound" :text="item.title" v-bind="props"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #subheader="{ props }">
|
||||||
|
<v-list-subheader>{{ props['title'] }}</v-list-subheader>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #item="{ props, item }">
|
<template #item="{ props, item }">
|
||||||
<v-list-item :value="item.value" v-bind="props" v-if="!item.raw.hidden">
|
<v-list-item :value="item.value" v-bind="props" v-if="item.raw instanceof TransactionTag && !item.raw.hidden">
|
||||||
<template #title>
|
<template #title>
|
||||||
<v-list-item-title>
|
<v-list-item-title>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
@@ -214,6 +218,7 @@ import SnackBar from '@/components/desktop/SnackBar.vue';
|
|||||||
import { ref, computed, useTemplateRef, watch } from 'vue';
|
import { ref, computed, useTemplateRef, watch } from 'vue';
|
||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { useTransactionTagSelectionBase } from '@/components/base/TransactionTagSelectionBase.ts';
|
||||||
|
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
@@ -224,7 +229,7 @@ import type { NameValue } from '@/core/base.ts';
|
|||||||
import { CategoryType } from '@/core/category.ts';
|
import { CategoryType } from '@/core/category.ts';
|
||||||
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
||||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||||
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getTransactionPrimaryCategoryName,
|
getTransactionPrimaryCategoryName,
|
||||||
@@ -248,6 +253,8 @@ interface BatchReplaceDialogResponse {
|
|||||||
|
|
||||||
const { tt, getCategorizedAccountsWithDisplayBalance } = useI18n();
|
const { tt, getCategorizedAccountsWithDisplayBalance } = useI18n();
|
||||||
|
|
||||||
|
const { allTagsWithGroupHeader } = useTransactionTagSelectionBase({ modelValue: [] }, false);
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const accountsStore = useAccountsStore();
|
const accountsStore = useAccountsStore();
|
||||||
const transactionCategoriesStore = useTransactionCategoriesStore();
|
const transactionCategoriesStore = useTransactionCategoriesStore();
|
||||||
@@ -274,7 +281,6 @@ const allAccounts = computed<Account[]>(() => accountsStore.allPlainAccounts);
|
|||||||
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
|
const allVisibleAccounts = computed<Account[]>(() => accountsStore.allVisiblePlainAccounts);
|
||||||
const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value, customAccountCategoryOrder.value));
|
const allVisibleCategorizedAccounts = computed<CategorizedAccountWithDisplayBalance[]>(() => getCategorizedAccountsWithDisplayBalance(allVisibleAccounts.value, showAccountBalance.value, customAccountCategoryOrder.value));
|
||||||
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
||||||
const allTags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
|
||||||
|
|
||||||
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
||||||
const hasVisibleIncomeCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleIncomeCategories);
|
const hasVisibleIncomeCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleIncomeCategories);
|
||||||
|
|||||||
@@ -265,7 +265,7 @@
|
|||||||
density="compact" variant="plain"
|
density="compact" variant="plain"
|
||||||
:disabled="!!disabled"
|
:disabled="!!disabled"
|
||||||
:placeholder="tt('None')"
|
:placeholder="tt('None')"
|
||||||
:items="allTags"
|
:items="allTagsWithGroupHeader"
|
||||||
:no-data-text="tt('No available tag')"
|
:no-data-text="tt('No available tag')"
|
||||||
v-model="editingTags"
|
v-model="editingTags"
|
||||||
>
|
>
|
||||||
@@ -277,8 +277,12 @@
|
|||||||
v-bind="props"/>
|
v-bind="props"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #subheader="{ props }">
|
||||||
|
<v-list-subheader>{{ props['title'] }}</v-list-subheader>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #item="{ props, item }">
|
<template #item="{ props, item }">
|
||||||
<v-list-item :value="item.value" v-bind="props" v-if="!item.raw.hidden">
|
<v-list-item :value="item.value" v-bind="props" v-if="item.raw instanceof TransactionTag && !item.raw.hidden">
|
||||||
<template #title>
|
<template #title>
|
||||||
<v-list-item-title>
|
<v-list-item-title>
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
@@ -403,6 +407,7 @@ import BatchCreateDialog, { type BatchCreateDialogDataType } from '../dialogs/Ba
|
|||||||
import { ref, computed, useTemplateRef } from 'vue';
|
import { ref, computed, useTemplateRef } from 'vue';
|
||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
import { useTransactionTagSelectionBase } from '@/components/base/TransactionTagSelectionBase.ts';
|
||||||
|
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
@@ -417,7 +422,7 @@ import { TransactionType } from '@/core/transaction.ts';
|
|||||||
|
|
||||||
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
||||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||||
import type { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
import { ImportTransaction } from '@/models/imported_transaction.ts';
|
import { ImportTransaction } from '@/models/imported_transaction.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -503,6 +508,8 @@ const {
|
|||||||
getCategorizedAccountsWithDisplayBalance
|
getCategorizedAccountsWithDisplayBalance
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
|
const { allTagsWithGroupHeader } = useTransactionTagSelectionBase({ modelValue: [] }, false);
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const accountsStore = useAccountsStore();
|
const accountsStore = useAccountsStore();
|
||||||
@@ -551,7 +558,6 @@ const allAccountsMap = computed<Record<string, Account>>(() => accountsStore.all
|
|||||||
const allAccountsMapByName = computed<Record<string, Account>>(() => getAccountMapByName(accountsStore.allAccounts));
|
const allAccountsMapByName = computed<Record<string, Account>>(() => getAccountMapByName(accountsStore.allAccounts));
|
||||||
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
const allCategories = computed<Record<number, TransactionCategory[]>>(() => transactionCategoriesStore.allTransactionCategories);
|
||||||
const allCategoriesMap = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap);
|
const allCategoriesMap = computed<Record<string, TransactionCategory>>(() => transactionCategoriesStore.allTransactionCategoriesMap);
|
||||||
const allTags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
|
||||||
const allTagsMap = computed<Record<string, TransactionTag>>(() => transactionTagsStore.allTransactionTagsMap);
|
const allTagsMap = computed<Record<string, TransactionTag>>(() => transactionTagsStore.allTransactionTagsMap);
|
||||||
|
|
||||||
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
const hasVisibleExpenseCategories = computed<boolean>(() => transactionCategoriesStore.hasVisibleExpenseCategories);
|
||||||
|
|||||||
Reference in New Issue
Block a user