mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-17 08:14:25 +08:00
fix some numerals were not displayed according to the numerical system
This commit is contained in:
@@ -3,6 +3,7 @@ import { ref, computed } from 'vue';
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { type NameValue } from '@/core/base.ts';
|
||||
import { NumeralSystem } from '@/core/numeral.ts';
|
||||
|
||||
export interface TimePickerValue {
|
||||
value: string;
|
||||
@@ -12,6 +13,7 @@ export interface TimePickerValue {
|
||||
export function useDateTimeSelectionBase() {
|
||||
const {
|
||||
getAllMeridiemIndicators,
|
||||
getCurrentNumeralSystemType,
|
||||
isLongTime24HourFormat,
|
||||
isLongTimeMeridiemIndicatorFirst,
|
||||
isLongTimeHourTwoDigits,
|
||||
@@ -25,14 +27,17 @@ export function useDateTimeSelectionBase() {
|
||||
const isSecondTwoDigits = ref<boolean>(isLongTimeSecondTwoDigits());
|
||||
const isMeridiemIndicatorFirst = ref<boolean>(isLongTimeMeridiemIndicatorFirst() || false);
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const meridiemItems = computed<NameValue[]>(() => getAllMeridiemIndicators());
|
||||
|
||||
function getDisplayTimeValue(value: number, forceTwoDigits: boolean): string {
|
||||
if (forceTwoDigits && value < 10) {
|
||||
return `0${value}`;
|
||||
} else {
|
||||
return value.toString();
|
||||
let textualValue = value.toString();
|
||||
|
||||
if (forceTwoDigits) {
|
||||
textualValue = textualValue.padStart(2, NumeralSystem.WesternArabicNumerals.digitZero);
|
||||
}
|
||||
|
||||
return numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(textualValue);
|
||||
}
|
||||
|
||||
function generateAllHours(count: number, forceTwoDigits: boolean): TimePickerValue[] {
|
||||
@@ -43,7 +48,7 @@ export function useDateTimeSelectionBase() {
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (!is24Hour.value) {
|
||||
ret.push({
|
||||
value: '12',
|
||||
value: getDisplayTimeValue(12, forceTwoDigits),
|
||||
itemsIndex: i
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
@click="currentPage = parseInt(page)"
|
||||
v-if="page !== '...'"
|
||||
>
|
||||
<span>{{ page }}</span>
|
||||
<span>{{ getDisplayPage(page) }}</span>
|
||||
</v-btn>
|
||||
<v-btn variant="text"
|
||||
color="default"
|
||||
@@ -31,8 +31,8 @@
|
||||
<v-list-item class="text-sm" :density="density">
|
||||
<v-list-item-title class="cursor-pointer">
|
||||
<v-autocomplete width="100"
|
||||
item-title="page"
|
||||
item-value="page"
|
||||
item-title="name"
|
||||
item-value="value"
|
||||
auto-select-first="exact"
|
||||
:density="density"
|
||||
:items="allPages"
|
||||
@@ -52,6 +52,8 @@ import { ref, computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import type { NameNumeralValue } from '@/core/base.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import type { ComponentDensity } from '@/lib/ui/desktop.ts';
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -66,17 +68,21 @@ const emit = defineEmits<{
|
||||
(e: 'update:modelValue', value: number): void;
|
||||
}>();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentNumeralSystemType } = useI18n();
|
||||
|
||||
const showMenus = ref<Record<string, boolean>>({});
|
||||
|
||||
const allPages = computed<{ page: number }[]>(() => {
|
||||
const pages = [];
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
|
||||
function getDisplayPage(page: number | string): string {
|
||||
return numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(page.toString());
|
||||
}
|
||||
|
||||
const allPages = computed<NameNumeralValue[]>(() => {
|
||||
const pages: NameNumeralValue[] = [];
|
||||
|
||||
for (let i = 1; i <= props.totalPageCount; i++) {
|
||||
pages.push({
|
||||
page: i
|
||||
});
|
||||
pages.push({ value: i, name: getDisplayPage(i) });
|
||||
}
|
||||
|
||||
return pages;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<div class="d-flex align-center justify-center" style="block-size: 24px; inline-size: 24px;">
|
||||
<div class="slide-group-stepper-indicator"></div>
|
||||
</div>
|
||||
<h4 class="text-h4 step-number">{{ `0${idx + 1}` }}</h4>
|
||||
<h4 class="text-h4 step-number">{{ getDisplayStep(idx + 1) }}</h4>
|
||||
</div>
|
||||
<div style="line-height: 0;">
|
||||
<h6 class="text-sm font-weight-medium step-title">{{ step.title }}</h6>
|
||||
@@ -31,7 +31,7 @@
|
||||
<div class="d-flex align-center justify-center" style="block-size: 24px; inline-size: 24px;">
|
||||
<div class="slide-group-stepper-indicator"></div>
|
||||
</div>
|
||||
<h4 class="text-h4 step-number">{{ `0${idx + 1}` }}</h4>
|
||||
<h4 class="text-h4 step-number">{{ getDisplayStep(idx + 1) }}</h4>
|
||||
</div>
|
||||
<div style="line-height: 0;">
|
||||
<h6 class="text-sm font-weight-medium step-title">{{ step.title }}</h6>
|
||||
@@ -46,6 +46,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { NumeralSystem } from '@/core/numeral.ts';
|
||||
|
||||
export interface StepBarItem {
|
||||
name: string;
|
||||
title: string;
|
||||
@@ -63,8 +67,15 @@ const emit = defineEmits<{
|
||||
(e: 'step:change', stepName: string): void;
|
||||
}>();
|
||||
|
||||
const { getCurrentNumeralSystemType } = useI18n();
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const isClickable = computed<boolean>(() => props.clickable !== 'false' && props.clickable !== false);
|
||||
|
||||
function getDisplayStep(index: number): string {
|
||||
return numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(index.toString().padStart(2, NumeralSystem.WesternArabicNumerals.digitZero));
|
||||
}
|
||||
|
||||
function changeStep(step: StepBarItem): void {
|
||||
if (isClickable.value) {
|
||||
emit('step:change', step.name);
|
||||
|
||||
@@ -8,6 +8,11 @@ export interface NameValue {
|
||||
readonly value: string;
|
||||
}
|
||||
|
||||
export interface NameNumeralValue {
|
||||
readonly name: string;
|
||||
readonly value: number;
|
||||
}
|
||||
|
||||
export interface TypeAndName {
|
||||
readonly type: number;
|
||||
readonly name: string;
|
||||
|
||||
+6
-6
@@ -60,14 +60,14 @@ type DateTimeTokenFormatFunction = (d: MomentDateTime, options: DateTimeFormatOp
|
||||
|
||||
class MomentDateTime implements DateTime {
|
||||
private static readonly tokenFormatFuncs: Record<string, DateTimeTokenFormatFunction> = {
|
||||
'YY': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarYear(options), minNumeralLength: 2, maxLength: 2 }),
|
||||
'YYYY': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarYear(options), minNumeralLength: 4 }),
|
||||
'M': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonth(options) }),
|
||||
'MM': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonth(options), minNumeralLength: 2 }),
|
||||
'YY': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarYear(options), hasNumeral: true, minNumeralLength: 2, maxLength: 2 }),
|
||||
'YYYY': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarYear(options), hasNumeral: true, minNumeralLength: 4 }),
|
||||
'M': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonth(options), hasNumeral: true }),
|
||||
'MM': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonth(options), hasNumeral: true, minNumeralLength: 2 }),
|
||||
'MMM': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonthDisplayShortName(options) }),
|
||||
'MMMM': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarMonthDisplayName(options) }),
|
||||
'D': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarDay(options) }),
|
||||
'DD': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarDay(options), minNumeralLength: 2 }),
|
||||
'D': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarDay(options), hasNumeral: true }),
|
||||
'DD': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getLocalizedCalendarDay(options), hasNumeral: true, minNumeralLength: 2 }),
|
||||
'dd': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getWeekDayDisplayMinName(options) }),
|
||||
'ddd': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getWeekDayDisplayShortName(options) }),
|
||||
'dddd': (d: MomentDateTime, options: DateTimeFormatOptions) => ofObject<DateTimeFormatResult>({ value: d.getWeekDayDisplayName(options) }),
|
||||
|
||||
+16
-13
@@ -1069,12 +1069,13 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function getAllTimezones(includeSystemDefault?: boolean): LocalizedTimezoneInfo[] {
|
||||
const defaultTimezoneOffset = getBrowserTimezoneOffset();
|
||||
const numeralSystem = getCurrentNumeralSystemType();
|
||||
const defaultTimezoneOffset = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(getBrowserTimezoneOffset());
|
||||
const defaultTimezoneOffsetMinutes = getBrowserTimezoneOffsetMinutes();
|
||||
const allTimezoneInfos: LocalizedTimezoneInfo[] = [];
|
||||
|
||||
for (let i = 0; i < ALL_TIMEZONES.length; i++) {
|
||||
const utcOffset = (ALL_TIMEZONES[i].timezoneName !== UTC_TIMEZONE.timezoneName ? getTimezoneOffset(ALL_TIMEZONES[i].timezoneName) : '');
|
||||
const utcOffset = (ALL_TIMEZONES[i].timezoneName !== UTC_TIMEZONE.timezoneName ? numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(ALL_TIMEZONES[i].timezoneName)) : '');
|
||||
const displayName = t(`timezone.${ALL_TIMEZONES[i].displayName}`);
|
||||
|
||||
allTimezoneInfos.push({
|
||||
@@ -1099,11 +1100,11 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
allTimezoneInfos.sort(function (c1, c2) {
|
||||
const utcOffset1 = parseInt(c1.utcOffset.replace(':', ''));
|
||||
const utcOffset2 = parseInt(c2.utcOffset.replace(':', ''));
|
||||
const utcOffsetMinutes1 = c1.utcOffsetMinutes;
|
||||
const utcOffsetMinutes2 = c2.utcOffsetMinutes;
|
||||
|
||||
if (utcOffset1 !== utcOffset2) {
|
||||
return utcOffset1 - utcOffset2;
|
||||
if (utcOffsetMinutes1 !== utcOffsetMinutes2) {
|
||||
return utcOffsetMinutes1 - utcOffsetMinutes2;
|
||||
}
|
||||
|
||||
return c1.displayName.localeCompare(c2.displayName);
|
||||
@@ -1113,7 +1114,8 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function getAllTimezoneTypesUsedForStatistics(currentTimezone?: string): TypeAndDisplayName[] {
|
||||
const currentTimezoneOffset = getTimezoneOffset(currentTimezone);
|
||||
const numeralSystem = getCurrentNumeralSystemType();
|
||||
const currentTimezoneOffset = numeralSystem.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(currentTimezone));
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -1836,29 +1838,30 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function getTimezoneDifferenceDisplayText(utcOffset: number): string {
|
||||
const numeralSystem = getCurrentNumeralSystemType();
|
||||
const defaultTimezoneOffset = getTimezoneOffsetMinutes();
|
||||
const offsetTime = getTimeDifferenceHoursAndMinutes(utcOffset - defaultTimezoneOffset);
|
||||
|
||||
if (utcOffset > defaultTimezoneOffset) {
|
||||
if (offsetTime.offsetMinutes) {
|
||||
return t('format.misc.hoursMinutesAheadOfDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours,
|
||||
minutes: offsetTime.offsetMinutes
|
||||
hours: numeralSystem.formatNumber(offsetTime.offsetHours),
|
||||
minutes: numeralSystem.formatNumber(offsetTime.offsetMinutes)
|
||||
});
|
||||
} else {
|
||||
return t('format.misc.hoursAheadOfDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours
|
||||
hours: numeralSystem.formatNumber(offsetTime.offsetHours)
|
||||
});
|
||||
}
|
||||
} else if (utcOffset < defaultTimezoneOffset) {
|
||||
if (offsetTime.offsetMinutes) {
|
||||
return t('format.misc.hoursMinutesBehindDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours,
|
||||
minutes: offsetTime.offsetMinutes
|
||||
hours: numeralSystem.formatNumber(offsetTime.offsetHours),
|
||||
minutes: numeralSystem.formatNumber(offsetTime.offsetMinutes)
|
||||
});
|
||||
} else {
|
||||
return t('format.misc.hoursBehindDefaultTimezone', {
|
||||
hours: offsetTime.offsetHours
|
||||
hours: numeralSystem.formatNumber(offsetTime.offsetHours)
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -10,11 +10,12 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||
|
||||
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import type { WeekDayValue } from '@/core/datetime.ts';
|
||||
import type { LocalizedTimezoneInfo } from '@/core/timezone.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { TemplateType } from '@/core/template.ts';
|
||||
import { DISPLAY_HIDDEN_AMOUNT } from '@/consts/numeral.ts';
|
||||
import { TRANSACTION_MAX_PICTURE_COUNT } from '@/consts/transaction.ts';
|
||||
|
||||
import { Account, type CategorizedAccountWithDisplayBalance } from '@/models/account.ts';
|
||||
@@ -59,6 +60,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
const {
|
||||
tt,
|
||||
getAllTimezones,
|
||||
getCurrentNumeralSystemType,
|
||||
getTimezoneDifferenceDisplayText,
|
||||
formatAmountToLocalizedNumeralsWithCurrency,
|
||||
getAdaptiveAmountRate,
|
||||
@@ -89,6 +91,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
|
||||
const transaction = ref<Transaction | TransactionTemplate>(createNewTransactionModel(transactionDefaultType));
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const showAccountBalance = computed<boolean>(() => settingsStore.appSettings.showAccountBalance);
|
||||
const defaultCurrency = computed<string>(() => userStore.currentUserDefaultCurrency);
|
||||
@@ -265,7 +268,8 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
});
|
||||
|
||||
const transactionDisplayTimezone = computed<string>(() => {
|
||||
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.value.utcOffset)}`;
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getUtcOffsetByUtcOffsetMinutes(transaction.value.utcOffset));
|
||||
return `UTC${utcOffset}`;
|
||||
});
|
||||
|
||||
const transactionTimezoneTimeDifference = computed<string>(() => {
|
||||
@@ -416,6 +420,7 @@ export function useTransactionEditPageBase(type: TransactionEditPageType, initMo
|
||||
setGeoLocationByClickMap,
|
||||
transaction,
|
||||
// computed states
|
||||
numeralSystem,
|
||||
currentTimezoneOffsetMinutes,
|
||||
showAccountBalance,
|
||||
defaultCurrency,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionListFilter, type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndName } from '@/core/base.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { type TextualYearMonthDay, type Year0BasedMonth, type LocalizedDateRange, type WeekDayValue, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
@@ -74,6 +75,7 @@ export function useTransactionListPageBase() {
|
||||
const {
|
||||
tt,
|
||||
getAllDateRanges,
|
||||
getCurrentNumeralSystemType,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatUnixTimeToLongDate,
|
||||
formatUnixTimeToLongYearMonth,
|
||||
@@ -95,6 +97,7 @@ export function useTransactionListPageBase() {
|
||||
const customMaxDatetime = ref<number>(0);
|
||||
const currentCalendarDate = ref<TextualYearMonthDay | ''>('');
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
|
||||
const fiscalYearStart = computed<number>(() => userStore.currentUserFiscalYearStart);
|
||||
@@ -288,11 +291,13 @@ export function useTransactionListPageBase() {
|
||||
}
|
||||
|
||||
function getDisplayTimezone(transaction: Transaction): string {
|
||||
return `UTC${getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset)}`;
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getUtcOffsetByUtcOffsetMinutes(transaction.utcOffset));
|
||||
return `UTC${utcOffset}`;
|
||||
}
|
||||
|
||||
function getDisplayTimeInDefaultTimezone(transaction: Transaction): string {
|
||||
return `${formatUnixTimeToLongDateTime(transaction.time)} (UTC${getTimezoneOffset(settingsStore.appSettings.timeZone)})`;
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(settingsStore.appSettings.timeZone));
|
||||
return `${formatUnixTimeToLongDateTime(transaction.time)} (UTC${utcOffset})`;
|
||||
}
|
||||
|
||||
function getDisplayAmount(transaction: Transaction): string {
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
<v-card-text>
|
||||
<div class="mb-8">
|
||||
<span class="text-body-1" v-if="!loadingOverview || (allAccounts && allAccounts.length)">{{ tt('format.misc.youHaveAccounts', { count: allAccounts.length }) }}</span>
|
||||
<span class="text-body-1" v-if="!loadingOverview || (allAccounts && allAccounts.length)">{{ tt('format.misc.youHaveAccounts', { count: displayAccountCount }) }}</span>
|
||||
<v-skeleton-loader class="skeleton-no-margin mt-1 mb-2 pb-1" width="200px" type="text" :loading="true" v-else-if="loadingOverview && (!allAccounts || !allAccounts.length)"></v-skeleton-loader>
|
||||
</div>
|
||||
|
||||
@@ -201,6 +201,7 @@ import { useHomePageBase } from '@/views/base/HomePageBase.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
|
||||
import { type NumeralSystem } from '@/core/numeral.ts';
|
||||
import { DateRange } from '@/core/datetime.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { type TransactionMonthlyIncomeAndExpenseData, LATEST_12MONTHS_TRANSACTION_AMOUNTS_REQUEST_TYPES } from '@/models/transaction.ts';
|
||||
@@ -227,7 +228,7 @@ type SnackBarType = InstanceType<typeof SnackBar>;
|
||||
const router = useRouter();
|
||||
const theme = useTheme();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentNumeralSystemType } = useI18n();
|
||||
const {
|
||||
showAmountInHomePage,
|
||||
allAccounts,
|
||||
@@ -248,6 +249,9 @@ const snackbar = useTemplateRef<SnackBarType>('snackbar');
|
||||
const loadingOverview = ref<boolean>(true);
|
||||
|
||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
|
||||
const displayAccountCount = computed<string>(() => allAccounts.value ? numeralSystem.value.formatNumber(allAccounts.value.length) : numeralSystem.value.digitZero);
|
||||
|
||||
function clickMonthlyIncomeOrExpense(e: MonthlyIncomeAndExpenseCardClickEvent): void {
|
||||
const minTime = e.monthStartTime;
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
{{ tt('Transactions Per Page') }}
|
||||
</span>
|
||||
<v-select class="ms-2" density="compact" max-width="100"
|
||||
item-title="title"
|
||||
item-title="name"
|
||||
item-value="value"
|
||||
:disabled="loading"
|
||||
:items="reconciliationStatementsTablePageOptions"
|
||||
@@ -278,6 +278,8 @@ import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { NameNumeralValue } from '@/core/base.ts';
|
||||
import type { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
import { AccountBalanceTrendChartType, ChartDateAggregationType } from '@/core/statistics.ts';
|
||||
import { KnownFileType } from '@/core/file.ts';
|
||||
@@ -310,16 +312,11 @@ type SnackBarType = InstanceType<typeof SnackBar>;
|
||||
type AmountInputDialogType = InstanceType<typeof AmountInputDialog>;
|
||||
type EditDialogType = InstanceType<typeof EditDialog>;
|
||||
|
||||
interface ReconciliationStatementDialogTablePageOption {
|
||||
value: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'error', message: string): void;
|
||||
}>();
|
||||
|
||||
const { tt, formatNumberToLocalizedNumerals } = useI18n();
|
||||
const { tt, getCurrentNumeralSystemType, formatNumberToLocalizedNumerals } = useI18n();
|
||||
|
||||
const {
|
||||
accountId,
|
||||
@@ -383,7 +380,8 @@ const chartDataDateAggregationType = ref<number | undefined>(undefined);
|
||||
|
||||
let rejectFunc: ((reason?: unknown) => void) | null = null;
|
||||
|
||||
const reconciliationStatementsTablePageOptions = computed<ReconciliationStatementDialogTablePageOption[]>(() => getTablePageOptions(reconciliationStatements.value?.transactions.length));
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const reconciliationStatementsTablePageOptions = computed<NameNumeralValue[]>(() => getTablePageOptions(reconciliationStatements.value?.transactions.length));
|
||||
|
||||
const totalPageCount = computed<number>(() => {
|
||||
if (!reconciliationStatements.value || !reconciliationStatements.value.transactions || reconciliationStatements.value.transactions.length < 1) {
|
||||
@@ -414,11 +412,11 @@ const dataTableHeaders = computed<object[]>(() => {
|
||||
return headers;
|
||||
});
|
||||
|
||||
function getTablePageOptions(linesCount?: number): ReconciliationStatementDialogTablePageOption[] {
|
||||
const pageOptions: ReconciliationStatementDialogTablePageOption[] = [];
|
||||
function getTablePageOptions(linesCount?: number): NameNumeralValue[] {
|
||||
const pageOptions: NameNumeralValue[] = [];
|
||||
|
||||
if (!linesCount || linesCount < 1) {
|
||||
pageOptions.push({ value: -1, title: tt('All') });
|
||||
pageOptions.push({ value: -1, name: tt('All') });
|
||||
return pageOptions;
|
||||
}
|
||||
|
||||
@@ -431,10 +429,10 @@ function getTablePageOptions(linesCount?: number): ReconciliationStatementDialog
|
||||
break;
|
||||
}
|
||||
|
||||
pageOptions.push({ value: count, title: count.toString() });
|
||||
pageOptions.push({ value: count, name: numeralSystem.value.formatNumber(count) });
|
||||
}
|
||||
|
||||
pageOptions.push({ value: -1, title: tt('All') });
|
||||
pageOptions.push({ value: -1, name: tt('All') });
|
||||
|
||||
return pageOptions;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,11 @@
|
||||
</div>
|
||||
<div class="mx-6 mt-4" v-if="pageType === TransactionListPageType.List.type">
|
||||
<span class="text-subtitle-2">{{ tt('Transactions Per Page') }}</span>
|
||||
<v-select class="mt-2" density="compact" :disabled="loading"
|
||||
:items="[ 5, 10, 15, 20, 25, 30, 50 ]"
|
||||
<v-select class="mt-2" density="compact"
|
||||
item-title="name"
|
||||
item-value="value"
|
||||
:disabled="loading"
|
||||
:items="allPageCounts"
|
||||
v-model="countPerPage"
|
||||
/>
|
||||
</div>
|
||||
@@ -666,7 +669,7 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||
import { useDesktopPageStore } from '@/stores/desktopPage.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import type { NameNumeralValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import {
|
||||
type Year0BasedMonth,
|
||||
type LocalizedRecentMonthDateRange,
|
||||
@@ -674,7 +677,7 @@ import {
|
||||
DateRangeScene,
|
||||
DateRange
|
||||
} from '@/core/datetime.ts';
|
||||
import { AmountFilterType } from '@/core/numeral.ts';
|
||||
import { type NumeralSystem, AmountFilterType } from '@/core/numeral.ts';
|
||||
import { ThemeType } from '@/core/theme.ts';
|
||||
import { TransactionType, TransactionTagFilterType } from '@/core/transaction.ts';
|
||||
import { TemplateType } from '@/core/template.ts';
|
||||
@@ -774,7 +777,8 @@ const {
|
||||
tt,
|
||||
getAllRecentMonthDateRanges,
|
||||
getAllTransactionTagFilterTypes,
|
||||
getWeekdayLongName
|
||||
getWeekdayLongName,
|
||||
getCurrentNumeralSystemType
|
||||
} = useI18n();
|
||||
|
||||
const {
|
||||
@@ -874,6 +878,19 @@ const showFilterCategoryDialog = ref<boolean>(false);
|
||||
const showFilterTagDialog = ref<boolean>(false);
|
||||
|
||||
const isDarkMode = computed<boolean>(() => theme.global.name.value === ThemeType.Dark);
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
|
||||
const allPageCounts = computed<NameNumeralValue[]>(() => {
|
||||
const pageCounts: NameNumeralValue[] = [];
|
||||
const availableCountPerPage: number[] = [ 5, 10, 15, 20, 25, 30, 50 ];
|
||||
|
||||
for (let i = 0; i < availableCountPerPage.length; i++) {
|
||||
const count = availableCountPerPage[i];
|
||||
pageCounts.push({ value: count, name: numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(count.toString()) });
|
||||
}
|
||||
|
||||
return pageCounts;
|
||||
});
|
||||
|
||||
const recentMonthDateRanges = computed<LocalizedRecentMonthDateRange[]>(() => getAllRecentMonthDateRanges(pageType.value === TransactionListPageType.List.type, true));
|
||||
|
||||
|
||||
@@ -503,7 +503,7 @@
|
||||
<v-spacer/>
|
||||
<span>{{ tt('Lines Per Page') }}</span>
|
||||
<v-select class="ms-2" density="compact" max-width="100"
|
||||
item-title="title"
|
||||
item-title="name"
|
||||
item-value="value"
|
||||
:disabled="loading || submitting"
|
||||
:items="parsedFileLinesTablePageOptions"
|
||||
@@ -794,12 +794,12 @@
|
||||
<div class="title-and-toolbar d-flex align-center text-no-wrap mt-2"
|
||||
v-if="importTransactions && importTransactions.length > 10">
|
||||
<span :class="{ 'text-error': selectedInvalidTransactionCount > 0 }">
|
||||
{{ tt('format.misc.selectedCount', { count: selectedImportTransactionCount, totalCount: importTransactions.length }) }}
|
||||
{{ tt('format.misc.selectedCount', { count: getDisplayCount(selectedImportTransactionCount), totalCount: getDisplayCount(importTransactions.length) }) }}
|
||||
</span>
|
||||
<v-spacer/>
|
||||
<span>{{ tt('Transactions Per Page') }}</span>
|
||||
<v-select class="ms-2" density="compact" max-width="100"
|
||||
item-title="title"
|
||||
item-title="name"
|
||||
item-value="value"
|
||||
:disabled="loading || submitting"
|
||||
:items="importTransactionsTablePageOptions"
|
||||
@@ -815,7 +815,7 @@
|
||||
</v-window-item>
|
||||
<v-window-item value="finalResult">
|
||||
<h4 class="text-h4 mb-1">{{ tt('Data Import Completed') }}</h4>
|
||||
<p class="my-5">{{ tt('format.misc.importTransactionResult', { count: importedCount }) }}</p>
|
||||
<p class="my-5">{{ tt('format.misc.importTransactionResult', { count: getDisplayCount(importedCount || 0) }) }}</p>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
|
||||
@@ -906,8 +906,8 @@ import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
import { useOverviewStore } from '@/stores/overview.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { NameValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { KnownAmountFormat } from '@/core/numeral.ts';
|
||||
import type { NameValue, NameNumeralValue, TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { type NumeralSystem, KnownAmountFormat } from '@/core/numeral.ts';
|
||||
import { KnownDateTimeFormat } from '@/core/datetime.ts';
|
||||
import { KnownDateTimezoneFormat } from '@/core/timezone.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
@@ -992,11 +992,6 @@ interface ImportTransactionDialogFilter {
|
||||
description: string | null; // null for 'All Description'
|
||||
}
|
||||
|
||||
interface ImportTransactionsDialogTablePageOption {
|
||||
value: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
persistent?: boolean;
|
||||
}>();
|
||||
@@ -1005,6 +1000,7 @@ const {
|
||||
tt,
|
||||
getAllImportTransactionColumnTypes,
|
||||
getAllSupportedImportFileCagtegoryAndTypes,
|
||||
getCurrentNumeralSystemType,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatAmountToLocalizedNumeralsWithCurrency,
|
||||
formatNumberToLocalizedNumerals,
|
||||
@@ -1063,6 +1059,7 @@ const submitting = ref<boolean>(false);
|
||||
let resolveFunc: (() => void) | null = null;
|
||||
let rejectFunc: ((reason?: unknown) => void) | null = null;
|
||||
|
||||
const numeralSystem = computed<NumeralSystem>(() => getCurrentNumeralSystemType());
|
||||
const showAccountBalance = computed<boolean>(() => settingsStore.appSettings.showAccountBalance);
|
||||
const currentTimezoneOffsetMinutes = computed<number>(() => getTimezoneOffsetMinutes(settingsStore.appSettings.timeZone));
|
||||
|
||||
@@ -1252,7 +1249,7 @@ const parsedFileLinesHeaders = computed<object[]>(() => {
|
||||
return headers;
|
||||
});
|
||||
|
||||
const parsedFileLinesTablePageOptions = computed<ImportTransactionsDialogTablePageOption[]>(() => getTablePageOptions(parsedFileLines.value?.length));
|
||||
const parsedFileLinesTablePageOptions = computed<NameNumeralValue[]>(() => getTablePageOptions(parsedFileLines.value?.length));
|
||||
|
||||
const parsedFileAllTransactionTypes = computed<string[]>(() => parsedFileDataColumnMapping.value.parseFileAllTransactionTypes(parsedFileData.value));
|
||||
const parsedFileValidMappedTransactionTypes = computed<Record<string, TransactionType>>(() => parsedFileDataColumnMapping.value.parseFileValidMappedTransactionTypes(parsedFileData.value));
|
||||
@@ -1282,7 +1279,7 @@ const importTransactionHeaders = computed<object[]>(() => {
|
||||
];
|
||||
});
|
||||
|
||||
const importTransactionsTablePageOptions = computed<ImportTransactionsDialogTablePageOption[]>(() => getTablePageOptions(importTransactions.value?.length));
|
||||
const importTransactionsTablePageOptions = computed<NameNumeralValue[]>(() => getTablePageOptions(importTransactions.value?.length));
|
||||
|
||||
const totalPageCount = computed<number>(() => {
|
||||
if (!importTransactions.value || importTransactions.value.length < 1) {
|
||||
@@ -1490,11 +1487,15 @@ const displayFilterCustomDateRange = computed<string>(() => {
|
||||
return `${minDisplayTime} - ${maxDisplayTime}`
|
||||
});
|
||||
|
||||
function getTablePageOptions(linesCount?: number): ImportTransactionsDialogTablePageOption[] {
|
||||
const pageOptions: ImportTransactionsDialogTablePageOption[] = [];
|
||||
function getDisplayCount(count: number): string {
|
||||
return numeralSystem.value.formatNumber(count);
|
||||
}
|
||||
|
||||
function getTablePageOptions(linesCount?: number): NameNumeralValue[] {
|
||||
const pageOptions: NameNumeralValue[] = [];
|
||||
|
||||
if (!linesCount || linesCount < 1) {
|
||||
pageOptions.push({ value: -1, title: tt('All') });
|
||||
pageOptions.push({ value: -1, name: tt('All') });
|
||||
return pageOptions;
|
||||
}
|
||||
|
||||
@@ -1507,10 +1508,10 @@ function getTablePageOptions(linesCount?: number): ImportTransactionsDialogTable
|
||||
break;
|
||||
}
|
||||
|
||||
pageOptions.push({ value: count, title: count.toString() });
|
||||
pageOptions.push({ value: count, name: getDisplayCount(count) });
|
||||
}
|
||||
|
||||
pageOptions.push({ value: -1, title: tt('All') });
|
||||
pageOptions.push({ value: -1, name: tt('All') });
|
||||
|
||||
return pageOptions;
|
||||
}
|
||||
@@ -2110,7 +2111,7 @@ function submit(): void {
|
||||
}
|
||||
|
||||
confirmDialog.value?.open('format.misc.confirmImportTransactions', {
|
||||
count: transactions.length
|
||||
count: getDisplayCount(transactions.length)
|
||||
}).then(() => {
|
||||
editingTransaction.value = null;
|
||||
editingTags.value = [];
|
||||
@@ -2379,7 +2380,7 @@ function showBatchReplaceDialog(type: BatchReplaceDialogDataType): void {
|
||||
|
||||
if (updatedCount > 0) {
|
||||
snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', {
|
||||
count: updatedCount
|
||||
count: getDisplayCount(updatedCount)
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -2463,7 +2464,7 @@ function showReplaceInvalidItemDialog(type: BatchReplaceDialogDataType, invalidI
|
||||
|
||||
if (updatedCount > 0) {
|
||||
snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', {
|
||||
count: updatedCount
|
||||
count: getDisplayCount(updatedCount)
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -2535,7 +2536,7 @@ function showReplaceAllTypesDialog(): void {
|
||||
|
||||
if (updatedCount > 0) {
|
||||
snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', {
|
||||
count: updatedCount
|
||||
count: getDisplayCount(updatedCount)
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -2607,7 +2608,7 @@ function showBatchCreateInvalidItemDialog(type: BatchCreateDialogDataType, inval
|
||||
|
||||
if (updatedCount > 0) {
|
||||
snackbar.value?.showMessage('format.misc.youHaveUpdatedTransactions', {
|
||||
count: updatedCount
|
||||
count: getDisplayCount(updatedCount)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -553,6 +553,7 @@ const {
|
||||
geoLocationStatus,
|
||||
setGeoLocationByClickMap,
|
||||
transaction,
|
||||
numeralSystem,
|
||||
currentTimezoneOffsetMinutes,
|
||||
defaultCurrency,
|
||||
defaultAccountId,
|
||||
@@ -662,7 +663,8 @@ const transactionDisplayTime = computed<string>(() => {
|
||||
return formatUnixTimeToLongTime(getActualUnixTimeForStore(transaction.value.time, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()));
|
||||
}
|
||||
|
||||
return `${formatUnixTimeToLongTime(getActualUnixTimeForStore(transaction.value.time, transaction.value.utcOffset, getBrowserTimezoneOffsetMinutes()))} (UTC${getTimezoneOffset(settingsStore.appSettings.timeZone)})`;
|
||||
const utcOffset = numeralSystem.value.replaceWesternArabicDigitsToLocalizedDigits(getTimezoneOffset(settingsStore.appSettings.timeZone));
|
||||
return `${formatUnixTimeToLongTime(getActualUnixTimeForStore(transaction.value.time, transaction.value.utcOffset, getBrowserTimezoneOffsetMinutes()))} (UTC${utcOffset})`;
|
||||
});
|
||||
|
||||
const transactionDisplayTimezoneName = computed<string>(() => {
|
||||
|
||||
Reference in New Issue
Block a user