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);
}
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)) {
return null;
}
@@ -1215,13 +1215,17 @@ export function useI18n() {
}
}
let finalCurrencyCode = '';
if (!isBoolean(currencyCode) && !currencyCode) {
currencyCode = userStore.currentUserDefaultCurrency;
finalCurrencyCode = userStore.currentUserDefaultCurrency;
} else if (isBoolean(currencyCode) && !currencyCode) {
currencyCode = '';
finalCurrencyCode = '';
} else {
finalCurrencyCode = currencyCode;
}
if (!currencyCode) {
if (!finalCurrencyCode) {
return textualValue;
}
@@ -1229,9 +1233,9 @@ export function useI18n() {
currencyDisplayType = getCurrentCurrencyDisplayType();
}
const currencyUnit = getCurrencyUnitName(currencyCode, isPlural);
const currencyName = getCurrencyName(currencyCode);
return appendCurrencySymbol(textualValue, currencyDisplayType, currencyCode, currencyUnit, currencyName, isPlural);
const currencyUnit = getCurrencyUnitName(finalCurrencyCode, isPlural);
const currencyName = getCurrencyName(finalCurrencyCode);
return appendCurrencySymbol(textualValue, currencyDisplayType, finalCurrencyCode, currencyUnit, currencyName, isPlural);
}
function getFormattedExchangeRateAmount(value: number | string): string {
+116 -131
View File
@@ -1,10 +1,10 @@
<template>
<f7-page @page:afterin="onPageAfterIn">
<f7-page>
<f7-navbar>
<f7-nav-left :back-link="$t('Back')"></f7-nav-left>
<f7-nav-title :title="$t('Filter Amount')"></f7-nav-title>
<f7-nav-left :back-link="tt('Back')"></f7-nav-left>
<f7-nav-title :title="tt('Filter Amount')"></f7-nav-title>
<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-navbar>
@@ -13,11 +13,11 @@
class="ebk-small-amount"
link="#" no-chevron
:header="amount1Header"
:title="getDisplayAmount(amount1)"
:title="formatAmountWithCurrency(amount1)"
@click="showAmount1Sheet = true"
>
<number-pad-sheet :min-value="allowedMinAmount"
:max-value="allowedMaxAmount"
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
:max-value="TRANSACTION_MAX_AMOUNT"
v-model:show="showAmount1Sheet"
v-model="amount1"
></number-pad-sheet>
@@ -27,12 +27,12 @@
class="ebk-small-amount"
link="#" no-chevron
:header="amount2Header"
:title="getDisplayAmount(amount2)"
:title="formatAmountWithCurrency(amount2)"
@click="showAmount2Sheet = true"
v-if="amountCount === 2"
>
<number-pad-sheet :min-value="allowedMinAmount"
:max-value="allowedMaxAmount"
<number-pad-sheet :min-value="TRANSACTION_MIN_AMOUNT"
:max-value="TRANSACTION_MAX_AMOUNT"
v-model:show="showAmount2Sheet"
v-model="amount2"
></number-pad-sheet>
@@ -40,8 +40,8 @@
</f7-list>
<f7-list form strong inset dividers class="margin-vertical">
<f7-list-item :key="filterType.type" :title="$t(filterType.name)"
v-for="filterType in allAmountFilterTypes"
<f7-list-item :key="filterType.type" :title="tt(filterType.name)"
v-for="filterType in AmountFilterType.values()"
@click="type = filterType.type">
<template #after>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="type === filterType.type"></f7-icon>
@@ -51,10 +51,13 @@
</f7-page>
</template>
<script>
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/setting.ts';
import { useUserStore } from '@/stores/user.ts';
<script setup lang="ts">
import { ref, computed } from 'vue';
import type { Router } from 'framework7/types';
import { useI18n } from '@/locales/helpers.ts';
import { useI18nUIComponents } from '@/lib/ui/mobile.ts';
import { useTransactionsStore } from '@/stores/transaction.js';
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 logger from '@/lib/logger.ts';
export default {
props: [
'f7route',
'f7router'
],
data() {
return {
type: '',
amount1: 0,
amount2: 0,
showAmount1Sheet: false,
showAmount2Sheet: false
}
},
computed: {
...mapStores(useSettingsStore, useUserStore, useTransactionsStore),
allAmountFilterTypes() {
return AmountFilterType.values();
},
allowedMinAmount() {
return TRANSACTION_MIN_AMOUNT;
},
allowedMaxAmount() {
return TRANSACTION_MAX_AMOUNT;
},
amountCount() {
return this.getAmountFilterParameterCount(this.type);
},
title() {
const amountFilterType = AmountFilterType.valueOf(this.type);
return amountFilterType ? this.$t(amountFilterType.name) : this.$t('Amount');
},
amount1Header() {
if (this.type === AmountFilterType.GreaterThan.type
|| this.type === AmountFilterType.Between.type
|| this.type === AmountFilterType.NotBetween.type) {
return this.$t('Minimum Amount');
} else if (this.type === AmountFilterType.LessThan.type) {
return this.$t('Maximum Amount');
} else {
return this.$t('Amount');
const props = defineProps<{
f7route: Router.Route;
f7router: Router.Router;
}>();
const type = ref<string>('');
const amount1 = ref<number>(0);
const amount2 = ref<number>(0);
const showAmount1Sheet = ref<boolean>(false);
const showAmount2Sheet = ref<boolean>(false);
const { tt, formatAmountWithCurrency } = useI18n();
const { showToast } = useI18nUIComponents();
const transactionsStore = useTransactionsStore();
const amountCount = computed<number>(() => getAmountFilterParameterCount(type.value));
const amount1Header = computed<string>(() => {
if (type.value === AmountFilterType.GreaterThan.type
|| type.value === AmountFilterType.Between.type
|| type.value === AmountFilterType.NotBetween.type) {
return tt('Minimum Amount');
} else if (type.value === AmountFilterType.LessThan.type) {
return tt('Maximum Amount');
} else {
return tt('Amount');
}
});
const amount2Header = computed<string>(() => {
if (type.value === AmountFilterType.Between.type) {
return tt('Maximum Amount');
} else if (type.value === AmountFilterType.NotBetween.type) {
return tt('Maximum Amount');
} else {
return tt('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]);
}
},
amount2Header() {
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;
} catch (ex) {
logger.warn('cannot parse amount from filter value, original value is ' + query['value'], ex);
}
}
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>