support changing primary category for transaction category

This commit is contained in:
MaysWind
2024-06-23 23:37:58 +08:00
parent 9627e65d6d
commit 0e391bee50
12 changed files with 166 additions and 28 deletions
+14
View File
@@ -116,6 +116,20 @@ export function allVisibleTransactionCategories(allTransactionCategories) {
return ret;
}
export function allVisiblePrimaryTransactionCategoriesByType(allTransactionCategories, type) {
const allVisibleCategories = allVisibleTransactionCategories(allTransactionCategories);
if (!allVisibleCategories) {
return [];
}
if (!allVisibleCategories[type.toString()]) {
return [];
}
return allVisibleCategories[type.toString()].visibleCategories;
}
export function isSubCategoryIdAvailable(categories, categoryId) {
if (!categories || !categories.length) {
return false;
+2 -1
View File
@@ -436,10 +436,11 @@ export default {
categories
});
},
modifyTransactionCategory: ({ id, name, icon, color, comment, hidden }) => {
modifyTransactionCategory: ({ id, name, parentId, icon, color, comment, hidden }) => {
return axios.post('v1/transaction/categories/modify.json', {
id,
name,
parentId,
icon,
color,
comment,
+6
View File
@@ -648,6 +648,10 @@ export default {
'cannot add to secondary transaction category': 'Cannot add transaction category to secondary transaction category',
'cannot use primary category for transaction category': 'Cannot use primary category for transaction category',
'transaction category is in use and cannot be deleted': 'Transaction category is in use and it cannot be deleted',
'not allow to change primary category to secondary category': 'Not allow to change primary category to secondary category',
'not allow to change secondary category to primary category': 'Not allow to change secondary category to primary category',
'not allow to change primary category with different type': 'Not allow to change primary category with different type',
'not allow to use secondary category as primary category': 'Not allow to use secondary category as primary category',
'transaction tag id is invalid': 'Transaction tag ID is invalid',
'transaction tag not found': 'Transaction tag is not found',
'transaction tag name is empty': 'Transaction tag title is empty',
@@ -1153,6 +1157,7 @@ export default {
'Unable to unhide this category': 'Unable to unhide this category',
'Are you sure you want to delete this category?': 'Are you sure you want to delete this category?',
'Unable to delete this category': 'Unable to delete this category',
'Primary Category': 'Primary Category',
'Add Primary Category': 'Add Primary Category',
'Add Secondary Category': 'Add Secondary Category',
'Edit Category': 'Edit Category',
@@ -1161,6 +1166,7 @@ export default {
'Category Icon': 'Category Icon',
'Category Color': 'Category Color',
'Your category description (optional)': 'Your category description (optional)',
'No available primary category': 'No available primary category',
'Category name cannot be blank': 'Category name cannot be blank',
'Unable to retrieve category': 'Unable to retrieve category',
'Unable to add category': 'Unable to add category',
+6
View File
@@ -648,6 +648,10 @@ export default {
'cannot add to secondary transaction category': '不能在二级交易分类中添加',
'cannot use primary category for transaction category': '交易分类不能使用一级分类',
'transaction category is in use and cannot be deleted': '交易分类正在被使用,无法删除',
'not allow to change primary category to secondary category': '不允许更改一级分类为二级分类',
'not allow to change secondary category to primary category': '不允许更改二级分类为一级分类',
'not allow to change primary category with different type': '不允许更改为不同类型的一级分类',
'not allow to use secondary category as primary category': '不允许使用二级分类作为一级分类',
'transaction tag id is invalid': '交易标签ID无效',
'transaction tag not found': '交易标签不存在',
'transaction tag name is empty': '交易标签标题不能为空',
@@ -1153,6 +1157,7 @@ export default {
'Unable to unhide this category': '无法取消隐藏该分类',
'Are you sure you want to delete this category?': '您确定要删除该分类?',
'Unable to delete this category': '无法删除该分类',
'Primary Category': '一级分类',
'Add Primary Category': '添加一级分类',
'Add Secondary Category': '添加二级分类',
'Edit Category': '编辑分类',
@@ -1161,6 +1166,7 @@ export default {
'Category Icon': '分类图标',
'Category Color': '分类颜色',
'Your category description (optional)': '你的分类描述 (可选)',
'No available primary category': '没有可用一级分类',
'Category name cannot be blank': '分类名称不能为空',
'Unable to retrieve category': '无法获取分类',
'Unable to add category': '无法添加分类',
+11 -2
View File
@@ -46,7 +46,11 @@ function addCategoryToTransactionCategoryList(state, category) {
state.allTransactionCategoriesMap[category.id] = category;
}
function updateCategoryInTransactionCategoryList(state, category) {
function updateCategoryInTransactionCategoryList(state, category, oldCategory) {
if (oldCategory && category.parentId !== oldCategory.parentId) {
return false;
}
let categoryList = null;
if (!category.parentId || category.parentId === '0') {
@@ -65,6 +69,7 @@ function updateCategoryInTransactionCategoryList(state, category) {
}
state.allTransactionCategoriesMap[category.id] = category;
return true;
}
function updateCategoryDisplayOrderInCategoryList(state, { category, from, to }) {
@@ -293,7 +298,11 @@ export const useTransactionCategoriesStore = defineStore('transactionCategories'
if (!submitCategory.id) {
addCategoryToTransactionCategoryList(self, data.result);
} else {
updateCategoryInTransactionCategoryList(self, data.result);
const result = updateCategoryInTransactionCategoryList(self, data.result, self.allTransactionCategoriesMap[submitCategory.id]);
if (!result && !self.transactionCategoryListStateInvalid) {
self.updateTransactionCategoryListInvalidState(true);
}
}
resolve(data.result);
@@ -414,6 +414,10 @@ export default {
self.$refs.snackbar.showMessage(result.message);
}
if (self.transactionCategoriesStore.transactionCategoryListStateInvalid) {
self.reload(true);
}
self.updateCardMinHeight();
}).catch(error => {
if (error) {
@@ -21,6 +21,31 @@
v-model="category.name"
/>
</v-col>
<v-col cols="12" md="12" v-if="editCategoryId && category.parentId && category.parentId !== '0'">
<v-select
item-title="name"
item-value="id"
persistent-placeholder
:disabled="loading || submitting"
:label="$t('Primary Category')"
:placeholder="$t('Primary Category')"
:items="allAvailableCategories"
:no-data-text="$t('No available primary category')"
v-model="category.parentId"
>
<template #item="{ props, item }">
<v-list-item v-bind="props">
<template #prepend>
<ItemIcon class="mr-2" icon-type="category"
:icon-id="item.raw.icon" :color="item.raw.color"></ItemIcon>
</template>
<template #title>
<div class="text-truncate">{{ item.raw.name }}</div>
</template>
</v-list-item>
</template>
</v-select>
</v-col>
<v-col cols="12" md="6">
<icon-select icon-type="category"
:all-icon-infos="allCategoryIcons"
@@ -76,7 +101,10 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.js';
import categoryConstants from '@/consts/category.js';
import iconConstants from '@/consts/icon.js';
import colorConstants from '@/consts/color.js';
import { setCategoryModelByAnotherCategory } from '@/lib/category.js';
import {
setCategoryModelByAnotherCategory,
allVisiblePrimaryTransactionCategoriesByType
} from '@/lib/category.js';
export default {
props: [
@@ -102,6 +130,9 @@ export default {
},
computed: {
...mapStores(useTransactionCategoriesStore),
allAvailableCategories() {
return allVisiblePrimaryTransactionCategoriesByType(this.transactionCategoriesStore.allTransactionCategories, this.category.type);
},
title() {
if (!this.editCategoryId) {
if (this.category.parentId === '0') {
+30 -1
View File
@@ -10,6 +10,7 @@
<f7-list strong inset dividers class="margin-top skeleton-text" v-if="loading">
<f7-list-input label="Category Name" placeholder="Your category name"></f7-list-input>
<f7-list-item class="list-item-with-header-and-title" header="Primary Category" title="Primary Category"></f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-with-multi-item">
<template #default>
<div class="grid grid-cols-2">
@@ -61,6 +62,23 @@
v-model:value="category.name"
></f7-list-input>
<f7-list-item
link="#" no-chevron
class="list-item-with-header-and-title"
:header="$t('Primary Category')"
:title="getPrimaryCategoryName(category.parentId)"
@click="showPrimaryCategorySheet = true"
v-if="editCategoryId && category.parentId && category.parentId !== '0'"
>
<list-item-selection-sheet value-type="item"
key-field="id" value-field="id" title-field="name"
icon-field="icon" icon-type="category" color-field="color"
:items="allAvailableCategories"
v-model:show="showPrimaryCategorySheet"
v-model="category.parentId">
</list-item-selection-sheet>
</f7-list-item>
<f7-list-item class="list-item-with-header-and-title list-item-with-multi-item">
<template #default>
<div class="grid grid-cols-2">
@@ -134,7 +152,11 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.js';
import categoryConstants from '@/consts/category.js';
import iconConstants from '@/consts/icon.js';
import colorConstants from '@/consts/color.js';
import { setCategoryModelByAnotherCategory } from '@/lib/category.js';
import {
setCategoryModelByAnotherCategory,
allVisiblePrimaryTransactionCategoriesByType
} from '@/lib/category.js';
import {getNameByKeyValue} from "@/lib/common";
export default {
props: [
@@ -153,11 +175,15 @@ export default {
loading: false,
loadingError: null,
category: newTransactionCategory,
showPrimaryCategorySheet: false,
submitting: false
};
},
computed: {
...mapStores(useTransactionCategoriesStore),
allAvailableCategories() {
return allVisiblePrimaryTransactionCategoriesByType(this.transactionCategoriesStore.allTransactionCategories, this.category.type);
},
title() {
if (!this.editCategoryId) {
if (this.category.parentId === '0') {
@@ -274,6 +300,9 @@ export default {
self.$toast(error.message || error);
}
});
},
getPrimaryCategoryName(parentId) {
return getNameByKeyValue(this.allAvailableCategories, parentId, 'id', 'name');
}
}
}