migrate preset dialog to composition API and typescript

This commit is contained in:
MaysWind
2025-01-18 18:11:47 +08:00
parent f22666e756
commit 20e95e35aa
2 changed files with 82 additions and 90 deletions
+5 -4
View File
@@ -167,10 +167,6 @@ export function useI18n() {
const userStore = useUserStore(); const userStore = useUserStore();
// private functions // private functions
function getLanguageInfo(languageKey: string): LanguageInfo | undefined {
return ALL_LANGUAGES[languageKey];
}
function getLanguageDisplayName(languageName: string): string { function getLanguageDisplayName(languageName: string): string {
return t(`language.${languageName}`); return t(`language.${languageName}`);
} }
@@ -950,6 +946,10 @@ export function useI18n() {
return availableExchangeRates; return availableExchangeRates;
} }
function getLanguageInfo(languageKey: string): LanguageInfo | undefined {
return ALL_LANGUAGES[languageKey];
}
function getMonthShortName(monthName: string): string { function getMonthShortName(monthName: string): string {
return t(`datetime.${monthName}.short`); return t(`datetime.${monthName}.short`);
} }
@@ -1337,6 +1337,7 @@ export function useI18n() {
getAllTransactionDefaultCategories, getAllTransactionDefaultCategories,
getAllDisplayExchangeRates, getAllDisplayExchangeRates,
// get localized info // get localized info
getLanguageInfo,
getMonthShortName, getMonthShortName,
getMonthLongName, getMonthLongName,
getMonthdayOrdinal, getMonthdayOrdinal,
@@ -3,7 +3,7 @@
<v-card class="pa-2 pa-sm-4 pa-md-8"> <v-card class="pa-2 pa-sm-4 pa-md-8">
<template #title> <template #title>
<div class="d-flex align-center justify-center"> <div class="d-flex align-center justify-center">
<h4 class="text-h4">{{ $t('Default Categories') }}</h4> <h4 class="text-h4">{{ tt('Default Categories') }}</h4>
</div> </div>
</template> </template>
<v-card-text class="preset-transaction-categories mt-sm-2 mt-md-4 pt-0"> <v-card-text class="preset-transaction-categories mt-sm-2 mt-md-4 pt-0">
@@ -53,11 +53,11 @@
<v-card-text class="overflow-y-visible"> <v-card-text class="overflow-y-visible">
<div class="w-100 d-flex justify-center mt-2 mt-sm-4 mt-md-6 gap-4"> <div class="w-100 d-flex justify-center mt-2 mt-sm-4 mt-md-6 gap-4">
<v-btn :disabled="submitting" @click="save"> <v-btn :disabled="submitting" @click="save">
{{ $t('Save') }} {{ tt('Save') }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular> <v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
</v-btn> </v-btn>
<v-btn color="secondary" density="default" variant="tonal" <v-btn color="secondary" density="default" variant="tonal"
:disabled="submitting" @click="showState = false">{{ $t('Cancel') }}</v-btn> :disabled="submitting" @click="showState = false">{{ tt('Cancel') }}</v-btn>
</div> </div>
</v-card-text> </v-card-text>
</v-card> </v-card>
@@ -66,103 +66,94 @@
<snack-bar ref="snackbar" /> <snack-bar ref="snackbar" />
</template> </template>
<script> <script setup lang="ts">
import { mapStores } from 'pinia'; import SnackBar from '@/components/desktop/SnackBar.vue';
import { ref, computed, useTemplateRef } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts'; import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { CategoryType } from '@/core/category.ts'; import type { PartialRecord } from '@/core/base.ts';
import type { LanguageOption } from '@/locales/index.ts';
import { type LocalizedPresetCategory, CategoryType } from '@/core/category.ts';
import { categorizedArrayToPlainArray } from '@/lib/common.ts'; import { categorizedArrayToPlainArray } from '@/lib/common.ts';
import { type SnackBarType = InstanceType<typeof SnackBar>;
mdiDotsVertical
} from '@mdi/js';
export default { const { tt, getCurrentLanguageTag, getAllLanguageOptions, getAllTransactionDefaultCategories, getLanguageInfo } = useI18n();
props: [
'categoryType',
'persistent',
'show'
],
emits: [
'update:show',
'category:saved'
],
data() {
const self = this;
return { const transactionCategoriesStore = useTransactionCategoriesStore();
currentLocale: self.$locale.getCurrentLanguageTag(),
allCategoryTypes: [], const props = defineProps<{
submitting: false, categoryType: CategoryType;
icons: { persistent?: boolean;
more: mdiDotsVertical show: boolean;
} }>();
};
}, const emit = defineEmits<{
computed: { (e: 'update:show', value: boolean): void;
...mapStores(useTransactionCategoriesStore), (e: 'category:saved', event: { message: string }): void;
showState: { }>();
get: function () {
return this.show; const snackbar = useTemplateRef<SnackBarType>('snackbar');
},
set: function (value) { const currentLocale = ref<string>(getCurrentLanguageTag());
this.$emit('update:show', value); const submitting = ref<boolean>(false);
}
}, const allLanguages = computed<LanguageOption[]>(() => getAllLanguageOptions(false));
allLanguages() { const allPresetCategories = computed<PartialRecord<CategoryType, LocalizedPresetCategory[]>>(() => getAllTransactionDefaultCategories(props.categoryType, currentLocale.value));
return this.$locale.getAllLanguageInfoArray(false);
}, const showState = computed<boolean>({
allPresetCategories() { get: () => props.show,
return this.$locale.getAllTransactionDefaultCategories(this.categoryType, this.currentLocale); set: (value) => emit('update:show', value)
}, });
currentLanguageName() {
const languageInfo = this.$locale.getLanguageInfo(this.currentLocale); const currentLanguageName = computed<string>(() => {
const languageInfo = getLanguageInfo(currentLocale.value);
if (!languageInfo) { if (!languageInfo) {
return ''; return '';
} }
return languageInfo.displayName; return languageInfo.displayName;
});
function getCategoryTypeName(categoryType: CategoryType): string {
switch (categoryType) {
case CategoryType.Income:
return tt('Income Categories');
case CategoryType.Expense:
return tt('Expense Categories');
case CategoryType.Transfer:
return tt('Transfer Categories');
default:
return tt('Transaction Categories');
} }
}, }
methods: {
save() {
const self = this;
self.submitting = true; function save() {
submitting.value = true;
const submitCategories = categorizedArrayToPlainArray(self.allPresetCategories); const submitCategories = categorizedArrayToPlainArray(allPresetCategories.value);
self.transactionCategoriesStore.addCategories({ transactionCategoriesStore.addCategories({
categories: submitCategories categories: submitCategories
}).then(() => { }).then(() => {
self.submitting = false; submitting.value = false;
self.showState = false; showState.value = false;
this.$emit('category:saved', { emit('category:saved', {
message: 'You have added preset categories' message: 'You have added preset categories'
}); });
}).catch(error => { }).catch(error => {
self.submitting = false; submitting.value = false;
if (!error.processed) { if (!error.processed) {
self.$refs.snackbar.showError(error); snackbar.value?.showError(error);
} }
}); });
},
getCategoryTypeName(categoryType) {
switch (categoryType) {
case CategoryType.Income.toString():
return this.$t('Income Categories');
case CategoryType.Expense.toString():
return this.$t('Expense Categories');
case CategoryType.Transfer.toString():
return this.$t('Transfer Categories');
default:
return this.$t('Transaction Categories');
}
}
}
} }
</script> </script>