mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-20 17:54:30 +08:00
migrate amount filter page to composition API and typescript
This commit is contained in:
+11
-7
@@ -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 {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user