From 8fce3f2bcc1ce98c3f50878f5c7e9de43a5f7db3 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Fri, 24 Jan 2025 00:42:37 +0800 Subject: [PATCH] migrate account edit page to composition API and typescript --- src/components/desktop/AmountInput.vue | 2 +- .../base/accounts/AccountEditPageBase.ts | 182 +++++ .../accounts/list/dialogs/EditDialog.vue | 557 +++++++--------- src/views/mobile/accounts/EditPage.vue | 629 +++++++----------- 4 files changed, 666 insertions(+), 704 deletions(-) create mode 100644 src/views/base/accounts/AccountEditPageBase.ts diff --git a/src/components/desktop/AmountInput.vue b/src/components/desktop/AmountInput.vue index ff2981b8..cde42e14 100644 --- a/src/components/desktop/AmountInput.vue +++ b/src/components/desktop/AmountInput.vue @@ -43,7 +43,7 @@ const props = defineProps<{ class?: string; color?: string; density?: string; - currency: string; + currency?: string; showCurrency?: boolean; label?: string; placeholder?: string; diff --git a/src/views/base/accounts/AccountEditPageBase.ts b/src/views/base/accounts/AccountEditPageBase.ts new file mode 100644 index 00000000..9ea3a8c3 --- /dev/null +++ b/src/views/base/accounts/AccountEditPageBase.ts @@ -0,0 +1,182 @@ +import { ref, computed, watch } from 'vue'; + +import { useI18n } from '@/locales/helpers.ts'; + +import { useAccountsStore } from '@/stores/account.ts'; + +import type { TypeAndDisplayName } from '@/core/base.ts'; +import { AccountCategory, AccountType } from '@/core/account.ts'; +import type { LocalizedCurrencyInfo } from '@/core/currency.ts'; +import type { LocalizedAccountCategory } from '@/core/account.ts'; +import type { Account } from '@/models/account.ts'; + +import { setAccountSuitableIcon } from '@/lib/account.ts'; + +export interface DayAndDisplayName { + readonly day: number; + readonly displayName: string; +} + +export function useAccountEditPageBaseBase() { + const { tt, getAllCurrencies, getAllAccountCategories, getAllAccountTypes, getMonthdayShortName } = useI18n(); + const accountsStore = useAccountsStore(); + + const editAccountId = ref(null); + const clientSessionId = ref(''); + const loading = ref(false); + const submitting = ref(false); + const account = ref(accountsStore.generateNewAccountModel()); + const subAccounts = ref([]); + + const title = computed(() => { + if (!editAccountId.value) { + return 'Add Account'; + } else { + return 'Edit Account'; + } + }); + + const saveButtonTitle = computed(() => { + if (!editAccountId.value) { + return 'Add'; + } else { + return 'Save'; + } + }); + + const allAccountCategories = computed(() => getAllAccountCategories()); + const allAccountTypes = computed(() => getAllAccountTypes()); + const allCurrencies = computed(() => getAllCurrencies()); + + const allAvailableMonthDays = computed(() => { + const allAvailableDays: DayAndDisplayName[] = []; + + allAvailableDays.push({ + day: 0, + displayName: tt('Not set'), + }); + + for (let i = 1; i <= 28; i++) { + allAvailableDays.push({ + day: i, + displayName: getMonthdayShortName(i), + }); + } + + return allAvailableDays; + }); + + const isAccountSupportCreditCardStatementDate = computed(() => account.value && account.value.category === AccountCategory.CreditCard.type); + + function getAccountCreditCardStatementDate(statementDate?: number): string | null { + for (const item of allAvailableMonthDays.value) { + if (item.day === statementDate) { + return item.displayName; + } + } + + return null; + } + + function getInputEmptyProblemMessage(account: Account, isSubAccount: boolean): string | null { + if (!isSubAccount && !account.category) { + return 'Account category cannot be blank'; + } else if (!isSubAccount && !account.type) { + return 'Account type cannot be blank'; + } else if (!account.name) { + return 'Account name cannot be blank'; + } else if (account.type === AccountType.SingleAccount.type && !account.currency) { + return 'Account currency cannot be blank'; + } else { + return null; + } + } + + function isInputEmpty(): boolean { + const isAccountEmpty = !!getInputEmptyProblemMessage(account.value, false); + + if (isAccountEmpty) { + return true; + } + + if (account.value.type === AccountType.MultiSubAccounts.type) { + for (let i = 0; i < subAccounts.value.length; i++) { + const isSubAccountEmpty = !!getInputEmptyProblemMessage(subAccounts.value[i], true); + + if (isSubAccountEmpty) { + return true; + } + } + } + + return false; + } + + function getAccountOrSubAccountProblemMessage(): string | null { + let problemMessage = getInputEmptyProblemMessage(account.value, false); + + if (!problemMessage && account.value.type === AccountType.MultiSubAccounts.type) { + for (let i = 0; i < subAccounts.value.length; i++) { + problemMessage = getInputEmptyProblemMessage(subAccounts.value[i], true); + + if (problemMessage) { + break; + } + } + } + + return problemMessage; + } + + function addSubAccount(): boolean { + if (account.value.type !== AccountType.MultiSubAccounts.type) { + return false; + } + + const subAccount = accountsStore.generateNewSubAccountModel(account.value); + subAccounts.value.push(subAccount); + return true; + } + + function setAccount(newAccount: Account): void { + account.value.from(newAccount); + subAccounts.value = []; + + if (newAccount.childrenAccounts && newAccount.childrenAccounts.length > 0) { + for (let i = 0; i < newAccount.childrenAccounts.length; i++) { + const subAccount = accountsStore.generateNewSubAccountModel(account.value); + subAccount.from(newAccount.childrenAccounts[i]); + + subAccounts.value.push(subAccount); + } + } + } + + watch(() => account.value.category, (newValue, oldValue) => { + setAccountSuitableIcon(account.value, oldValue, newValue); + }); + + return { + // states + editAccountId, + clientSessionId, + loading, + submitting, + account, + subAccounts, + // computed states + title, + saveButtonTitle, + allAccountCategories, + allAccountTypes, + allCurrencies, + allAvailableMonthDays, + isAccountSupportCreditCardStatementDate, + // functions + getAccountCreditCardStatementDate, + isInputEmpty, + getAccountOrSubAccountProblemMessage, + addSubAccount, + setAccount + }; +} diff --git a/src/views/desktop/accounts/list/dialogs/EditDialog.vue b/src/views/desktop/accounts/list/dialogs/EditDialog.vue index 3a2ef86a..6600f2f1 100644 --- a/src/views/desktop/accounts/list/dialogs/EditDialog.vue +++ b/src/views/desktop/accounts/list/dialogs/EditDialog.vue @@ -1,19 +1,19 @@