mobile version supports rtl

This commit is contained in:
MaysWind
2025-08-19 23:56:28 +08:00
parent efe39c7390
commit 13d5759e84
44 changed files with 534 additions and 219 deletions
+4 -4
View File
@@ -21,7 +21,7 @@
<p class="no-margin">
<span class="month-expense" v-if="loading">0.00 USD</span>
<span class="month-expense" v-else-if="!loading">{{ transactionOverview && transactionOverview.thisMonth ? getDisplayExpenseAmount(transactionOverview.thisMonth) : '-' }}</span>
<f7-link class="margin-left-half" @click="showAmountInHomePage = !showAmountInHomePage">
<f7-link class="margin-inline-start-half" @click="showAmountInHomePage = !showAmountInHomePage">
<f7-icon class="ebk-hide-icon" :f7="showAmountInHomePage ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
</f7-link>
</p>
@@ -314,11 +314,11 @@ init();
}
.home-summary-misc > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.home-summary-misc > span:last-child {
margin-right: 0;
margin-inline-end: 0;
}
.dark .home-summary-card {
@@ -348,7 +348,7 @@ init();
}
.overview-transaction-list .overview-transaction-footer > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.overview-transaction-list .overview-transaction-amount {
+1 -1
View File
@@ -156,7 +156,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start-half">
<f7-list>
<f7-list-item :title="subCategory.name"
:key="subIdx"
+1 -1
View File
@@ -773,6 +773,6 @@ init();
}
.subaccount-delete-button {
margin-left: auto;
margin-inline-start: auto;
}
</style>
+16 -10
View File
@@ -19,7 +19,7 @@
<p class="no-margin">
<span class="net-assets" v-if="loading">0.00 USD</span>
<span class="net-assets" v-else-if="!loading">{{ netAssets }}</span>
<f7-link class="margin-left-half" @click="showAccountBalance = !showAccountBalance">
<f7-link class="margin-inline-start-half" @click="showAccountBalance = !showAccountBalance">
<f7-icon class="ebk-hide-icon" :f7="showAccountBalance ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
</f7-link>
</p>
@@ -44,7 +44,7 @@
<f7-list-item group-title :sortable="false">
<small>
<span>Account Category</span>
<span style="margin-left: 10px">0.00 USD</span>
<span style="margin-inline-start: 10px">0.00 USD</span>
</small>
</f7-list-item>
<f7-list-item class="nested-list-item" after="0.00 USD" link="#"
@@ -77,7 +77,7 @@
<f7-list-item group-title :sortable="false">
<small>
<span>{{ tt(accountCategory.name) }}</span>
<span style="margin-left: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
<span style="margin-inline-start: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
</small>
</f7-list-item>
<f7-list-item swipeout
@@ -137,16 +137,20 @@
</ul>
</li>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(account, !account.hidden)">
<f7-icon :f7="account.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(account)"></f7-swipeout-button>
<f7-swipeout-button color="primary" close :text="tt('More')" @click="showMoreActionSheetForAccount(account)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(account, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(account, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -207,6 +211,7 @@ import { useAccountListPageBaseBase } from '@/views/base/accounts/AccountListPag
import { useAccountsStore } from '@/stores/account.ts';
import { TextDirection } from '@/core/text.ts';
import { AccountType, AccountCategory } from '@/core/account.ts';
import type { Account, AccountShowingIds } from '@/models/account.ts';
@@ -216,7 +221,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -244,6 +249,7 @@ const showMoreActionSheet = ref<boolean>(false);
const showDeleteActionSheet = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const firstShowingIds = computed<AccountShowingIds>(() => accountsStore.getFirstShowingIds(showHidden.value));
const lastShowingIds = computed<AccountShowingIds>(() => accountsStore.getLastShowingIds(showHidden.value));
const hasAnyVisibleAccount = computed<boolean>(() => accountsStore.allVisibleAccountsCount > 0);
@@ -487,11 +493,11 @@ init();
}
.account-overview-info > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.account-overview-info > span:last-child {
margin-right: 0;
margin-inline-end: 0;
}
.account-list {
@@ -143,7 +143,7 @@
</div>
<div class="account-balance flex-shrink-1">
<span>Balance</span>
<span style="margin-left: 4px">0.00 USD</span>
<span style="margin-inline-start: 4px">0.00 USD</span>
</div>
</div>
</div>
@@ -229,14 +229,16 @@
</div>
<div class="account-balance flex-shrink-1">
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
<span style="margin-left: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
<span style="margin-inline-start: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<f7-swipeout-actions right v-if="item.type == 'transaction' && item.transaction">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="item.type == 'transaction' && item.transaction">
<f7-swipeout-button color="primary" close
:text="tt('Duplicate')"
v-if="item.transaction.type !== TransactionType.ModifyBalance"
@@ -245,7 +247,7 @@
:text="tt('Edit')"
v-if="item.transaction.editable && item.transaction.type !== TransactionType.ModifyBalance"
@click="editTransaction(item.transaction)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
v-if="item.transaction.editable"
@click="removeTransaction(item.transaction, false)">
<f7-icon f7="trash"></f7-icon>
@@ -260,7 +262,7 @@
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
<div></div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Time Granularity') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Time Granularity') }}</span>
<f7-link :class="{ 'disabled': loading }" href="#" popover-open=".chart-data-date-aggregation-type-popover-menu">{{ chartDataDateAggregationTypeDisplayName }}</f7-link>
</div>
</div>
@@ -352,6 +354,7 @@ import { useAccountsStore } from '@/stores/account.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionsStore } from '@/stores/transaction.ts';
import { TextDirection } from '@/core/text.ts';
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
import { AccountType } from '@/core/account.ts';
import { TransactionType } from '@/core/transaction.ts';
@@ -386,7 +389,14 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime, formatNumberToLocalizedNumerals } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getAllDateRanges,
formatUnixTimeToLongDateTime,
formatNumberToLocalizedNumerals
} = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -440,6 +450,7 @@ const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
topPosition: 0
});
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
@@ -708,11 +719,11 @@ init();
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content {
padding-left: 0 !important;
padding-inline-start: 0 !important;
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner {
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
padding-inline-start: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner:after {
@@ -725,7 +736,7 @@ init();
}
.list.reconciliation-statement-list li.transaction-info .account-balance {
margin-left: 4px;
margin-inline-start: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+12 -5
View File
@@ -48,15 +48,19 @@
</f7-badge>
</ItemIcon>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(category, !category.hidden)">
<f7-icon :f7="category.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(category)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(category, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(category, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -96,6 +100,7 @@ import { useCategoryListPageBase } from '@/views/base/categories/CategoryListPag
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { TextDirection } from '@/core/text.ts';
import { CategoryType } from '@/core/category.ts';
import type { TransactionCategory } from '@/models/transaction_category.ts';
@@ -110,7 +115,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const { loading, primaryCategoryId, currentPrimaryCategory } = useCategoryListPageBase();
@@ -127,6 +132,8 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const categories = computed<TransactionCategory[]>(() => {
if (!primaryCategoryId.value || primaryCategoryId.value === '' || primaryCategoryId.value === '0') {
if (!transactionCategoriesStore.allTransactionCategories || !transactionCategoriesStore.allTransactionCategories[categoryType.value]) {
+1 -1
View File
@@ -21,7 +21,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start">
<f7-list>
<f7-list-item :title="subCategory.name"
:key="subIdx"
+8 -3
View File
@@ -62,17 +62,19 @@
@swipeout:closed="onExchangeRateSwipeoutClosed()">
<template #title>
<div class="no-padding no-margin">
<span style="margin-right: 5px">{{ exchangeRate.currencyDisplayName }}</span>
<span style="margin-inline-end: 5px">{{ exchangeRate.currencyDisplayName }}</span>
<small class="smaller">{{ exchangeRate.currencyCode }}</small>
</div>
</template>
<f7-swipeout-actions right v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
<f7-swipeout-button color="primary" close
:text="tt('Set as Base')"
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
@click="remove(exchangeRate, false)"
v-if="exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates">
<f7-icon f7="trash"></f7-icon>
@@ -134,6 +136,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import { TextDirection } from '@/core/text.ts';
import { NumeralSystem } from '@/core/numeral.ts';
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
@@ -149,6 +152,7 @@ const props = defineProps<{
const {
tt,
getCurrentLanguageTextDirection,
getCurrentNumeralSystemType,
getCurrencyName,
formatAmountToLocalizedNumerals,
@@ -180,6 +184,7 @@ const showBaseAmountSheet = ref<boolean>(false);
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
const showDeleteActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
const baseAmountFontSizeClass = computed<string>(() => {
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
@@ -83,7 +83,7 @@
</template>
<template #root>
<ul class="padding-left"
<ul class="padding-inline-start"
v-if="account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id])">
<f7-list-item checkbox
:title="subAccount.name"
@@ -30,7 +30,7 @@
v-for="categorizedItems in ALL_APPLICATION_CLOUD_SETTINGS"
@change="updateSettingsSelected(categorizedItems, $event.target.checked)">
<template #root>
<ul class="padding-left">
<ul class="padding-inline-start">
<f7-list-item checkbox
:disabled="loading || enabling || disabling"
:title="tt(settingItem.settingName)"
@@ -32,7 +32,7 @@
<f7-icon f7="app_fill"></f7-icon>
</template>
<template #root>
<ul class="padding-left">
<ul class="padding-inline-start">
<f7-list-item checkbox class="disabled" title="Sub Category Name"
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
<template #media>
@@ -91,7 +91,7 @@
</template>
<template #root>
<ul class="padding-left"
<ul class="padding-inline-start"
v-if="(showHidden && categoryType.allSubCategories[category.id]) || categoryType.allVisibleSubCategoryCounts[category.id]">
<f7-list-item checkbox
:title="subCategory.name"
@@ -93,7 +93,10 @@
<div class="display-flex justify-content-space-between">
<div class="fontsize-minimum">A</div>
<div class="fontsize-maximum">A</div>
<div class="fontsize-default" :style="`left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">{{ tt('Default') }}</div>
<div class="fontsize-default"
:style="textDirection === TextDirection.LTR ? `left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)` : `right: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">
{{ tt('Default') }}
</div>
</div>
<f7-range
:min="FontSize.MinimumFontSize.type"
@@ -120,6 +123,7 @@ import { useI18n } from '@/locales/helpers.ts';
import { useSettingsStore } from '@/stores/setting.ts';
import { TextDirection } from '@/core/text.ts';
import { FontSize } from '@/core/font.ts';
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
@@ -128,13 +132,21 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getWeekdayShortName,
formatUnixTimeToLongYearMonth,
formatUnixTimeToShortTime,
formatAmountToLocalizedNumeralsWithCurrency
} = useI18n();
const settingsStore = useSettingsStore();
const currentUnixTime = ref<number>(getCurrentUnixTime());
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
const currentDayOfMonth = computed<number>(() => getDay(getLocalDatetimeFromUnixTime(currentUnixTime.value)));
@@ -50,8 +50,8 @@
<f7-card v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.categoricalChartType === CategoricalChartType.Pie.type">
<f7-card-header class="no-border display-block">
<div class="statistics-chart-header full-line text-align-right">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<div :class="{ 'statistics-chart-header': true, 'full-line': true, 'text-align-right': textDirection === TextDirection.LTR, 'text-align-left': textDirection === TextDirection.RTL}">
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</f7-card-header>
@@ -104,7 +104,7 @@
{{ totalAmountName }}
</div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</div>
@@ -196,7 +196,7 @@
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
<div></div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</div>
@@ -239,13 +239,13 @@
<f7-toolbar tabbar bottom class="toolbar-item-auto-size">
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(-1)">
<f7-icon f7="arrow_left_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading || query.chartDataType === ChartDataType.AccountTotalAssets.type || query.chartDataType === ChartDataType.AccountTotalLiabilities.type }" popover-open=".date-popover-menu">
<span :class="{ 'tabbar-item-changed': isQueryDateRangeChanged }">{{ queryDateRangeName }}</span>
</f7-link>
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(1)">
<f7-icon f7="arrow_right_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
@@ -343,6 +343,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useStatisticsStore } from '@/stores/statistics.ts';
import type { TypeAndDisplayName } from '@/core/base.ts';
import { TextDirection } from '@/core/text.ts';
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
import {
StatisticsAnalysisType,
@@ -367,7 +368,13 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getAllCategoricalChartTypes, formatPercentToLocalizedNumerals } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getAllCategoricalChartTypes,
formatPercentToLocalizedNumerals
} = useI18n();
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -414,6 +421,8 @@ const showCustomDateRangeSheet = ref<boolean>(false);
const showCustomMonthRangeSheet = ref<boolean>(false);
const showMoreActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const allChartTypes = computed<TypeAndDisplayName[]>(() => {
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
return getAllCategoricalChartTypes();
+18 -12
View File
@@ -17,7 +17,7 @@
</template>
<template #title>
<div class="display-flex">
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half">Tag Name</div>
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half">Tag Name</div>
</div>
</template>
</f7-list-item>
@@ -46,11 +46,11 @@
</template>
<template #title>
<div class="display-flex">
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half"
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half"
v-if="editingTag.id !== tag.id">
{{ tag.name }}
</div>
<f7-input class="list-title-input padding-left-half"
<f7-input class="list-title-input padding-inline-start-half"
type="text"
:placeholder="tt('Tag Title')"
v-else-if="editingTag.id === tag.id"
@@ -67,7 +67,7 @@
v-if="editingTag.id === tag.id"
@click="save(editingTag)">
</f7-button>
<f7-button class="no-padding margin-left-half"
<f7-button class="no-padding margin-inline-start-half"
raised fill
icon-f7="xmark"
color="gray"
@@ -75,15 +75,19 @@
@click="cancelSave(editingTag)">
</f7-button>
</template>
<f7-swipeout-actions left v-if="sortable && editingTag.id !== tag.id">
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable && editingTag.id !== tag.id">
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(tag, !tag.hidden)">
<f7-icon :f7="tag.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable && editingTag.id !== tag.id">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable && editingTag.id !== tag.id">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(tag)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(tag, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(tag, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -95,7 +99,7 @@
</template>
<template #title>
<div class="display-flex">
<f7-input class="list-title-input padding-left-half"
<f7-input class="list-title-input padding-inline-start-half"
type="text"
:placeholder="tt('Tag Title')"
v-model:value="newTag.name"
@@ -110,7 +114,7 @@
color="blue"
@click="save(newTag)">
</f7-button>
<f7-button class="no-padding margin-left-half"
<f7-button class="no-padding margin-inline-start-half"
raised fill
icon-f7="xmark"
color="gray"
@@ -152,6 +156,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { TextDirection } from '@/core/text.ts';
import { TransactionTag } from '@/models/transaction_tag.ts';
import {
@@ -164,7 +169,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const transactionTagsStore = useTransactionTagsStore();
@@ -181,6 +186,7 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
@@ -413,7 +419,7 @@ init();
<style>
.tag-item-list.list .item-media + .item-inner {
margin-left: 5px;
margin-inline-start: 5px;
}
.transaction-tag-list-item-content {
+11 -5
View File
@@ -46,15 +46,19 @@
</f7-badge>
</f7-icon>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(template, !template.hidden)">
<f7-icon :f7="template.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(template)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(template, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(template, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -93,6 +97,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
import { TextDirection } from '@/core/text.ts';
import { TemplateType } from '@/core/template.ts';
import { TransactionTemplate } from '@/models/transaction_template.ts';
@@ -108,7 +113,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const transactionTemplatesStore = useTransactionTemplatesStore();
@@ -124,6 +129,7 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const templates = computed<TransactionTemplate[]>(() => transactionTemplatesStore.allTransactionTemplates[templateType.value] || []);
const firstShowingId = computed<string | null>(() => getFirstShowingId(templates.value, showHidden.value));
const lastShowingId = computed<string | null>(() => getLastShowingId(templates.value, showHidden.value));
+8 -8
View File
@@ -105,7 +105,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableExpenseCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableExpenseCategories">
@@ -137,7 +137,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableIncomeCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableIncomeCategories">
@@ -169,7 +169,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableTransferCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableTransferCategories">
@@ -1252,8 +1252,8 @@ init();
<style>
.category-separate-icon.icon {
margin-left: 5px;
margin-right: 5px;
margin-inline-start: 5px;
margin-inline-end: 5px;
font-size: var(--ebk-category-separate-icon-font-size);
line-height: 16px;
color: var(--f7-color-gray-tint);
@@ -1292,19 +1292,19 @@ init();
}
.transaction-edit-timezone-name {
padding-left: 4px;
padding-inline-start: 4px;
}
.transaction-edit-tag {
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
margin-right: 4px;
margin-inline-end: 4px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.chip.transaction-edit-tag .chip-media+.chip-label {
margin-left: 0;
margin-inline-start: 0;
}
.chip.transaction-edit-tag .chip-media i.icon {
+31 -17
View File
@@ -47,13 +47,13 @@
<f7-toolbar tabbar bottom class="toolbar-item-auto-size transaction-list-toolbar">
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, -1)">
<f7-icon f7="arrow_left_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': loading }" popover-open=".date-popover-menu">
<span :class="{ 'tabbar-item-changed': query.dateType !== DateRange.All.type }">{{ queryDateRangeName }}</span>
</f7-link>
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, 1)">
<f7-icon f7="arrow_right_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
</f7-link>
<f7-link class="tabbar-text-with-ellipsis" popover-open=".category-popover-menu" :class="{ 'disabled': query.type === 1 }">
<span :class="{ 'tabbar-item-changed': query.categoryIds }">{{ queryCategoryName }}</span>
@@ -285,14 +285,15 @@
<span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(transaction)})` }}</span>
<span v-if="transaction.sourceAccount">·</span>
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
<f7-icon f7="arrow_right" class="transaction-account-arrow" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
<f7-icon class="transaction-account-arrow icon-with-direction" f7="arrow_right" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
<span v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id">{{ transaction.destinationAccount.name }}</span>
</div>
</div>
</div>
</div>
</template>
<f7-swipeout-actions right>
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR">
<f7-swipeout-button color="primary" close
:text="tt('Duplicate')"
v-if="transaction.type !== TransactionType.ModifyBalance"
@@ -301,7 +302,7 @@
:text="tt('Edit')"
v-if="transaction.editable"
@click="edit(transaction)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
v-if="transaction.editable"
@click="remove(transaction, false)">
<f7-icon f7="trash"></f7-icon>
@@ -398,7 +399,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content>
<f7-list dividers class="padding-left">
<f7-list dividers class="padding-inline-start">
<f7-list-item :class="{ 'list-item-selected': query.categoryIds === category.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[category.id] }"
:title="tt('All')" @click="changeCategoryFilter(category.id)">
<template #media>
@@ -520,7 +521,7 @@
v-for="filterType in AmountFilterType.values()"
@click="changeAmountFilter(filterType.type)">
<template #after>
<span class="margin-right-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
<span class="margin-inline-end-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)"></f7-icon>
</template>
</f7-list-item>
@@ -617,6 +618,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
import type { TypeAndDisplayName } from '@/core/base.ts';
import { TextDirection } from '@/core/text.ts';
import {
type TimeRangeAndDateType,
DateRangeScene,
@@ -662,6 +664,7 @@ const props = defineProps<{
const {
tt,
getCurrentLanguageTextDirection,
getAllShortWeekdayNames,
getAllTransactionTagFilterTypes,
getWeekdayShortName
@@ -739,6 +742,7 @@ const showCustomDateRangeSheet = ref<boolean>(false);
const showCustomMonthSheet = ref<boolean>(false);
const showDeleteActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
@@ -1511,7 +1515,7 @@ init();
<style>
.transaction-list-toolbar .toolbar-inner {
padding-right: 8px;
padding-inline-end: 8px;
}
.list.transaction-amount-list .transaction-amount-statistics {
@@ -1520,17 +1524,17 @@ init();
}
.list.transaction-amount-list .transaction-amount-statistics > span {
margin-left: 8px;
margin-inline-start: 8px;
font-weight: normal;
}
.list.transaction-info-list li.transaction-info .item-media + .item-inner {
margin-left: 0;
margin-inline-start: 0;
}
.list.transaction-info-list li.transaction-info .actual-item-inner {
width: 100%;
margin-left: 10px;
margin-inline-start: 10px;
overflow: hidden;
}
@@ -1540,7 +1544,7 @@ init();
.list.transaction-info-list li.transaction-info .transaction-date {
width: var(--ebk-transaction-date-width);
margin-right: 6px;
margin-inline-end: 6px;
}
.list.transaction-info-list li.transaction-info .transaction-day {
@@ -1550,6 +1554,10 @@ init();
text-align: left;
}
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-day {
text-align: right;
}
.list.transaction-info-list li.transaction-info .transaction-day-of-week {
opacity: 0.6;
font-size: var(--ebk-transaction-day-of-week-font-size);
@@ -1569,14 +1577,14 @@ init();
--f7-chip-height: var(--ebk-transaction-tag-chip-height);
--f7-chip-text-color: var(--f7-list-item-footer-text-color);
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
margin-right: 4px;
margin-inline-end: 4px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.list.transaction-info-list li.transaction-info .chip.transaction-tag .chip-media+.chip-label {
margin-left: 0;
margin-inline-start: 0;
}
.list.transaction-info-list li.transaction-info .transaction-footer {
@@ -1588,15 +1596,21 @@ init();
}
.list.transaction-info-list li.transaction-info .transaction-footer > span {
margin-right: 4px;
unicode-bidi: isolate;
margin-inline-end: 4px;
}
.list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
font-size: var(--ebk-transaction-account-arrow-font-size);
margin-right: 4px;
margin-inline-end: 4px;
margin-top: var(--ebk-transaction-account-arrow-margin-top);
}
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
margin-inline-end: 0;
margin-inline-start: 4px;
}
.list.transaction-info-list li.transaction-info .transaction-amount {
color: var(--f7-list-item-after-text-color);
overflow: hidden;
@@ -1613,7 +1627,7 @@ init();
}
.more-popover-menu .transaction-tag-name {
padding-right: 4px;
padding-inline-end: 4px;
font-size: var(--f7-list-item-title-font-size);
}
@@ -184,6 +184,6 @@ reloadUserDataStatistics();
<style>
.export-file-type-list.list > ul > li > .item-content {
padding-left: 0;
padding-inline-start: 0;
}
</style>
+7 -2
View File
@@ -34,7 +34,9 @@
<template #after>
<small>{{ session.lastSeenDateTime }}</small>
</template>
<f7-swipeout-actions right v-if="!session.isCurrent">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!session.isCurrent">
<f7-swipeout-button color="red" :text="tt('Log Out')" @click="revoke(session)"></f7-swipeout-button>
</f7-swipeout-actions>
</f7-list-item>
@@ -51,6 +53,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTokensStore } from '@/stores/token.ts';
import { TextDirection } from '@/core/text.ts';
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
import { isEquals } from '@/lib/common.ts';
@@ -73,7 +76,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, formatUnixTimeToLongDateTime } = useI18n();
const { tt, getCurrentLanguageTextDirection, formatUnixTimeToLongDateTime } = useI18n();
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
const tokensStore = useTokensStore();
@@ -82,6 +85,8 @@ const tokens = ref<TokenInfoResponse[]>([]);
const loading = ref<boolean>(true);
const loadingError = ref<unknown | null>(null);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const sessions = computed<MobilePageSessionInfo[]>(() => {
const sessions: MobilePageSessionInfo[] = [];
+16 -2
View File
@@ -526,6 +526,7 @@ import { useRootStore } from '@/stores/index.ts';
import { useUserStore } from '@/stores/user.ts';
import { useAccountsStore } from '@/stores/account.ts';
import { TextDirection } from '@/core/text.ts';
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
import type { UserProfileResponse } from '@/models/user.ts';
@@ -538,7 +539,15 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getAllLanguageOptions, getAllCurrencies, getCurrencyName, formatFiscalYearStartToLongDay } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getAllLanguageOptions,
getAllCurrencies,
getCurrencyName,
formatFiscalYearStartToLongDay
} = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -661,6 +670,8 @@ function save(): void {
return;
}
const oldTextDirection: TextDirection = getCurrentLanguageTextDirection();
saving.value = true;
showLoading(() => saving.value);
@@ -671,7 +682,10 @@ function save(): void {
doAfterProfileUpdate(response.user);
showToast('Your profile has been successfully updated');
router.back();
if (oldTextDirection === getCurrentLanguageTextDirection()) {
router.back(); // if text direction is changed, the page will be reloaded, so it don't need to go back
}
}).catch(error => {
saving.value = false;
hideLoading();