mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-19 17:24:26 +08:00
migrate preset dialog to composition API and typescript
This commit is contained in:
@@ -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: [],
|
|
||||||
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.getAllLanguageInfoArray(false);
|
|
||||||
},
|
|
||||||
allPresetCategories() {
|
|
||||||
return this.$locale.getAllTransactionDefaultCategories(this.categoryType, this.currentLocale);
|
|
||||||
},
|
|
||||||
currentLanguageName() {
|
|
||||||
const languageInfo = this.$locale.getLanguageInfo(this.currentLocale);
|
|
||||||
|
|
||||||
if (!languageInfo) {
|
const props = defineProps<{
|
||||||
return '';
|
categoryType: CategoryType;
|
||||||
}
|
persistent?: boolean;
|
||||||
|
show: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
return languageInfo.displayName;
|
const emit = defineEmits<{
|
||||||
}
|
(e: 'update:show', value: boolean): void;
|
||||||
},
|
(e: 'category:saved', event: { message: string }): void;
|
||||||
methods: {
|
}>();
|
||||||
save() {
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
self.submitting = true;
|
const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||||
|
|
||||||
const submitCategories = categorizedArrayToPlainArray(self.allPresetCategories);
|
const currentLocale = ref<string>(getCurrentLanguageTag());
|
||||||
|
const submitting = ref<boolean>(false);
|
||||||
|
|
||||||
self.transactionCategoriesStore.addCategories({
|
const allLanguages = computed<LanguageOption[]>(() => getAllLanguageOptions(false));
|
||||||
categories: submitCategories
|
const allPresetCategories = computed<PartialRecord<CategoryType, LocalizedPresetCategory[]>>(() => getAllTransactionDefaultCategories(props.categoryType, currentLocale.value));
|
||||||
}).then(() => {
|
|
||||||
self.submitting = false;
|
|
||||||
self.showState = false;
|
|
||||||
|
|
||||||
this.$emit('category:saved', {
|
const showState = computed<boolean>({
|
||||||
message: 'You have added preset categories'
|
get: () => props.show,
|
||||||
});
|
set: (value) => emit('update:show', value)
|
||||||
}).catch(error => {
|
});
|
||||||
self.submitting = false;
|
|
||||||
|
|
||||||
if (!error.processed) {
|
const currentLanguageName = computed<string>(() => {
|
||||||
self.$refs.snackbar.showError(error);
|
const languageInfo = getLanguageInfo(currentLocale.value);
|
||||||
}
|
|
||||||
});
|
if (!languageInfo) {
|
||||||
},
|
return '';
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
submitting.value = true;
|
||||||
|
|
||||||
|
const submitCategories = categorizedArrayToPlainArray(allPresetCategories.value);
|
||||||
|
|
||||||
|
transactionCategoriesStore.addCategories({
|
||||||
|
categories: submitCategories
|
||||||
|
}).then(() => {
|
||||||
|
submitting.value = false;
|
||||||
|
showState.value = false;
|
||||||
|
|
||||||
|
emit('category:saved', {
|
||||||
|
message: 'You have added preset categories'
|
||||||
|
});
|
||||||
|
}).catch(error => {
|
||||||
|
submitting.value = false;
|
||||||
|
|
||||||
|
if (!error.processed) {
|
||||||
|
snackbar.value?.showError(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user