mobile version supports rtl
This commit is contained in:
@@ -363,13 +363,13 @@ function toggleLegend(legend: TrendsBarChartLegend): void {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.monthly-trends-bar-chart-legend {
|
.monthly-trends-bar-chart-legend {
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monthly-trends-bar-chart-legend-icon.f7-icons {
|
.monthly-trends-bar-chart-legend-icon.f7-icons {
|
||||||
font-size: var(--ebk-trends-bar-chart-legend-icon-font-size);
|
font-size: var(--ebk-trends-bar-chart-legend-icon-font-size);
|
||||||
margin-right: 2px;
|
margin-inline-end: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monthly-trends-bar-chart-legend-unselected .monthly-trends-bar-chart-legend-icon.f7-icons {
|
.monthly-trends-bar-chart-legend-unselected .monthly-trends-bar-chart-legend-icon.f7-icons {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
|
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
|
||||||
<span class="numpad-button-text numpad-button-text-normal">
|
<span class="numpad-button-text numpad-button-text-normal">
|
||||||
<f7-icon f7="delete_left"></f7-icon>
|
<f7-icon class="icon-with-direction" f7="delete_left"></f7-icon>
|
||||||
</span>
|
</span>
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="numpad-button numpad-button-confirm no-right-border no-bottom-border" fill @click="confirm()">
|
<f7-button class="numpad-button numpad-button-confirm no-right-border no-bottom-border" fill @click="confirm()">
|
||||||
@@ -400,7 +400,7 @@ watch(() => props.flipNegative, (newValue) => {
|
|||||||
.numpad-value {
|
.numpad-value {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 16px;
|
padding-inline-start: 16px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
height: var(--ebk-numpad-value-height);
|
height: var(--ebk-numpad-value-height);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<div class="pie-chart-toolbox-container padding-horizontal" v-if="showSelectedItemInfo">
|
<div class="pie-chart-toolbox-container padding-horizontal" v-if="showSelectedItemInfo">
|
||||||
<div class="pie-chart-toolbox">
|
<div class="pie-chart-toolbox">
|
||||||
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(1)">
|
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(1)">
|
||||||
<f7-icon f7="arrow_left"></f7-icon>
|
<f7-icon class="icon-with-direction" f7="arrow_left"></f7-icon>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
|
|
||||||
<div class="pie-chart-toolbox-info">
|
<div class="pie-chart-toolbox-info">
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<span v-else-if="!skeleton && selectedItem.displayName">{{ selectedItem.displayName }}</span>
|
<span v-else-if="!skeleton && selectedItem.displayName">{{ selectedItem.displayName }}</span>
|
||||||
<span class="skeleton-text" v-if="skeleton">Value</span>
|
<span class="skeleton-text" v-if="skeleton">Value</span>
|
||||||
<span v-else-if="!skeleton && showValue" :style="getColorStyle(selectedItem ? selectedItem.color : '')">{{ selectedItem.displayValue }}</span>
|
<span v-else-if="!skeleton && showValue" :style="getColorStyle(selectedItem ? selectedItem.color : '')">{{ selectedItem.displayValue }}</span>
|
||||||
<f7-icon class="item-navigate-icon" f7="chevron_right" v-if="enableClickItem"></f7-icon>
|
<f7-icon class="item-navigate-icon icon-with-direction" f7="chevron_right" v-if="enableClickItem"></f7-icon>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
<f7-link :no-link-class="true" v-else-if="!validItems || !validItems.length">
|
<f7-link :no-link-class="true" v-else-if="!validItems || !validItems.length">
|
||||||
{{ tt('No transaction data') }}
|
{{ tt('No transaction data') }}
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(-1)">
|
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(-1)">
|
||||||
<f7-icon f7="arrow_right"></f7-icon>
|
<f7-icon class="icon-with-direction" f7="arrow_right"></f7-icon>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -264,14 +264,14 @@ function clickItem(item: CommonPieChartDataItem): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pie-chart-toolbox-info a > span + span {
|
.pie-chart-toolbox-info a > span + span {
|
||||||
padding-left: 8px;
|
padding-inline-start: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pie-chart-toolbox-info .item-navigate-icon {
|
.pie-chart-toolbox-info .item-navigate-icon {
|
||||||
color: rgba(0, 0, 0, 0.2);
|
color: rgba(0, 0, 0, 0.2);
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding-left: 4px;
|
padding-inline-start: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pie-chart-toolbox-button {
|
.pie-chart-toolbox-button {
|
||||||
|
|||||||
@@ -82,13 +82,13 @@ watch(() => props.modelValue, (newValue) => {
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.list-item-pincode-input .item-content {
|
.list-item-pincode-input .item-content {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
padding-right: 0;
|
padding-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-item-pincode-input .item-content .item-inner {
|
.list-item-pincode-input .item-content .item-inner {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
padding-right: 0;
|
padding-inline-end: 0;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
v-for="type in allTransactionScheduledFrequencyTypes"
|
v-for="type in allTransactionScheduledFrequencyTypes"
|
||||||
@click="changeFrequencyType(type.type)">
|
@click="changeFrequencyType(type.type)">
|
||||||
<template #after>
|
<template #after>
|
||||||
<f7-icon class="list-item-showing" f7="chevron_right" v-if="currentFrequencyType === type.type"></f7-icon>
|
<f7-icon class="list-item-showing icon-with-direction" f7="chevron_right" v-if="currentFrequencyType === type.type"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
</f7-list>
|
</f7-list>
|
||||||
@@ -165,10 +165,10 @@ function onSheetClosed(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.schedule-frequency-type-list.list .item-inner {
|
.schedule-frequency-type-list.list .item-inner {
|
||||||
padding-right: 6px;
|
padding-inline-end: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.schedule-frequency-value-list-list.list .item-content {
|
.schedule-frequency-value-list-list.list .item-content {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<f7-block class="no-padding no-margin">
|
<f7-block class="no-padding no-margin">
|
||||||
<div class="display-flex">
|
<div class="display-flex">
|
||||||
<f7-icon class="transaction-tag-icon" f7="number"></f7-icon>
|
<f7-icon class="transaction-tag-icon" f7="number"></f7-icon>
|
||||||
<div class="tag-selection-list-item list-item-valign-middle padding-left-half">
|
<div class="tag-selection-list-item list-item-valign-middle padding-inline-start-half">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="display-flex">
|
<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"
|
type="text"
|
||||||
:placeholder="tt('Tag Title')"
|
:placeholder="tt('Tag Title')"
|
||||||
v-model:value="newTag.name"
|
v-model:value="newTag.name"
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
color="blue"
|
color="blue"
|
||||||
@click="saveNewTag()">
|
@click="saveNewTag()">
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="no-padding margin-left-half"
|
<f7-button class="no-padding margin-inline-start-half"
|
||||||
raised fill
|
raised fill
|
||||||
icon-f7="xmark"
|
icon-f7="xmark"
|
||||||
color="gray"
|
color="gray"
|
||||||
@@ -261,7 +261,7 @@ function onSheetClosed(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tag-selection-list.list .item-media + .item-inner {
|
.tag-selection-list.list .item-media + .item-inner {
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-selection-list-item {
|
.tag-selection-list-item {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? item[primaryIconField] : undefined" :color="primaryColorField ? item[primaryColorField] : undefined"></ItemIcon>
|
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? item[primaryIconField] : undefined" :color="primaryColorField ? item[primaryColorField] : undefined"></ItemIcon>
|
||||||
</template>
|
</template>
|
||||||
<template #after>
|
<template #after>
|
||||||
<f7-icon class="list-item-showing" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
|
<f7-icon class="list-item-showing icon-with-direction" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
<f7-list-item v-if="!filteredItems || !filteredItems.length"
|
<f7-list-item v-if="!filteredItems || !filteredItems.length"
|
||||||
@@ -160,10 +160,10 @@ function onSheetClosed(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.primary-list.list .item-inner {
|
.primary-list.list .item-inner {
|
||||||
padding-right: 6px;
|
padding-inline-end: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.secondary-list.list .item-content {
|
.secondary-list.list .item-content {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
} from '@/core/setting.ts';
|
} from '@/core/setting.ts';
|
||||||
|
|
||||||
const settingsLocalStorageKey: string = 'ebk_app_settings';
|
const settingsLocalStorageKey: string = 'ebk_app_settings';
|
||||||
|
const currentLanguageSessionStorageKey: string = 'ebk_current_language';
|
||||||
|
|
||||||
function getStoredApplicationSettings(): BaseApplicationSetting {
|
function getStoredApplicationSettings(): BaseApplicationSetting {
|
||||||
try {
|
try {
|
||||||
@@ -101,3 +102,16 @@ export function isEnableAnimate(): boolean {
|
|||||||
export function clearSettings(): void {
|
export function clearSettings(): void {
|
||||||
localStorage.removeItem(settingsLocalStorageKey);
|
localStorage.removeItem(settingsLocalStorageKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSessionCurrentLanguageKey(): string {
|
||||||
|
return sessionStorage.getItem(currentLanguageSessionStorageKey) || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setSessionCurrentLanguageKey(languageKey: string): void {
|
||||||
|
if (!languageKey) {
|
||||||
|
sessionStorage.removeItem(currentLanguageSessionStorageKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionStorage.setItem(currentLanguageSessionStorageKey, languageKey);
|
||||||
|
}
|
||||||
|
|||||||
+38
-31
@@ -4,6 +4,7 @@ import type { Dialog, Picker, Router } from 'framework7/types';
|
|||||||
|
|
||||||
import { useI18n } from '@/locales/helpers.ts';
|
import { useI18n } from '@/locales/helpers.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
||||||
import { getNumberValue } from '../common.ts';
|
import { getNumberValue } from '../common.ts';
|
||||||
import { isEnableAnimate } from '../settings.ts';
|
import { isEnableAnimate } from '../settings.ts';
|
||||||
@@ -195,7 +196,7 @@ export function onInfiniteScrolling(callback: (e: Event) => void): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useI18nUIComponents() {
|
export function useI18nUIComponents() {
|
||||||
const { tt, te } = useI18n();
|
const { tt, te, getCurrentLanguageTextDirection } = useI18n();
|
||||||
|
|
||||||
function routeBackOnError<T>(f7router: Router.Router, errorRef: Ref<T>): void {
|
function routeBackOnError<T>(f7router: Router.Router, errorRef: Ref<T>): void {
|
||||||
const unwatch = watch(errorRef, (newValue) => {
|
const unwatch = watch(errorRef, (newValue) => {
|
||||||
@@ -230,52 +231,58 @@ export function useI18nUIComponents() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function showConfirm(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (dialog: Dialog.Dialog, e: Event) => void): void {
|
function showConfirm(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (dialog: Dialog.Dialog, e: Event) => void): void {
|
||||||
|
const textDirection = getCurrentLanguageTextDirection();
|
||||||
|
|
||||||
|
const cancelButton: Dialog.DialogButton = {
|
||||||
|
text: tt('Cancel'),
|
||||||
|
onClick: cancelCallback
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmButton: Dialog.DialogButton = {
|
||||||
|
text: tt('OK'),
|
||||||
|
onClick: confirmCallback
|
||||||
|
};
|
||||||
|
|
||||||
f7ready((f7) => {
|
f7ready((f7) => {
|
||||||
f7.dialog.create({
|
f7.dialog.create({
|
||||||
title: tt('global.app.title'),
|
title: tt('global.app.title'),
|
||||||
text: tt(message),
|
text: tt(message),
|
||||||
animate: isEnableAnimate(),
|
animate: isEnableAnimate(),
|
||||||
buttons: [
|
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
|
||||||
{
|
|
||||||
text: tt('Cancel'),
|
|
||||||
onClick: cancelCallback
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: tt('OK'),
|
|
||||||
onClick: confirmCallback
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).open();
|
}).open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function showPrompt(message: string, currentValue?: string, confirmCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void): void {
|
function showPrompt(message: string, currentValue?: string, confirmCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void): void {
|
||||||
|
const textDirection = getCurrentLanguageTextDirection();
|
||||||
|
|
||||||
|
const cancelButton: Dialog.DialogButton = {
|
||||||
|
text: tt('Cancel'),
|
||||||
|
onClick: (dialog, event) => {
|
||||||
|
if (cancelCallback) {
|
||||||
|
const inputValue = dialog.$el.find('.dialog-input').val();
|
||||||
|
cancelCallback(inputValue, dialog, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmButton: Dialog.DialogButton = {
|
||||||
|
text: tt('OK'),
|
||||||
|
onClick: (dialog, event) => {
|
||||||
|
if (confirmCallback) {
|
||||||
|
const inputValue = dialog.$el.find('.dialog-input').val();
|
||||||
|
confirmCallback(inputValue, dialog, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
f7ready((f7) => {
|
f7ready((f7) => {
|
||||||
f7.dialog.create({
|
f7.dialog.create({
|
||||||
title: tt('global.app.title'),
|
title: tt('global.app.title'),
|
||||||
text: tt(message),
|
text: tt(message),
|
||||||
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
|
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
|
||||||
animate: isEnableAnimate(),
|
animate: isEnableAnimate(),
|
||||||
buttons: [
|
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
|
||||||
{
|
|
||||||
text: tt('Cancel'),
|
|
||||||
onClick: (dialog, event) => {
|
|
||||||
if (cancelCallback) {
|
|
||||||
const inputValue = dialog.$el.find('.dialog-input').val();
|
|
||||||
cancelCallback(inputValue, dialog, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: tt('OK'),
|
|
||||||
onClick: (dialog, event) => {
|
|
||||||
if (confirmCallback) {
|
|
||||||
const inputValue = dialog.$el.find('.dialog-input').val();
|
|
||||||
confirmCallback(inputValue, dialog, event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}).open();
|
}).open();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-4
@@ -190,6 +190,11 @@ import {
|
|||||||
getAllFilteredAccountsBalance
|
getAllFilteredAccountsBalance
|
||||||
} from '@/lib/account.ts';
|
} from '@/lib/account.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
getSessionCurrentLanguageKey,
|
||||||
|
setSessionCurrentLanguageKey
|
||||||
|
} from '@/lib/settings.ts';
|
||||||
|
|
||||||
import services from '@/lib/services.ts';
|
import services from '@/lib/services.ts';
|
||||||
import logger from '@/lib/logger.ts';
|
import logger from '@/lib/logger.ts';
|
||||||
|
|
||||||
@@ -1961,13 +1966,30 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setSessionCurrentLanguageKey(languageKey);
|
||||||
services.setLocale(languageKey);
|
services.setLocale(languageKey);
|
||||||
document.querySelector('html')?.setAttribute('lang', languageKey);
|
document.querySelector('html')?.setAttribute('lang', languageKey);
|
||||||
|
|
||||||
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
if (document.querySelector('html')?.getAttribute('data-dir-mode') === 'isolate') {
|
||||||
document.querySelector('html')?.removeAttribute('dir');
|
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
||||||
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
|
if (location.search.includes('rtl')) {
|
||||||
document.querySelector('html')?.setAttribute('dir', 'rtl');
|
const url = new URL(window.location.href);
|
||||||
|
url.search = '';
|
||||||
|
window.location.replace(url.toString());
|
||||||
|
}
|
||||||
|
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
|
||||||
|
if (!location.search.includes('rtl')) {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.searchParams.set('rtl', '');
|
||||||
|
window.location.replace(url.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
||||||
|
document.querySelector('html')?.removeAttribute('dir');
|
||||||
|
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
|
||||||
|
document.querySelector('html')?.setAttribute('dir', 'rtl');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultCurrency = getDefaultCurrency();
|
const defaultCurrency = getDefaultCurrency();
|
||||||
@@ -2003,11 +2025,15 @@ export function useI18n() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initLocale(lastUserLanguage?: string, timezone?: string): LocaleDefaultSettings | null {
|
function initLocale(lastUserLanguage?: string, timezone?: string): LocaleDefaultSettings | null {
|
||||||
|
const sessionLanguageKey: string = getSessionCurrentLanguageKey();
|
||||||
let localeDefaultSettings: LocaleDefaultSettings | null = null;
|
let localeDefaultSettings: LocaleDefaultSettings | null = null;
|
||||||
|
|
||||||
if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
|
if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
|
||||||
logger.info(`Last user language is ${lastUserLanguage}`);
|
logger.info(`Last user language is ${lastUserLanguage}`);
|
||||||
localeDefaultSettings = setLanguage(lastUserLanguage, true);
|
localeDefaultSettings = setLanguage(lastUserLanguage, true);
|
||||||
|
} else if (sessionLanguageKey && getLanguageInfo(sessionLanguageKey)) {
|
||||||
|
logger.info(`Session language is ${sessionLanguageKey}`);
|
||||||
|
localeDefaultSettings = setLanguage(sessionLanguageKey, true);
|
||||||
} else {
|
} else {
|
||||||
localeDefaultSettings = setLanguage(null, true);
|
localeDefaultSettings = setLanguage(null, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@import 'framework7/css';
|
||||||
|
@import 'framework7/components/dialog/css';
|
||||||
|
@import 'framework7/components/popup/css';
|
||||||
|
@import 'framework7/components/login-screen/css';
|
||||||
|
@import 'framework7/components/popover/css';
|
||||||
|
@import 'framework7/components/actions/css';
|
||||||
|
@import 'framework7/components/sheet/css';
|
||||||
|
@import 'framework7/components/notification/css';
|
||||||
|
@import 'framework7/components/toast/css';
|
||||||
|
@import 'framework7/components/preloader/css';
|
||||||
|
@import 'framework7/components/progressbar/css';
|
||||||
|
@import 'framework7/components/sortable/css';
|
||||||
|
@import 'framework7/components/swipeout/css';
|
||||||
|
@import 'framework7/components/accordion/css';
|
||||||
|
@import 'framework7/components/card/css';
|
||||||
|
@import 'framework7/components/chip/css';
|
||||||
|
@import 'framework7/components/form/css';
|
||||||
|
@import 'framework7/components/input/css';
|
||||||
|
@import 'framework7/components/checkbox/css';
|
||||||
|
@import 'framework7/components/radio/css';
|
||||||
|
@import 'framework7/components/toggle/css';
|
||||||
|
@import 'framework7/components/range/css';
|
||||||
|
@import 'framework7/components/grid/css';
|
||||||
|
@import 'framework7/components/picker/css';
|
||||||
|
@import 'framework7/components/infinite-scroll/css';
|
||||||
|
@import 'framework7/components/pull-to-refresh/css';
|
||||||
|
@import 'framework7/components/searchbar/css';
|
||||||
|
@import 'framework7/components/tooltip/css';
|
||||||
|
@import 'framework7/components/skeleton/css';
|
||||||
|
@import 'framework7/components/treeview/css';
|
||||||
|
@import 'framework7/components/typography/css';
|
||||||
|
@import 'framework7/components/swiper/css';
|
||||||
|
@import 'framework7/components/photo-browser/css';
|
||||||
+9
-43
@@ -39,40 +39,6 @@ import Framework7PhotoBrowser from 'framework7/components/photo-browser';
|
|||||||
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
|
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
|
||||||
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
|
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
|
||||||
|
|
||||||
import 'framework7/css';
|
|
||||||
import 'framework7/components/dialog/css';
|
|
||||||
import 'framework7/components/popup/css';
|
|
||||||
import 'framework7/components/login-screen/css';
|
|
||||||
import 'framework7/components/popover/css';
|
|
||||||
import 'framework7/components/actions/css';
|
|
||||||
import 'framework7/components/sheet/css';
|
|
||||||
import 'framework7/components/notification/css';
|
|
||||||
import 'framework7/components/toast/css';
|
|
||||||
import 'framework7/components/preloader/css';
|
|
||||||
import 'framework7/components/progressbar/css';
|
|
||||||
import 'framework7/components/sortable/css';
|
|
||||||
import 'framework7/components/swipeout/css';
|
|
||||||
import 'framework7/components/accordion/css';
|
|
||||||
import 'framework7/components/card/css';
|
|
||||||
import 'framework7/components/chip/css';
|
|
||||||
import 'framework7/components/form/css';
|
|
||||||
import 'framework7/components/input/css';
|
|
||||||
import 'framework7/components/checkbox/css';
|
|
||||||
import 'framework7/components/radio/css';
|
|
||||||
import 'framework7/components/toggle/css';
|
|
||||||
import 'framework7/components/range/css';
|
|
||||||
import 'framework7/components/grid/css';
|
|
||||||
import 'framework7/components/picker/css';
|
|
||||||
import 'framework7/components/infinite-scroll/css';
|
|
||||||
import 'framework7/components/pull-to-refresh/css';
|
|
||||||
import 'framework7/components/searchbar/css';
|
|
||||||
import 'framework7/components/tooltip/css';
|
|
||||||
import 'framework7/components/skeleton/css';
|
|
||||||
import 'framework7/components/treeview/css';
|
|
||||||
import 'framework7/components/typography/css';
|
|
||||||
import 'framework7/components/swiper/css';
|
|
||||||
import 'framework7/components/photo-browser/css';
|
|
||||||
|
|
||||||
import 'framework7-icons';
|
import 'framework7-icons';
|
||||||
import 'line-awesome/dist/line-awesome/css/line-awesome.css';
|
import 'line-awesome/dist/line-awesome/css/line-awesome.css';
|
||||||
|
|
||||||
@@ -113,15 +79,15 @@ import AccountBalanceTrendsBarChart from '@/components/mobile/AccountBalanceTren
|
|||||||
|
|
||||||
import TextareaAutoSize from '@/directives/mobile/textareaAutoSize.ts';
|
import TextareaAutoSize from '@/directives/mobile/textareaAutoSize.ts';
|
||||||
|
|
||||||
import '@/styles/mobile/global.css';
|
import '@/styles/mobile/global.scss';
|
||||||
import '@/styles/mobile/font-size-default.css';
|
import '@/styles/mobile/font-size-default.scss';
|
||||||
import '@/styles/mobile/font-size-small.css';
|
import '@/styles/mobile/font-size-small.scss';
|
||||||
import '@/styles/mobile/font-size-large.css';
|
import '@/styles/mobile/font-size-large.scss';
|
||||||
import '@/styles/mobile/font-size-x-large.css';
|
import '@/styles/mobile/font-size-x-large.scss';
|
||||||
import '@/styles/mobile/font-size-xx-large.css';
|
import '@/styles/mobile/font-size-xx-large.scss';
|
||||||
import '@/styles/mobile/font-size-xxx-large.css';
|
import '@/styles/mobile/font-size-xxx-large.scss';
|
||||||
import '@/styles/mobile/font-size-xxxx-large.css';
|
import '@/styles/mobile/font-size-xxxx-large.scss';
|
||||||
import '@/styles/mobile/amount-color.css';
|
import '@/styles/mobile/amount-color.scss';
|
||||||
|
|
||||||
import App from '@/MobileApp.vue';
|
import App from '@/MobileApp.vue';
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
@import '../node_modules/framework7/framework7-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/dialog/dialog-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/popup/popup-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/login-screen/login-screen-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/popover/popover-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/actions/actions-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/sheet/sheet-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/notification/notification-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/toast/toast-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/preloader/preloader-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/progressbar/progressbar-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/sortable/sortable-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/swipeout/swipeout-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/accordion/accordion-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/card/card-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/chip/chip-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/form/form-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/input/input-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/checkbox/checkbox-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/radio/radio-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/toggle/toggle-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/range/range-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/grid/grid-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/picker/picker-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/infinite-scroll/infinite-scroll-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/pull-to-refresh/pull-to-refresh-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/searchbar/searchbar-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/tooltip/tooltip-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/skeleton/skeleton-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/treeview/treeview-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/typography/typography-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/swiper/swiper-rtl.css';
|
||||||
|
@import '../node_modules/framework7/components/photo-browser/photo-browser-rtl.css';
|
||||||
@@ -58,6 +58,18 @@
|
|||||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png">
|
<link rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png">
|
||||||
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/8.3__iPad_Mini_portrait.png">
|
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/8.3__iPad_Mini_portrait.png">
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
|
<link id="framework7-css" rel="stylesheet" crossorigin>
|
||||||
|
<script>
|
||||||
|
document.querySelector('html').setAttribute('data-dir-mode', 'isolate');
|
||||||
|
|
||||||
|
if (location.search.includes('rtl')) {
|
||||||
|
document.querySelector('html').setAttribute('dir', 'rtl');
|
||||||
|
document.getElementById('framework7-css').href = '{{framework7-rtl-css-filepath}}';
|
||||||
|
} else {
|
||||||
|
document.querySelector('html').removeAttribute('dir');
|
||||||
|
document.getElementById('framework7-css').href = '{{framework7-ltr-css-filepath}}';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<script src="./server_settings.js"></script>
|
<script src="./server_settings.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -21,6 +21,38 @@ input[type=number] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Common class **/
|
/** Common class **/
|
||||||
|
.margin-inline-start {
|
||||||
|
margin-inline-start: var(--f7-typography-margin) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-inline-start-half {
|
||||||
|
margin-inline-start: calc(var(--f7-typography-margin) / 2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-inline-end {
|
||||||
|
margin-inline-end: var(--f7-typography-margin) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-inline-end-half {
|
||||||
|
margin-inline-end: calc(var(--f7-typography-margin) / 2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-inline-start {
|
||||||
|
padding-inline-start: var(--f7-typography-padding) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-inline-start-half {
|
||||||
|
padding-inline-start: calc(var(--f7-typography-padding) / 2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-inline-end {
|
||||||
|
padding-inline-end: var(--f7-typography-padding) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-inline-end-half {
|
||||||
|
padding-inline-end: calc(var(--f7-typography-padding) / 2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.no-right-border {
|
.no-right-border {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
@@ -234,6 +266,10 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] i.icon.icon-with-direction {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/** Replacing the default style of @vuepic/vue-datepicker **/
|
/** Replacing the default style of @vuepic/vue-datepicker **/
|
||||||
.dp__theme_light {
|
.dp__theme_light {
|
||||||
--dp-primary-color: #c67e48;
|
--dp-primary-color: #c67e48;
|
||||||
@@ -245,12 +281,12 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
|
|
||||||
/** Common class for replacing the default style of framework7 **/
|
/** Common class for replacing the default style of framework7 **/
|
||||||
.navbar .navbar-compact-icons.right a + a {
|
.navbar .navbar-compact-icons.right a + a {
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-item-auto-size .toolbar-inner {
|
.toolbar-item-auto-size .toolbar-inner {
|
||||||
padding-left: 16px;
|
padding-inline-start: 16px;
|
||||||
padding-right: 16px;
|
padding-inline-end: 16px;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,11 +438,22 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
.list .item-content .list-item-checked-icon {
|
.list .item-content .list-item-checked-icon {
|
||||||
font-size: var(--ebk-list-item-checked-icon-font-size);
|
font-size: var(--ebk-list-item-checked-icon-font-size);
|
||||||
color: var(--f7-radio-active-color, var(--f7-theme-color));
|
color: var(--f7-radio-active-color, var(--f7-theme-color));
|
||||||
margin-right: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
|
}
|
||||||
|
|
||||||
|
html:not([dir="rtl"]) .list .item-content .list-item-checked-icon {
|
||||||
|
margin-inline-end: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .list .item-content .list-item-checked-icon {
|
||||||
|
margin-inline-start: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
|
||||||
}
|
}
|
||||||
|
|
||||||
.list .item-content > .item-inner > .item-after .list-item-checked-icon {
|
.list .item-content > .item-inner > .item-after .list-item-checked-icon {
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .list .item-content > .item-inner > .item-after .list-item-checked-icon {
|
||||||
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list li.no-margin .item-content.item-input {
|
.list li.no-margin .item-content.item-input {
|
||||||
@@ -435,7 +482,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.icon-after-text {
|
.icon-after-text {
|
||||||
margin-left: 6px;
|
margin-inline-start: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-after-text i.icon {
|
.icon-after-text i.icon {
|
||||||
@@ -443,12 +490,22 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.badge.right-bottom-icon {
|
.badge.right-bottom-icon {
|
||||||
margin-left: -12px;
|
margin-inline-start: -12px;
|
||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .badge.right-bottom-icon {
|
||||||
|
left: unset;
|
||||||
|
right: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .icon.las .badge.right-bottom-icon {
|
||||||
|
right: 100%;
|
||||||
|
margin-inline-start: -14px;
|
||||||
|
}
|
||||||
|
|
||||||
.badge.right-bottom-icon > .icon {
|
.badge.right-bottom-icon > .icon {
|
||||||
font-size: var(--ebk-right-bottom-icon-font-size);
|
font-size: var(--ebk-right-bottom-icon-font-size);
|
||||||
width: var(--ebk-right-bottom-icon-font-size);
|
width: var(--ebk-right-bottom-icon-font-size);
|
||||||
@@ -472,7 +529,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
margin-left: -18px;
|
margin-inline-start: -18px;
|
||||||
margin-top: -8px;
|
margin-top: -8px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: #666
|
background: #666
|
||||||
@@ -493,19 +550,19 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list-item-with-multi-item .list-item-subitem:first-child .item-content {
|
.list-item-with-multi-item .list-item-subitem:first-child .item-content {
|
||||||
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-item-with-multi-item .list-item-subitem .item-inner {
|
.list-item-with-multi-item .list-item-subitem .item-inner {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
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));
|
||||||
padding-top: var(--f7-list-item-padding-vertical);
|
padding-top: var(--f7-list-item-padding-vertical);
|
||||||
padding-bottom: var(--f7-list-item-padding-vertical);
|
padding-bottom: var(--f7-list-item-padding-vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-item-with-multi-item .list-item-subitem:first-child .item-inner {
|
.list-item-with-multi-item .list-item-subitem:first-child .item-inner {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Combination list for framework7 **/
|
/** Combination list for framework7 **/
|
||||||
@@ -544,8 +601,12 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
border-radius: var(--f7-list-inset-border-radius);
|
border-radius: var(--f7-list-inset-border-radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
.combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
|
html:not([dir="rtl"]) .combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
|
||||||
|
margin-inline-end: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.combination-list-wrapper .list.combination-list-content.inset > ul {
|
.combination-list-wrapper .list.combination-list-content.inset > ul {
|
||||||
@@ -576,7 +637,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item.has-child-list-item .item-link .item-inner {
|
.nested-list-item.has-child-list-item .item-link .item-inner {
|
||||||
padding-right: 0;
|
padding-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item.has-child-list-item .item-link .item-inner:before {
|
.nested-list-item.has-child-list-item .item-link .item-inner:before {
|
||||||
@@ -589,7 +650,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
|
|
||||||
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner,
|
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner,
|
||||||
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-inner {
|
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-inner {
|
||||||
padding-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
|
padding-inline-end: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner:before {
|
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner:before {
|
||||||
@@ -603,13 +664,13 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
.nested-list-item .nested-list-item-title {
|
.nested-list-item .nested-list-item-title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
margin-right: var(--f7-list-item-media-margin);
|
margin-inline-end: var(--f7-list-item-media-margin);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item.has-child-list-item .nested-list-item-title {
|
.nested-list-item.has-child-list-item .nested-list-item-title {
|
||||||
margin-left: var(--f7-list-item-media-margin);
|
margin-inline-start: var(--f7-list-item-media-margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item .nested-list-item-after {
|
.nested-list-item .nested-list-item-after {
|
||||||
@@ -618,8 +679,8 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
display: flex;
|
display: flex;
|
||||||
font-size: var(--f7-list-item-after-font-size);
|
font-size: var(--f7-list-item-after-font-size);
|
||||||
color: var(--f7-list-item-after-text-color);
|
color: var(--f7-list-item-after-text-color);
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
padding-left: var(--f7-list-item-after-padding);
|
padding-inline-start: var(--f7-list-item-after-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nested-list-item.has-child-list-item > .swipeout-content > .item-content > .item-inner:after,
|
.nested-list-item.has-child-list-item > .swipeout-content > .item-content > .item-inner:after,
|
||||||
@@ -654,7 +715,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sortable-enabled .nested-list-item .nested-list-item-child .item-inner {
|
.sortable-enabled .nested-list-item .nested-list-item-child .item-inner {
|
||||||
padding-right: var(--f7-safe-area-right) !important;
|
padding-inline-end: var(--f7-safe-area-right) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Fix @vuepic/vue-datepicker style issue **/
|
/** Fix @vuepic/vue-datepicker style issue **/
|
||||||
@@ -683,6 +744,10 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[dir="rtl"] .dp__main .dp__btn.dp--arrow-btn-nav {
|
||||||
|
transform: scaleX(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* statistics-list */
|
/* statistics-list */
|
||||||
.statistics-list-item-overview-amount {
|
.statistics-list-item-overview-amount {
|
||||||
margin-top: 2px;
|
margin-top: 2px;
|
||||||
@@ -709,7 +774,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
.statistics-percent {
|
.statistics-percent {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
margin-left: 6px;
|
margin-inline-start: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics-item-end {
|
.statistics-item-end {
|
||||||
@@ -719,7 +784,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.statistics-percent-line {
|
.statistics-percent-line {
|
||||||
margin-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
|
margin-inline-end: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics-percent-line .progressbar {
|
.statistics-percent-line .progressbar {
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<p class="no-margin">
|
<p class="no-margin">
|
||||||
<span class="month-expense" v-if="loading">0.00 USD</span>
|
<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>
|
<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-icon class="ebk-hide-icon" :f7="showAmountInHomePage ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
</p>
|
</p>
|
||||||
@@ -314,11 +314,11 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.home-summary-misc > span {
|
.home-summary-misc > span {
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home-summary-misc > span:last-child {
|
.home-summary-misc > span:last-child {
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .home-summary-card {
|
.dark .home-summary-card {
|
||||||
@@ -348,7 +348,7 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.overview-transaction-list .overview-transaction-footer > span {
|
.overview-transaction-list .overview-transaction-footer > span {
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overview-transaction-list .overview-transaction-amount {
|
.overview-transaction-list .overview-transaction-amount {
|
||||||
|
|||||||
@@ -156,7 +156,7 @@
|
|||||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||||
</template>
|
</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>
|
||||||
<f7-list-item :title="subCategory.name"
|
<f7-list-item :title="subCategory.name"
|
||||||
:key="subIdx"
|
:key="subIdx"
|
||||||
|
|||||||
@@ -773,6 +773,6 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.subaccount-delete-button {
|
.subaccount-delete-button {
|
||||||
margin-left: auto;
|
margin-inline-start: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<p class="no-margin">
|
<p class="no-margin">
|
||||||
<span class="net-assets" v-if="loading">0.00 USD</span>
|
<span class="net-assets" v-if="loading">0.00 USD</span>
|
||||||
<span class="net-assets" v-else-if="!loading">{{ netAssets }}</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-icon class="ebk-hide-icon" :f7="showAccountBalance ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
</p>
|
</p>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<f7-list-item group-title :sortable="false">
|
<f7-list-item group-title :sortable="false">
|
||||||
<small>
|
<small>
|
||||||
<span>Account Category</span>
|
<span>Account Category</span>
|
||||||
<span style="margin-left: 10px">0.00 USD</span>
|
<span style="margin-inline-start: 10px">0.00 USD</span>
|
||||||
</small>
|
</small>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
<f7-list-item class="nested-list-item" after="0.00 USD" link="#"
|
<f7-list-item class="nested-list-item" after="0.00 USD" link="#"
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
<f7-list-item group-title :sortable="false">
|
<f7-list-item group-title :sortable="false">
|
||||||
<small>
|
<small>
|
||||||
<span>{{ tt(accountCategory.name) }}</span>
|
<span>{{ tt(accountCategory.name) }}</span>
|
||||||
<span style="margin-left: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
|
<span style="margin-inline-start: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
|
||||||
</small>
|
</small>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
<f7-list-item swipeout
|
<f7-list-item swipeout
|
||||||
@@ -137,16 +137,20 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
<f7-swipeout-actions left v-if="sortable">
|
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||||
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
: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)">
|
overswipe close @click="hide(account, !account.hidden)">
|
||||||
<f7-icon :f7="account.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
<f7-icon :f7="account.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</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="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="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-icon f7="trash"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
@@ -207,6 +211,7 @@ import { useAccountListPageBaseBase } from '@/views/base/accounts/AccountListPag
|
|||||||
|
|
||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||||
import type { Account, AccountShowingIds } from '@/models/account.ts';
|
import type { Account, AccountShowingIds } from '@/models/account.ts';
|
||||||
|
|
||||||
@@ -216,7 +221,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt } = useI18n();
|
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -244,6 +249,7 @@ const showMoreActionSheet = ref<boolean>(false);
|
|||||||
const showDeleteActionSheet = ref<boolean>(false);
|
const showDeleteActionSheet = ref<boolean>(false);
|
||||||
const displayOrderSaving = ref<boolean>(false);
|
const displayOrderSaving = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const firstShowingIds = computed<AccountShowingIds>(() => accountsStore.getFirstShowingIds(showHidden.value));
|
const firstShowingIds = computed<AccountShowingIds>(() => accountsStore.getFirstShowingIds(showHidden.value));
|
||||||
const lastShowingIds = computed<AccountShowingIds>(() => accountsStore.getLastShowingIds(showHidden.value));
|
const lastShowingIds = computed<AccountShowingIds>(() => accountsStore.getLastShowingIds(showHidden.value));
|
||||||
const hasAnyVisibleAccount = computed<boolean>(() => accountsStore.allVisibleAccountsCount > 0);
|
const hasAnyVisibleAccount = computed<boolean>(() => accountsStore.allVisibleAccountsCount > 0);
|
||||||
@@ -487,11 +493,11 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.account-overview-info > span {
|
.account-overview-info > span {
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-overview-info > span:last-child {
|
.account-overview-info > span:last-child {
|
||||||
margin-right: 0;
|
margin-inline-end: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-list {
|
.account-list {
|
||||||
|
|||||||
@@ -143,7 +143,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="account-balance flex-shrink-1">
|
<div class="account-balance flex-shrink-1">
|
||||||
<span>Balance</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -229,14 +229,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="account-balance flex-shrink-1">
|
<div class="account-balance flex-shrink-1">
|
||||||
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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
|
<f7-swipeout-button color="primary" close
|
||||||
:text="tt('Duplicate')"
|
:text="tt('Duplicate')"
|
||||||
v-if="item.transaction.type !== TransactionType.ModifyBalance"
|
v-if="item.transaction.type !== TransactionType.ModifyBalance"
|
||||||
@@ -245,7 +247,7 @@
|
|||||||
:text="tt('Edit')"
|
:text="tt('Edit')"
|
||||||
v-if="item.transaction.editable && item.transaction.type !== TransactionType.ModifyBalance"
|
v-if="item.transaction.editable && item.transaction.type !== TransactionType.ModifyBalance"
|
||||||
@click="editTransaction(item.transaction)"></f7-swipeout-button>
|
@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"
|
v-if="item.transaction.editable"
|
||||||
@click="removeTransaction(item.transaction, false)">
|
@click="removeTransaction(item.transaction, false)">
|
||||||
<f7-icon f7="trash"></f7-icon>
|
<f7-icon f7="trash"></f7-icon>
|
||||||
@@ -260,7 +262,7 @@
|
|||||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="align-self-flex-end">
|
<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>
|
<f7-link :class="{ 'disabled': loading }" href="#" popover-open=".chart-data-date-aggregation-type-popover-menu">{{ chartDataDateAggregationTypeDisplayName }}</f7-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -352,6 +354,7 @@ import { useAccountsStore } from '@/stores/account.ts';
|
|||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||||
import { AccountType } from '@/core/account.ts';
|
import { AccountType } from '@/core/account.ts';
|
||||||
import { TransactionType } from '@/core/transaction.ts';
|
import { TransactionType } from '@/core/transaction.ts';
|
||||||
@@ -386,7 +389,14 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime, formatNumberToLocalizedNumerals } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
|
getAllDateRanges,
|
||||||
|
formatUnixTimeToLongDateTime,
|
||||||
|
formatNumberToLocalizedNumerals
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -440,6 +450,7 @@ const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
|
|||||||
topPosition: 0
|
topPosition: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
|
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
|
||||||
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
|
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
|
||||||
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
|
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
|
||||||
@@ -708,11 +719,11 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content {
|
.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 {
|
.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 {
|
.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 {
|
.list.reconciliation-statement-list li.transaction-info .account-balance {
|
||||||
margin-left: 4px;
|
margin-inline-start: 4px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -48,15 +48,19 @@
|
|||||||
</f7-badge>
|
</f7-badge>
|
||||||
</ItemIcon>
|
</ItemIcon>
|
||||||
</template>
|
</template>
|
||||||
<f7-swipeout-actions left v-if="sortable">
|
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||||
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
: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)">
|
overswipe close @click="hide(category, !category.hidden)">
|
||||||
<f7-icon :f7="category.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
<f7-icon :f7="category.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</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="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-icon f7="trash"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
@@ -96,6 +100,7 @@ import { useCategoryListPageBase } from '@/views/base/categories/CategoryListPag
|
|||||||
|
|
||||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { CategoryType } from '@/core/category.ts';
|
import { CategoryType } from '@/core/category.ts';
|
||||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||||
|
|
||||||
@@ -110,7 +115,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt } = useI18n();
|
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
const { loading, primaryCategoryId, currentPrimaryCategory } = useCategoryListPageBase();
|
const { loading, primaryCategoryId, currentPrimaryCategory } = useCategoryListPageBase();
|
||||||
|
|
||||||
@@ -127,6 +132,8 @@ const showDeleteActionSheet = ref<boolean>(false);
|
|||||||
const displayOrderModified = ref<boolean>(false);
|
const displayOrderModified = ref<boolean>(false);
|
||||||
const displayOrderSaving = ref<boolean>(false);
|
const displayOrderSaving = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
|
|
||||||
const categories = computed<TransactionCategory[]>(() => {
|
const categories = computed<TransactionCategory[]>(() => {
|
||||||
if (!primaryCategoryId.value || primaryCategoryId.value === '' || primaryCategoryId.value === '0') {
|
if (!primaryCategoryId.value || primaryCategoryId.value === '' || primaryCategoryId.value === '0') {
|
||||||
if (!transactionCategoriesStore.allTransactionCategories || !transactionCategoriesStore.allTransactionCategories[categoryType.value]) {
|
if (!transactionCategoriesStore.allTransactionCategories || !transactionCategoriesStore.allTransactionCategories[categoryType.value]) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||||
</template>
|
</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>
|
||||||
<f7-list-item :title="subCategory.name"
|
<f7-list-item :title="subCategory.name"
|
||||||
:key="subIdx"
|
:key="subIdx"
|
||||||
|
|||||||
@@ -62,17 +62,19 @@
|
|||||||
@swipeout:closed="onExchangeRateSwipeoutClosed()">
|
@swipeout:closed="onExchangeRateSwipeoutClosed()">
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="no-padding no-margin">
|
<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>
|
<small class="smaller">{{ exchangeRate.currencyCode }}</small>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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
|
<f7-swipeout-button color="primary" close
|
||||||
:text="tt('Set as Base')"
|
:text="tt('Set as Base')"
|
||||||
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
|
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
|
||||||
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
|
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
|
||||||
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
|
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)"
|
@click="remove(exchangeRate, false)"
|
||||||
v-if="exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates">
|
v-if="exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates">
|
||||||
<f7-icon f7="trash"></f7-icon>
|
<f7-icon f7="trash"></f7-icon>
|
||||||
@@ -134,6 +136,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
|
|||||||
|
|
||||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { NumeralSystem } from '@/core/numeral.ts';
|
import { NumeralSystem } from '@/core/numeral.ts';
|
||||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||||
|
|
||||||
@@ -149,6 +152,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
tt,
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
getCurrentNumeralSystemType,
|
getCurrentNumeralSystemType,
|
||||||
getCurrencyName,
|
getCurrencyName,
|
||||||
formatAmountToLocalizedNumerals,
|
formatAmountToLocalizedNumerals,
|
||||||
@@ -180,6 +184,7 @@ const showBaseAmountSheet = ref<boolean>(false);
|
|||||||
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
|
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
|
||||||
const showDeleteActionSheet = ref<boolean>(false);
|
const showDeleteActionSheet = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
|
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
|
||||||
const baseAmountFontSizeClass = computed<string>(() => {
|
const baseAmountFontSizeClass = computed<string>(() => {
|
||||||
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
|
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #root>
|
<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])">
|
v-if="account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id])">
|
||||||
<f7-list-item checkbox
|
<f7-list-item checkbox
|
||||||
:title="subAccount.name"
|
:title="subAccount.name"
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
v-for="categorizedItems in ALL_APPLICATION_CLOUD_SETTINGS"
|
v-for="categorizedItems in ALL_APPLICATION_CLOUD_SETTINGS"
|
||||||
@change="updateSettingsSelected(categorizedItems, $event.target.checked)">
|
@change="updateSettingsSelected(categorizedItems, $event.target.checked)">
|
||||||
<template #root>
|
<template #root>
|
||||||
<ul class="padding-left">
|
<ul class="padding-inline-start">
|
||||||
<f7-list-item checkbox
|
<f7-list-item checkbox
|
||||||
:disabled="loading || enabling || disabling"
|
:disabled="loading || enabling || disabling"
|
||||||
:title="tt(settingItem.settingName)"
|
:title="tt(settingItem.settingName)"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<f7-icon f7="app_fill"></f7-icon>
|
<f7-icon f7="app_fill"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
<template #root>
|
<template #root>
|
||||||
<ul class="padding-left">
|
<ul class="padding-inline-start">
|
||||||
<f7-list-item checkbox class="disabled" title="Sub Category Name"
|
<f7-list-item checkbox class="disabled" title="Sub Category Name"
|
||||||
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
|
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
|
||||||
<template #media>
|
<template #media>
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #root>
|
<template #root>
|
||||||
<ul class="padding-left"
|
<ul class="padding-inline-start"
|
||||||
v-if="(showHidden && categoryType.allSubCategories[category.id]) || categoryType.allVisibleSubCategoryCounts[category.id]">
|
v-if="(showHidden && categoryType.allSubCategories[category.id]) || categoryType.allVisibleSubCategoryCounts[category.id]">
|
||||||
<f7-list-item checkbox
|
<f7-list-item checkbox
|
||||||
:title="subCategory.name"
|
:title="subCategory.name"
|
||||||
|
|||||||
@@ -93,7 +93,10 @@
|
|||||||
<div class="display-flex justify-content-space-between">
|
<div class="display-flex justify-content-space-between">
|
||||||
<div class="fontsize-minimum">A</div>
|
<div class="fontsize-minimum">A</div>
|
||||||
<div class="fontsize-maximum">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>
|
</div>
|
||||||
<f7-range
|
<f7-range
|
||||||
:min="FontSize.MinimumFontSize.type"
|
:min="FontSize.MinimumFontSize.type"
|
||||||
@@ -120,6 +123,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
|||||||
|
|
||||||
import { useSettingsStore } from '@/stores/setting.ts';
|
import { useSettingsStore } from '@/stores/setting.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { FontSize } from '@/core/font.ts';
|
import { FontSize } from '@/core/font.ts';
|
||||||
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
|
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
|
||||||
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
|
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
|
||||||
@@ -128,13 +132,21 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
|
getWeekdayShortName,
|
||||||
|
formatUnixTimeToLongYearMonth,
|
||||||
|
formatUnixTimeToShortTime,
|
||||||
|
formatAmountToLocalizedNumeralsWithCurrency
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const settingsStore = useSettingsStore();
|
const settingsStore = useSettingsStore();
|
||||||
|
|
||||||
const currentUnixTime = ref<number>(getCurrentUnixTime());
|
const currentUnixTime = ref<number>(getCurrentUnixTime());
|
||||||
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
|
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
|
||||||
|
|
||||||
|
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
|
||||||
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
|
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
|
||||||
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
|
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
|
||||||
const currentDayOfMonth = computed<number>(() => getDay(getLocalDatetimeFromUnixTime(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 v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.categoricalChartType === CategoricalChartType.Pie.type">
|
||||||
<f7-card-header class="no-border display-block">
|
<f7-card-header class="no-border display-block">
|
||||||
<div class="statistics-chart-header full-line text-align-right">
|
<div :class="{ 'statistics-chart-header': true, 'full-line': true, 'text-align-right': textDirection === TextDirection.LTR, 'text-align-left': textDirection === TextDirection.RTL}">
|
||||||
<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>
|
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||||
</div>
|
</div>
|
||||||
</f7-card-header>
|
</f7-card-header>
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
{{ totalAmountName }}
|
{{ totalAmountName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="align-self-flex-end">
|
<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>
|
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="align-self-flex-end">
|
<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>
|
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -239,13 +239,13 @@
|
|||||||
|
|
||||||
<f7-toolbar tabbar bottom class="toolbar-item-auto-size">
|
<f7-toolbar tabbar bottom class="toolbar-item-auto-size">
|
||||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(-1)">
|
<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>
|
||||||
<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">
|
<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>
|
<span :class="{ 'tabbar-item-changed': isQueryDateRangeChanged }">{{ queryDateRangeName }}</span>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(1)">
|
<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>
|
||||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
|
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
|
||||||
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
|
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
|
||||||
@@ -343,6 +343,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
|||||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||||
|
|
||||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||||
import {
|
import {
|
||||||
StatisticsAnalysisType,
|
StatisticsAnalysisType,
|
||||||
@@ -367,7 +368,13 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllCategoricalChartTypes, formatPercentToLocalizedNumerals } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
|
getAllCategoricalChartTypes,
|
||||||
|
formatPercentToLocalizedNumerals
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -414,6 +421,8 @@ const showCustomDateRangeSheet = ref<boolean>(false);
|
|||||||
const showCustomMonthRangeSheet = ref<boolean>(false);
|
const showCustomMonthRangeSheet = ref<boolean>(false);
|
||||||
const showMoreActionSheet = ref<boolean>(false);
|
const showMoreActionSheet = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
|
|
||||||
const allChartTypes = computed<TypeAndDisplayName[]>(() => {
|
const allChartTypes = computed<TypeAndDisplayName[]>(() => {
|
||||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||||
return getAllCategoricalChartTypes();
|
return getAllCategoricalChartTypes();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="display-flex">
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
@@ -46,11 +46,11 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="display-flex">
|
<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">
|
v-if="editingTag.id !== tag.id">
|
||||||
{{ tag.name }}
|
{{ tag.name }}
|
||||||
</div>
|
</div>
|
||||||
<f7-input class="list-title-input padding-left-half"
|
<f7-input class="list-title-input padding-inline-start-half"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="tt('Tag Title')"
|
:placeholder="tt('Tag Title')"
|
||||||
v-else-if="editingTag.id === tag.id"
|
v-else-if="editingTag.id === tag.id"
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
v-if="editingTag.id === tag.id"
|
v-if="editingTag.id === tag.id"
|
||||||
@click="save(editingTag)">
|
@click="save(editingTag)">
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="no-padding margin-left-half"
|
<f7-button class="no-padding margin-inline-start-half"
|
||||||
raised fill
|
raised fill
|
||||||
icon-f7="xmark"
|
icon-f7="xmark"
|
||||||
color="gray"
|
color="gray"
|
||||||
@@ -75,15 +75,19 @@
|
|||||||
@click="cancelSave(editingTag)">
|
@click="cancelSave(editingTag)">
|
||||||
</f7-button>
|
</f7-button>
|
||||||
</template>
|
</template>
|
||||||
<f7-swipeout-actions left v-if="sortable && editingTag.id !== tag.id">
|
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||||
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
: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)">
|
overswipe close @click="hide(tag, !tag.hidden)">
|
||||||
<f7-icon :f7="tag.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
<f7-icon :f7="tag.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</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="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-icon f7="trash"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
@@ -95,7 +99,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
<div class="display-flex">
|
<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"
|
type="text"
|
||||||
:placeholder="tt('Tag Title')"
|
:placeholder="tt('Tag Title')"
|
||||||
v-model:value="newTag.name"
|
v-model:value="newTag.name"
|
||||||
@@ -110,7 +114,7 @@
|
|||||||
color="blue"
|
color="blue"
|
||||||
@click="save(newTag)">
|
@click="save(newTag)">
|
||||||
</f7-button>
|
</f7-button>
|
||||||
<f7-button class="no-padding margin-left-half"
|
<f7-button class="no-padding margin-inline-start-half"
|
||||||
raised fill
|
raised fill
|
||||||
icon-f7="xmark"
|
icon-f7="xmark"
|
||||||
color="gray"
|
color="gray"
|
||||||
@@ -152,6 +156,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
|||||||
|
|
||||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -164,7 +169,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt } = useI18n();
|
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const transactionTagsStore = useTransactionTagsStore();
|
const transactionTagsStore = useTransactionTagsStore();
|
||||||
@@ -181,6 +186,7 @@ const showDeleteActionSheet = ref<boolean>(false);
|
|||||||
const displayOrderModified = ref<boolean>(false);
|
const displayOrderModified = ref<boolean>(false);
|
||||||
const displayOrderSaving = ref<boolean>(false);
|
const displayOrderSaving = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
||||||
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
|
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
|
||||||
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
|
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
|
||||||
@@ -413,7 +419,7 @@ init();
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.tag-item-list.list .item-media + .item-inner {
|
.tag-item-list.list .item-media + .item-inner {
|
||||||
margin-left: 5px;
|
margin-inline-start: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transaction-tag-list-item-content {
|
.transaction-tag-list-item-content {
|
||||||
|
|||||||
@@ -46,15 +46,19 @@
|
|||||||
</f7-badge>
|
</f7-badge>
|
||||||
</f7-icon>
|
</f7-icon>
|
||||||
</template>
|
</template>
|
||||||
<f7-swipeout-actions left v-if="sortable">
|
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||||
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
: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)">
|
overswipe close @click="hide(template, !template.hidden)">
|
||||||
<f7-icon :f7="template.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
<f7-icon :f7="template.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</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="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-icon f7="trash"></f7-icon>
|
||||||
</f7-swipeout-button>
|
</f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
@@ -93,6 +97,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
|||||||
|
|
||||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { TemplateType } from '@/core/template.ts';
|
import { TemplateType } from '@/core/template.ts';
|
||||||
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||||
|
|
||||||
@@ -108,7 +113,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt } = useI18n();
|
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const transactionTemplatesStore = useTransactionTemplatesStore();
|
const transactionTemplatesStore = useTransactionTemplatesStore();
|
||||||
@@ -124,6 +129,7 @@ const showDeleteActionSheet = ref<boolean>(false);
|
|||||||
const displayOrderModified = ref<boolean>(false);
|
const displayOrderModified = ref<boolean>(false);
|
||||||
const displayOrderSaving = ref<boolean>(false);
|
const displayOrderSaving = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const templates = computed<TransactionTemplate[]>(() => transactionTemplatesStore.allTransactionTemplates[templateType.value] || []);
|
const templates = computed<TransactionTemplate[]>(() => transactionTemplatesStore.allTransactionTemplates[templateType.value] || []);
|
||||||
const firstShowingId = computed<string | null>(() => getFirstShowingId(templates.value, showHidden.value));
|
const firstShowingId = computed<string | null>(() => getFirstShowingId(templates.value, showHidden.value));
|
||||||
const lastShowingId = computed<string | null>(() => getLastShowingId(templates.value, showHidden.value));
|
const lastShowingId = computed<string | null>(() => getLastShowingId(templates.value, showHidden.value));
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<div class="list-item-custom-title" v-if="hasAvailableExpenseCategories">
|
<div class="list-item-custom-title" v-if="hasAvailableExpenseCategories">
|
||||||
<span>{{ getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
|
<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>
|
<span>{{ getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-item-custom-title" v-else-if="!hasAvailableExpenseCategories">
|
<div class="list-item-custom-title" v-else-if="!hasAvailableExpenseCategories">
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<div class="list-item-custom-title" v-if="hasAvailableIncomeCategories">
|
<div class="list-item-custom-title" v-if="hasAvailableIncomeCategories">
|
||||||
<span>{{ getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
|
<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>
|
<span>{{ getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-item-custom-title" v-else-if="!hasAvailableIncomeCategories">
|
<div class="list-item-custom-title" v-else-if="!hasAvailableIncomeCategories">
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
<template #title>
|
<template #title>
|
||||||
<div class="list-item-custom-title" v-if="hasAvailableTransferCategories">
|
<div class="list-item-custom-title" v-if="hasAvailableTransferCategories">
|
||||||
<span>{{ getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
|
<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>
|
<span>{{ getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="list-item-custom-title" v-else-if="!hasAvailableTransferCategories">
|
<div class="list-item-custom-title" v-else-if="!hasAvailableTransferCategories">
|
||||||
@@ -1252,8 +1252,8 @@ init();
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.category-separate-icon.icon {
|
.category-separate-icon.icon {
|
||||||
margin-left: 5px;
|
margin-inline-start: 5px;
|
||||||
margin-right: 5px;
|
margin-inline-end: 5px;
|
||||||
font-size: var(--ebk-category-separate-icon-font-size);
|
font-size: var(--ebk-category-separate-icon-font-size);
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
color: var(--f7-color-gray-tint);
|
color: var(--f7-color-gray-tint);
|
||||||
@@ -1292,19 +1292,19 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.transaction-edit-timezone-name {
|
.transaction-edit-timezone-name {
|
||||||
padding-left: 4px;
|
padding-inline-start: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transaction-edit-tag {
|
.transaction-edit-tag {
|
||||||
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chip.transaction-edit-tag .chip-media+.chip-label {
|
.chip.transaction-edit-tag .chip-media+.chip-label {
|
||||||
margin-left: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chip.transaction-edit-tag .chip-media i.icon {
|
.chip.transaction-edit-tag .chip-media i.icon {
|
||||||
|
|||||||
@@ -47,13 +47,13 @@
|
|||||||
|
|
||||||
<f7-toolbar tabbar bottom class="toolbar-item-auto-size transaction-list-toolbar">
|
<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-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>
|
||||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': loading }" popover-open=".date-popover-menu">
|
<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>
|
<span :class="{ 'tabbar-item-changed': query.dateType !== DateRange.All.type }">{{ queryDateRangeName }}</span>
|
||||||
</f7-link>
|
</f7-link>
|
||||||
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, 1)">
|
<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>
|
||||||
<f7-link class="tabbar-text-with-ellipsis" popover-open=".category-popover-menu" :class="{ 'disabled': query.type === 1 }">
|
<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>
|
<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.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(transaction)})` }}</span>
|
||||||
<span v-if="transaction.sourceAccount">·</span>
|
<span v-if="transaction.sourceAccount">·</span>
|
||||||
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</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>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<f7-swipeout-actions right>
|
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||||
|
:right="textDirection === TextDirection.LTR">
|
||||||
<f7-swipeout-button color="primary" close
|
<f7-swipeout-button color="primary" close
|
||||||
:text="tt('Duplicate')"
|
:text="tt('Duplicate')"
|
||||||
v-if="transaction.type !== TransactionType.ModifyBalance"
|
v-if="transaction.type !== TransactionType.ModifyBalance"
|
||||||
@@ -301,7 +302,7 @@
|
|||||||
:text="tt('Edit')"
|
:text="tt('Edit')"
|
||||||
v-if="transaction.editable"
|
v-if="transaction.editable"
|
||||||
@click="edit(transaction)"></f7-swipeout-button>
|
@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"
|
v-if="transaction.editable"
|
||||||
@click="remove(transaction, false)">
|
@click="remove(transaction, false)">
|
||||||
<f7-icon f7="trash"></f7-icon>
|
<f7-icon f7="trash"></f7-icon>
|
||||||
@@ -398,7 +399,7 @@
|
|||||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||||
</template>
|
</template>
|
||||||
<f7-accordion-content>
|
<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] }"
|
<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)">
|
:title="tt('All')" @click="changeCategoryFilter(category.id)">
|
||||||
<template #media>
|
<template #media>
|
||||||
@@ -520,7 +521,7 @@
|
|||||||
v-for="filterType in AmountFilterType.values()"
|
v-for="filterType in AmountFilterType.values()"
|
||||||
@click="changeAmountFilter(filterType.type)">
|
@click="changeAmountFilter(filterType.type)">
|
||||||
<template #after>
|
<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>
|
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)"></f7-icon>
|
||||||
</template>
|
</template>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
@@ -617,6 +618,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
|||||||
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||||
|
|
||||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import {
|
import {
|
||||||
type TimeRangeAndDateType,
|
type TimeRangeAndDateType,
|
||||||
DateRangeScene,
|
DateRangeScene,
|
||||||
@@ -662,6 +664,7 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
tt,
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
getAllShortWeekdayNames,
|
getAllShortWeekdayNames,
|
||||||
getAllTransactionTagFilterTypes,
|
getAllTransactionTagFilterTypes,
|
||||||
getWeekdayShortName
|
getWeekdayShortName
|
||||||
@@ -739,6 +742,7 @@ const showCustomDateRangeSheet = ref<boolean>(false);
|
|||||||
const showCustomMonthSheet = ref<boolean>(false);
|
const showCustomMonthSheet = ref<boolean>(false);
|
||||||
const showDeleteActionSheet = ref<boolean>(false);
|
const showDeleteActionSheet = ref<boolean>(false);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
||||||
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
|
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
|
||||||
|
|
||||||
@@ -1511,7 +1515,7 @@ init();
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.transaction-list-toolbar .toolbar-inner {
|
.transaction-list-toolbar .toolbar-inner {
|
||||||
padding-right: 8px;
|
padding-inline-end: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-amount-list .transaction-amount-statistics {
|
.list.transaction-amount-list .transaction-amount-statistics {
|
||||||
@@ -1520,17 +1524,17 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-amount-list .transaction-amount-statistics > span {
|
.list.transaction-amount-list .transaction-amount-statistics > span {
|
||||||
margin-left: 8px;
|
margin-inline-start: 8px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-info-list li.transaction-info .item-media + .item-inner {
|
.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 {
|
.list.transaction-info-list li.transaction-info .actual-item-inner {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-left: 10px;
|
margin-inline-start: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1540,7 +1544,7 @@ init();
|
|||||||
|
|
||||||
.list.transaction-info-list li.transaction-info .transaction-date {
|
.list.transaction-info-list li.transaction-info .transaction-date {
|
||||||
width: var(--ebk-transaction-date-width);
|
width: var(--ebk-transaction-date-width);
|
||||||
margin-right: 6px;
|
margin-inline-end: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-info-list li.transaction-info .transaction-day {
|
.list.transaction-info-list li.transaction-info .transaction-day {
|
||||||
@@ -1550,6 +1554,10 @@ init();
|
|||||||
text-align: left;
|
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 {
|
.list.transaction-info-list li.transaction-info .transaction-day-of-week {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
font-size: var(--ebk-transaction-day-of-week-font-size);
|
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-height: var(--ebk-transaction-tag-chip-height);
|
||||||
--f7-chip-text-color: var(--f7-list-item-footer-text-color);
|
--f7-chip-text-color: var(--f7-list-item-footer-text-color);
|
||||||
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
||||||
margin-right: 4px;
|
margin-inline-end: 4px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-info-list li.transaction-info .chip.transaction-tag .chip-media+.chip-label {
|
.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 {
|
.list.transaction-info-list li.transaction-info .transaction-footer {
|
||||||
@@ -1588,15 +1596,21 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list.transaction-info-list li.transaction-info .transaction-footer > span {
|
.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 {
|
.list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
|
||||||
font-size: var(--ebk-transaction-account-arrow-font-size);
|
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);
|
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 {
|
.list.transaction-info-list li.transaction-info .transaction-amount {
|
||||||
color: var(--f7-list-item-after-text-color);
|
color: var(--f7-list-item-after-text-color);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1613,7 +1627,7 @@ init();
|
|||||||
}
|
}
|
||||||
|
|
||||||
.more-popover-menu .transaction-tag-name {
|
.more-popover-menu .transaction-tag-name {
|
||||||
padding-right: 4px;
|
padding-inline-end: 4px;
|
||||||
font-size: var(--f7-list-item-title-font-size);
|
font-size: var(--f7-list-item-title-font-size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,6 +184,6 @@ reloadUserDataStatistics();
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.export-file-type-list.list > ul > li > .item-content {
|
.export-file-type-list.list > ul > li > .item-content {
|
||||||
padding-left: 0;
|
padding-inline-start: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -34,7 +34,9 @@
|
|||||||
<template #after>
|
<template #after>
|
||||||
<small>{{ session.lastSeenDateTime }}</small>
|
<small>{{ session.lastSeenDateTime }}</small>
|
||||||
</template>
|
</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-button color="red" :text="tt('Log Out')" @click="revoke(session)"></f7-swipeout-button>
|
||||||
</f7-swipeout-actions>
|
</f7-swipeout-actions>
|
||||||
</f7-list-item>
|
</f7-list-item>
|
||||||
@@ -51,6 +53,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
|||||||
|
|
||||||
import { useTokensStore } from '@/stores/token.ts';
|
import { useTokensStore } from '@/stores/token.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
|
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
|
||||||
|
|
||||||
import { isEquals } from '@/lib/common.ts';
|
import { isEquals } from '@/lib/common.ts';
|
||||||
@@ -73,7 +76,7 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, formatUnixTimeToLongDateTime } = useI18n();
|
const { tt, getCurrentLanguageTextDirection, formatUnixTimeToLongDateTime } = useI18n();
|
||||||
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const tokensStore = useTokensStore();
|
const tokensStore = useTokensStore();
|
||||||
@@ -82,6 +85,8 @@ const tokens = ref<TokenInfoResponse[]>([]);
|
|||||||
const loading = ref<boolean>(true);
|
const loading = ref<boolean>(true);
|
||||||
const loadingError = ref<unknown | null>(null);
|
const loadingError = ref<unknown | null>(null);
|
||||||
|
|
||||||
|
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||||
|
|
||||||
const sessions = computed<MobilePageSessionInfo[]>(() => {
|
const sessions = computed<MobilePageSessionInfo[]>(() => {
|
||||||
const sessions: MobilePageSessionInfo[] = [];
|
const sessions: MobilePageSessionInfo[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -526,6 +526,7 @@ import { useRootStore } from '@/stores/index.ts';
|
|||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
import { useAccountsStore } from '@/stores/account.ts';
|
import { useAccountsStore } from '@/stores/account.ts';
|
||||||
|
|
||||||
|
import { TextDirection } from '@/core/text.ts';
|
||||||
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
|
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
|
||||||
|
|
||||||
import type { UserProfileResponse } from '@/models/user.ts';
|
import type { UserProfileResponse } from '@/models/user.ts';
|
||||||
@@ -538,7 +539,15 @@ const props = defineProps<{
|
|||||||
f7router: Router.Router;
|
f7router: Router.Router;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { tt, getAllLanguageOptions, getAllCurrencies, getCurrencyName, formatFiscalYearStartToLongDay } = useI18n();
|
const {
|
||||||
|
tt,
|
||||||
|
getCurrentLanguageTextDirection,
|
||||||
|
getAllLanguageOptions,
|
||||||
|
getAllCurrencies,
|
||||||
|
getCurrencyName,
|
||||||
|
formatFiscalYearStartToLongDay
|
||||||
|
} = useI18n();
|
||||||
|
|
||||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -661,6 +670,8 @@ function save(): void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const oldTextDirection: TextDirection = getCurrentLanguageTextDirection();
|
||||||
|
|
||||||
saving.value = true;
|
saving.value = true;
|
||||||
showLoading(() => saving.value);
|
showLoading(() => saving.value);
|
||||||
|
|
||||||
@@ -671,7 +682,10 @@ function save(): void {
|
|||||||
|
|
||||||
doAfterProfileUpdate(response.user);
|
doAfterProfileUpdate(response.user);
|
||||||
showToast('Your profile has been successfully updated');
|
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 => {
|
}).catch(error => {
|
||||||
saving.value = false;
|
saving.value = false;
|
||||||
hideLoading();
|
hideLoading();
|
||||||
|
|||||||
+66
-2
@@ -1,7 +1,7 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
|
||||||
import { type UserConfig, defineConfig } from 'vite'
|
import { type UserConfig, type Plugin, defineConfig } from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue';
|
import vue from '@vitejs/plugin-vue';
|
||||||
import vuetify from 'vite-plugin-vuetify';
|
import vuetify from 'vite-plugin-vuetify';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
@@ -15,6 +15,53 @@ const SRC_DIR = resolve(__dirname, './src');
|
|||||||
const PUBLIC_DIR = resolve(__dirname, './public');
|
const PUBLIC_DIR = resolve(__dirname, './public');
|
||||||
const BUILD_DIR = resolve(__dirname, './dist',);
|
const BUILD_DIR = resolve(__dirname, './dist',);
|
||||||
|
|
||||||
|
function injectFramework7CssFile({ htmlFileName, placeHolders }: { htmlFileName: string, placeHolders: { name: string, srcFileName: string, distFileNamePrefix: string }[] }): Plugin[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'inject-framework7-css-file:serve',
|
||||||
|
apply: 'serve',
|
||||||
|
enforce: 'post',
|
||||||
|
transformIndexHtml(html: string): string {
|
||||||
|
for (const placeholder of placeHolders) {
|
||||||
|
html = html.replace(`{{${placeholder.name}}}`, `${placeholder.srcFileName}`);
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'inject-framework7-css-file:build',
|
||||||
|
apply: 'build',
|
||||||
|
enforce: 'post',
|
||||||
|
generateBundle(_, bundle): void {
|
||||||
|
const placeholderCssFilePathMap: Record<string, string> = {};
|
||||||
|
|
||||||
|
for (const fileName of Object.keys(bundle)) {
|
||||||
|
for (const placeholder of placeHolders) {
|
||||||
|
if (fileName.startsWith(placeholder.distFileNamePrefix)) {
|
||||||
|
placeholderCssFilePathMap[placeholder.name] = fileName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const htmlAsset = bundle[htmlFileName];
|
||||||
|
|
||||||
|
if (!htmlAsset || htmlAsset.type !== 'asset') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let html = htmlAsset.source as string;
|
||||||
|
|
||||||
|
for (const [placeholder, filePath] of Object.entries(placeholderCssFilePathMap)) {
|
||||||
|
html = html.replace(`{{${placeholder}}}`, `./${filePath}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlAsset.source = html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
export default defineConfig(() => {
|
export default defineConfig(() => {
|
||||||
const licenseContent = fs.readFileSync('./LICENSE', { encoding: 'utf-8' });
|
const licenseContent = fs.readFileSync('./LICENSE', { encoding: 'utf-8' });
|
||||||
const buildUnixTime = process.env['buildUnixTime'] || '';
|
const buildUnixTime = process.env['buildUnixTime'] || '';
|
||||||
@@ -44,6 +91,21 @@ export default defineConfig(() => {
|
|||||||
configFile: 'styles/desktop/configured-variables/_vuetify.scss'
|
configFile: 'styles/desktop/configured-variables/_vuetify.scss'
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
injectFramework7CssFile({
|
||||||
|
htmlFileName: 'mobile.html',
|
||||||
|
placeHolders: [
|
||||||
|
{
|
||||||
|
name: 'framework7-ltr-css-filepath',
|
||||||
|
srcFileName: 'mobile-ltr.scss',
|
||||||
|
distFileNamePrefix: 'css/vendor-framework7-ltr'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'framework7-rtl-css-filepath',
|
||||||
|
srcFileName: 'mobile-rtl.scss',
|
||||||
|
distFileNamePrefix: 'css/vendor-framework7-rtl'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
Checker({
|
Checker({
|
||||||
vueTsc: true
|
vueTsc: true
|
||||||
}),
|
}),
|
||||||
@@ -141,7 +203,9 @@ export default defineConfig(() => {
|
|||||||
input: {
|
input: {
|
||||||
index: resolve(SRC_DIR, 'index.html'),
|
index: resolve(SRC_DIR, 'index.html'),
|
||||||
desktop: resolve(SRC_DIR, 'desktop.html'),
|
desktop: resolve(SRC_DIR, 'desktop.html'),
|
||||||
mobile: resolve(SRC_DIR, 'mobile.html')
|
mobile: resolve(SRC_DIR, 'mobile.html'),
|
||||||
|
'vendor-framework7-ltr': resolve(SRC_DIR, 'mobile-ltr.scss'),
|
||||||
|
'vendor-framework7-rtl': resolve(SRC_DIR, 'mobile-rtl.scss')
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
assetFileNames: assetInfo => {
|
assetFileNames: assetInfo => {
|
||||||
|
|||||||
Reference in New Issue
Block a user