migrate amount filter page to composition API and typescript

This commit is contained in:
MaysWind
2025-01-20 22:04:37 +08:00
parent fb367174b6
commit 9d9e6ef9bd
2 changed files with 127 additions and 138 deletions
+11 -7
View File
@@ -1188,7 +1188,7 @@ export function useI18n() {
return formatAmount(value, numberFormatOptions); return formatAmount(value, numberFormatOptions);
} }
function getFormattedAmountWithCurrency(value: number | string, currencyCode?: string, notConvertValue?: boolean, currencyDisplayType?: CurrencyDisplayType): string | null { function getFormattedAmountWithCurrency(value: number | string, currencyCode?: string | false, notConvertValue?: boolean, currencyDisplayType?: CurrencyDisplayType): string | null {
if (!isNumber(value) && !isString(value)) { if (!isNumber(value) && !isString(value)) {
return null; return null;
} }
@@ -1215,13 +1215,17 @@ export function useI18n() {
} }
} }
let finalCurrencyCode = '';
if (!isBoolean(currencyCode) && !currencyCode) { if (!isBoolean(currencyCode) && !currencyCode) {
currencyCode = userStore.currentUserDefaultCurrency; finalCurrencyCode = userStore.currentUserDefaultCurrency;
} else if (isBoolean(currencyCode) && !currencyCode) { } else if (isBoolean(currencyCode) && !currencyCode) {
currencyCode = ''; finalCurrencyCode = '';
} else {
finalCurrencyCode = currencyCode;
} }
if (!currencyCode) { if (!finalCurrencyCode) {
return textualValue; return textualValue;
} }
@@ -1229,9 +1233,9 @@ export function useI18n() {
currencyDisplayType = getCurrentCurrencyDisplayType(); currencyDisplayType = getCurrentCurrencyDisplayType();
} }
const currencyUnit = getCurrencyUnitName(currencyCode, isPlural); const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
const currencyName = getCurrencyName(currencyCode); const currencyName = getCurrencyName(finalCurrencyCode);
return appendCurrencySymbol(textualValue, currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural); return appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
} }
function getFormattedExchangeRateAmount(value: number | string): string { function getFormattedExchangeRateAmount(value: number | string): string {
+116 -131
View File
@@ -1,10 +1,10 @@
<template> <template>
<f7-page @page:afterin="onPageAfterIn"> <f7-page>
<f7-navbar> <f7-navbar>
<f7-nav-left :back-link="$t('Back')"></f7-nav-left> <f7-nav-left :back-link="tt('Back')"></f7-nav-left>
<f7-nav-title :title="$t('Filter Amount')"></f7-nav-title> <f7-nav-title :title="tt('Filter Amount')"></f7-nav-title>
<f7-nav-right> <f7-nav-right>
<f7-link :text="$t('Apply')" @click="confirm"></f7-link> <f7-link :text="tt('Apply')" @click="confirm"></f7-link>
</f7-nav-right> </f7-nav-right>
</f7-navbar> </f7-navbar>
@@ -13,11 +13,11 @@
class="ebk-small-amount" class="ebk-small-amount"
link="#" no-chevron link="#" no-chevron
:header="amount1Header" :header="amount1Header"
:title="getDisplayAmount(amount1)" :title="formatAmountWithCurrency(amount1)"
@click="showAmount1Sheet = true" @click="showAmount1Sheet = true"
> >
<number-pad-sheet :min-value="allowedMinAmount" <number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
:max-value="allowedMaxAmount" :max-value="TRANSACTION_MAX_AMOUNT"
v-model:show="showAmount1Sheet" v-model:show="showAmount1Sheet"
v-model="amount1" v-model="amount1"
></number-pad-sheet> ></number-pad-sheet>
@@ -27,12 +27,12 @@
class="ebk-small-amount" class="ebk-small-amount"
link="#" no-chevron link="#" no-chevron
:header="amount2Header" :header="amount2Header"
:title="getDisplayAmount(amount2)" :title="formatAmountWithCurrency(amount2)"
@click="showAmount2Sheet = true" @click="showAmount2Sheet = true"
v-if="amountCount === 2" v-if="amountCount === 2"
> >
<number-pad-sheet :min-value="allowedMinAmount" <number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
:max-value="allowedMaxAmount" :max-value="TRANSACTION_MAX_AMOUNT"
v-model:show="showAmount2Sheet" v-model:show="showAmount2Sheet"
v-model="amount2" v-model="amount2"
></number-pad-sheet> ></number-pad-sheet>
@@ -40,8 +40,8 @@
</f7-list> </f7-list>
<f7-list form strong inset dividers class="margin-vertical"> <f7-list form strong inset dividers class="margin-vertical">
<f7-list-item :key="filterType.type" :title="$t(filterType.name)" <f7-list-item :key="filterType.type" :title="tt(filterType.name)"
v-for="filterType in allAmountFilterTypes" v-for="filterType in AmountFilterType.values()"
@click="type = filterType.type"> @click="type = filterType.type">
<template #after> <template #after>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="type === filterType.type"></f7-icon> <f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="type === filterType.type"></f7-icon>
@@ -51,10 +51,13 @@
</f7-page> </f7-page>
</template> </template>
<script> <script setup lang="ts">
import { mapStores } from 'pinia'; import { ref, computed } from 'vue';
import { useSettingsStore } from '@/stores/setting.ts'; import type { Router } from 'framework7/types';
import { useUserStore } from '@/stores/user.ts';
import { useI18n } from '@/locales/helpers.ts';
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
import { useTransactionsStore } from '@/stores/transaction.js'; import { useTransactionsStore } from '@/stores/transaction.js';
import { AmountFilterType } from '@/core/numeral.ts'; import { AmountFilterType } from '@/core/numeral.ts';
@@ -62,123 +65,105 @@ import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transac
import { isString } from '@/lib/common.ts'; import { isString } from '@/lib/common.ts';
import logger from '@/lib/logger.ts'; import logger from '@/lib/logger.ts';
export default { const props = defineProps<{
props: [ f7route: Router.Route;
'f7route', f7router: Router.Router;
'f7router' }>();
],
data() { const type = ref<string>('');
return { const amount1 = ref<number>(0);
type: '', const amount2 = ref<number>(0);
amount1: 0, const showAmount1Sheet = ref<boolean>(false);
amount2: 0, const showAmount2Sheet = ref<boolean>(false);
showAmount1Sheet: false,
showAmount2Sheet: false const { tt, formatAmountWithCurrency } = useI18n();
} const { showToast } = useI18nUIComponents();
},
computed: { const transactionsStore = useTransactionsStore();
...mapStores(useSettingsStore, useUserStore, useTransactionsStore),
allAmountFilterTypes() { const amountCount = computed<number>(() => getAmountFilterParameterCount(type.value));
return AmountFilterType.values();
}, const amount1Header = computed<string>(() => {
allowedMinAmount() { if (type.value === AmountFilterType.GreaterThan.type
return TRANSACTION_MIN_AMOUNT; || type.value === AmountFilterType.Between.type
}, || type.value === AmountFilterType.NotBetween.type) {
allowedMaxAmount() { return tt('Minimum Amount');
return TRANSACTION_MAX_AMOUNT; } else if (type.value === AmountFilterType.LessThan.type) {
}, return tt('Maximum Amount');
amountCount() { } else {
return this.getAmountFilterParameterCount(this.type); return tt('Amount');
}, }
title() { });
const amountFilterType = AmountFilterType.valueOf(this.type);
return amountFilterType ? this.$t(amountFilterType.name) : this.$t('Amount'); const amount2Header = computed<string>(() => {
}, if (type.value === AmountFilterType.Between.type) {
amount1Header() { return tt('Maximum Amount');
if (this.type === AmountFilterType.GreaterThan.type } else if (type.value === AmountFilterType.NotBetween.type) {
|| this.type === AmountFilterType.Between.type return tt('Maximum Amount');
|| this.type === AmountFilterType.NotBetween.type) { } else {
return this.$t('Minimum Amount'); return tt('Amount');
} else if (this.type === AmountFilterType.LessThan.type) { }
return this.$t('Maximum Amount'); });
} else {
return this.$t('Amount'); function getAmountFilterParameterCount(filterType: string): number {
const amountFilterType = AmountFilterType.valueOf(filterType);
return amountFilterType ? amountFilterType.paramCount : 0;
}
function init(): void {
const query = props.f7route.query;
type.value = query['type'] || '';
let queryAmount1 = 0, queryAmount2 = 0;
if (isString(query['value'])) {
try {
const filterItems = query['value'].split(':');
const amountCount = getAmountFilterParameterCount(filterItems[0]);
if (filterItems.length === 2 && amountCount === 1) {
queryAmount1 = parseInt(filterItems[1]);
} else if (filterItems.length === 3 && amountCount === 2) {
queryAmount1 = parseInt(filterItems[1]);
queryAmount2 = parseInt(filterItems[2]);
} }
}, } catch (ex) {
amount2Header() { logger.warn('cannot parse amount from filter value, original value is ' + query['value'], ex);
if (this.type === AmountFilterType.Between.type) {
return this.$t('Maximum Amount');
} else if (this.type === AmountFilterType.NotBetween.type) {
return this.$t('Maximum Amount');
} else {
return this.$t('Amount');
}
}
},
created() {
const query = this.f7route.query;
this.type = query.type;
let amount1 = 0, amount2 = 0;
if (isString(query.value)) {
try {
const filterItems = query.value.split(':');
const amountCount = this.getAmountFilterParameterCount(filterItems[0]);
if (filterItems.length === 2 && amountCount === 1) {
amount1 = parseInt(filterItems[1]);
} else if (filterItems.length === 3 && amountCount === 2) {
amount1 = parseInt(filterItems[1]);
amount2 = parseInt(filterItems[2]);
}
} catch (ex) {
logger.warn('cannot parse amount from filter value, original value is ' + query.value, ex);
}
}
this.amount1 = amount1;
this.amount2 = amount2;
},
methods: {
onPageAfterIn() {
this.$routeBackOnError(this.f7router, 'loadingError');
},
confirm() {
const router = this.f7router;
let amountFilter = this.type;
if (this.amountCount === 1) {
amountFilter += ':' + this.amount1;
} else if (this.amountCount === 2) {
if (this.amount2 < this.amount1) {
this.$toast('Incorrect amount range');
return;
}
amountFilter += ':' + this.amount1 + ':' + this.amount2;
} else {
router.back();
return;
}
const changed = this.transactionsStore.updateTransactionListFilter({
amountFilter: amountFilter
});
if (changed) {
this.transactionsStore.updateTransactionListInvalidState(true);
}
router.back();
},
getDisplayAmount(value) {
return this.$locale.formatAmountWithCurrency(this.settingsStore, this.userStore, value, false);
},
getAmountFilterParameterCount(filterType) {
const amountFilterType = AmountFilterType.valueOf(filterType);
return amountFilterType ? amountFilterType.paramCount : 0;
} }
} }
amount1.value = queryAmount1;
amount2.value = queryAmount2;
} }
function confirm(): void {
const router = props.f7router;
let amountFilter = type.value;
if (amountCount.value === 1) {
amountFilter += ':' + amount1.value;
} else if (amountCount.value === 2) {
if (amount2.value < amount1.value) {
showToast('Incorrect amount range');
return;
}
amountFilter += ':' + amount1.value + ':' + amount2.value;
} else {
router.back();
return;
}
const changed = transactionsStore.updateTransactionListFilter({
amountFilter: amountFilter
});
if (changed) {
transactionsStore.updateTransactionListInvalidState(true);
}
router.back();
}
init();
</script> </script>