add category preset for desktop page

This commit is contained in:
MaysWind
2023-08-04 00:56:47 +08:00
parent 19d3d80013
commit 7e24492ce8
2 changed files with 182 additions and 3 deletions
@@ -106,7 +106,7 @@
<div class="d-flex align-center">
<span>{{ $t('No available category') }}</span>
<v-btn class="ml-3" color="default" variant="outlined"
@click="showPresetCategories"
@click="showPresetDialog = true"
v-if="hasSubCategories && noCategory">
{{ $t('Add Default Categories') }}
</v-btn>
@@ -178,11 +178,16 @@
</v-col>
</v-row>
<preset-category-dialog :category-type="activeCategoryType" v-model:show="showPresetDialog"
@category:saved="presetCategorySaved" />
<confirm-dialog ref="confirmDialog"/>
<snack-bar ref="snackbar" />
</template>
<script>
import PresetCategoryDialog from './categories/PresetCategoryDialog.vue';
import { mapStores } from 'pinia';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.js';
@@ -199,6 +204,9 @@ import {
} from '@mdi/js';
export default {
components: {
PresetCategoryDialog
},
data() {
return {
activeCategoryType: categoryConstants.allCategoryTypes.Expense,
@@ -210,6 +218,7 @@ export default {
categoryRemoving: {},
displayOrderModified: false,
showHidden: false,
showPresetDialog: false,
icons: {
refresh: mdiRefresh,
edit: mdiPencilOutline,
@@ -395,8 +404,11 @@ export default {
});
});
},
showPresetCategories() {
presetCategorySaved(e) {
if (e && e.message) {
this.$refs.snackbar.showMessage(e.message);
this.reload(false);
}
},
switchActiveCategoryType(activeCategoryType) {
if (this.activeCategoryType === activeCategoryType) {
@@ -0,0 +1,167 @@
<template>
<v-dialog scrollable width="600" max-height="600" :persistent="!!persistent" v-model="showState">
<v-card>
<v-toolbar color="primary">
<v-toolbar-title>{{ $t('Default Categories') }}</v-toolbar-title>
</v-toolbar>
<v-card-text class="preset-transaction-categories pb-4">
<template :key="categoryType" v-for="(categories, categoryType) in allPresetCategories">
<div class="d-flex align-center mb-1">
<h4>{{ getCategoryTypeName(categoryType) }}</h4>
<v-spacer/>
<v-menu location="bottom">
<template #activator="{ props }">
<v-btn variant="text" :disabled="submitting"
v-bind="props">{{ currentLanguageName }}</v-btn>
</template>
<v-list>
<v-list-item :key="locale" :value="locale" v-for="(lang, locale) in allLanguages">
<v-list-item-title class="cursor-pointer" @click="currentLocale = locale">
{{ lang.displayName }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
<v-expansion-panels class="border rounded mb-2" variant="accordion" multiple :disabled="submitting">
<v-expansion-panel :key="idx" v-for="(category, idx) in categories">
<v-expansion-panel-title class="py-0">
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
<span class="ml-3">{{ category.name }}</span>
</v-expansion-panel-title>
<v-expansion-panel-text v-if="category.subCategories.length">
<v-list rounded density="comfortable" class="pa-0">
<template :key="subIdx"
v-for="(subCategory, subIdx) in category.subCategories">
<v-list-item>
<template #prepend>
<ItemIcon icon-type="category" :icon-id="subCategory.icon" :color="subCategory.color"></ItemIcon>
</template>
<span class="ml-3">{{ subCategory.name }}</span>
</v-list-item>
<v-divider v-if="subIdx !== category.subCategories.length - 1"/>
</template>
</v-list>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</template>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="gray" :disabled="submitting" @click="showState = false">{{ $t('Cancel') }}</v-btn>
<v-btn :disabled="submitting" @click="save">
{{ $t('Save') }}
<v-progress-circular indeterminate size="24" class="ml-2" v-if="submitting"></v-progress-circular>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import { mapStores } from 'pinia';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.js';
import categoryConstants from '@/consts/category.js';
import { categoriedArrayToPlainArray } from '@/lib/common.js';
import {
mdiDotsVertical
} from '@mdi/js';
export default {
props: [
'categoryType',
'persistent',
'show'
],
emits: [
'update:show',
'category:saved'
],
data() {
const self = this;
return {
currentLocale: self.$locale.getCurrentLanguageCode(),
allCategoryTypes: [],
submitting: false,
icons: {
more: mdiDotsVertical
}
};
},
computed: {
...mapStores(useTransactionCategoriesStore),
showState: {
get: function () {
return this.show;
},
set: function (value) {
this.$emit('update:show', value);
}
},
allLanguages() {
return this.$locale.getAllLanguageInfos();
},
allPresetCategories() {
return this.$locale.getAllTransactionDefaultCategories(this.categoryType, this.currentLocale);
},
currentLanguageName() {
const languageInfo = this.$locale.getLanguageInfo(this.currentLocale);
if (!languageInfo) {
return '';
}
return languageInfo.displayName;
}
},
methods: {
save() {
const self = this;
self.submitting = true;
const submitCategories = categoriedArrayToPlainArray(self.allPresetCategories);
self.transactionCategoriesStore.addCategories({
categories: submitCategories
}).then(() => {
self.submitting = false;
self.showState = false;
this.$emit('category:saved', {
message: 'You have added preset categories'
});
}).catch(error => {
self.submitting = false;
if (!error.processed) {
self.$refs.snackbar.showError(error);
}
});
},
getCategoryTypeName(categoryType) {
switch (categoryType) {
case categoryConstants.allCategoryTypes.Income.toString():
return this.$t('Income Categories');
case categoryConstants.allCategoryTypes.Expense.toString():
return this.$t('Expense Categories');
case categoryConstants.allCategoryTypes.Transfer.toString():
return this.$t('Transfer Categories');
default:
return this.$t('Transaction Categories');
}
}
}
}
</script>
<style>
.preset-transaction-categories .v-expansion-panel-text__wrapper {
padding: 0 0 0 20px;
}
</style>