mobile version supports rtl
This commit is contained in:
@@ -363,13 +363,13 @@ function toggleLegend(legend: TrendsBarChartLegend): void {
|
||||
|
||||
<style>
|
||||
.monthly-trends-bar-chart-legend {
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monthly-trends-bar-chart-legend-icon.f7-icons {
|
||||
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 {
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</f7-button>
|
||||
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
|
||||
<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>
|
||||
</f7-button>
|
||||
<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 {
|
||||
display: flex;
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
padding-inline-start: 16px;
|
||||
line-height: 1;
|
||||
height: var(--ebk-numpad-value-height);
|
||||
align-items: center;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<div class="pie-chart-toolbox-container padding-horizontal" v-if="showSelectedItemInfo">
|
||||
<div class="pie-chart-toolbox">
|
||||
<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>
|
||||
|
||||
<div class="pie-chart-toolbox-info">
|
||||
@@ -61,7 +61,7 @@
|
||||
<span v-else-if="!skeleton && selectedItem.displayName">{{ selectedItem.displayName }}</span>
|
||||
<span class="skeleton-text" v-if="skeleton">Value</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 :no-link-class="true" v-else-if="!validItems || !validItems.length">
|
||||
{{ tt('No transaction data') }}
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -264,14 +264,14 @@ function clickItem(item: CommonPieChartDataItem): void {
|
||||
}
|
||||
|
||||
.pie-chart-toolbox-info a > span + span {
|
||||
padding-left: 8px;
|
||||
padding-inline-start: 8px;
|
||||
}
|
||||
|
||||
.pie-chart-toolbox-info .item-navigate-icon {
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
padding-left: 4px;
|
||||
padding-inline-start: 4px;
|
||||
}
|
||||
|
||||
.pie-chart-toolbox-button {
|
||||
|
||||
@@ -82,13 +82,13 @@ watch(() => props.modelValue, (newValue) => {
|
||||
|
||||
<style>
|
||||
.list-item-pincode-input .item-content {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
|
||||
.list-item-pincode-input .item-content .item-inner {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 0;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
v-for="type in allTransactionScheduledFrequencyTypes"
|
||||
@click="changeFrequencyType(type.type)">
|
||||
<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>
|
||||
</f7-list-item>
|
||||
</f7-list>
|
||||
@@ -165,10 +165,10 @@ function onSheetClosed(): void {
|
||||
}
|
||||
|
||||
.schedule-frequency-type-list.list .item-inner {
|
||||
padding-right: 6px;
|
||||
padding-inline-end: 6px;
|
||||
}
|
||||
|
||||
.schedule-frequency-value-list-list.list .item-content {
|
||||
padding-left: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<f7-block class="no-padding no-margin">
|
||||
<div class="display-flex">
|
||||
<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 }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="display-flex">
|
||||
<f7-input class="list-title-input padding-left-half"
|
||||
<f7-input class="list-title-input padding-inline-start-half"
|
||||
type="text"
|
||||
:placeholder="tt('Tag Title')"
|
||||
v-model:value="newTag.name"
|
||||
@@ -70,7 +70,7 @@
|
||||
color="blue"
|
||||
@click="saveNewTag()">
|
||||
</f7-button>
|
||||
<f7-button class="no-padding margin-left-half"
|
||||
<f7-button class="no-padding margin-inline-start-half"
|
||||
raised fill
|
||||
icon-f7="xmark"
|
||||
color="gray"
|
||||
@@ -261,7 +261,7 @@ function onSheetClosed(): void {
|
||||
}
|
||||
|
||||
.tag-selection-list.list .item-media + .item-inner {
|
||||
margin-left: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.tag-selection-list-item {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? item[primaryIconField] : undefined" :color="primaryColorField ? item[primaryColorField] : undefined"></ItemIcon>
|
||||
</template>
|
||||
<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>
|
||||
</f7-list-item>
|
||||
<f7-list-item v-if="!filteredItems || !filteredItems.length"
|
||||
@@ -160,10 +160,10 @@ function onSheetClosed(): void {
|
||||
}
|
||||
|
||||
.primary-list.list .item-inner {
|
||||
padding-right: 6px;
|
||||
padding-inline-end: 6px;
|
||||
}
|
||||
|
||||
.secondary-list.list .item-content {
|
||||
padding-left: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from '@/core/setting.ts';
|
||||
|
||||
const settingsLocalStorageKey: string = 'ebk_app_settings';
|
||||
const currentLanguageSessionStorageKey: string = 'ebk_current_language';
|
||||
|
||||
function getStoredApplicationSettings(): BaseApplicationSetting {
|
||||
try {
|
||||
@@ -101,3 +102,16 @@ export function isEnableAnimate(): boolean {
|
||||
export function clearSettings(): void {
|
||||
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);
|
||||
}
|
||||
|
||||
+30
-23
@@ -4,6 +4,7 @@ import type { Dialog, Picker, Router } from 'framework7/types';
|
||||
|
||||
import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
|
||||
import { getNumberValue } from '../common.ts';
|
||||
import { isEnableAnimate } from '../settings.ts';
|
||||
@@ -195,7 +196,7 @@ export function onInfiniteScrolling(callback: (e: Event) => void): void {
|
||||
}
|
||||
|
||||
export function useI18nUIComponents() {
|
||||
const { tt, te } = useI18n();
|
||||
const { tt, te, getCurrentLanguageTextDirection } = useI18n();
|
||||
|
||||
function routeBackOnError<T>(f7router: Router.Router, errorRef: Ref<T>): void {
|
||||
const unwatch = watch(errorRef, (newValue) => {
|
||||
@@ -230,34 +231,32 @@ export function useI18nUIComponents() {
|
||||
}
|
||||
|
||||
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) => {
|
||||
f7.dialog.create({
|
||||
title: tt('global.app.title'),
|
||||
text: tt(message),
|
||||
animate: isEnableAnimate(),
|
||||
buttons: [
|
||||
{
|
||||
text: tt('Cancel'),
|
||||
onClick: cancelCallback
|
||||
},
|
||||
{
|
||||
text: tt('OK'),
|
||||
onClick: confirmCallback
|
||||
}
|
||||
]
|
||||
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
|
||||
}).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 {
|
||||
f7ready((f7) => {
|
||||
f7.dialog.create({
|
||||
title: tt('global.app.title'),
|
||||
text: tt(message),
|
||||
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
|
||||
animate: isEnableAnimate(),
|
||||
buttons: [
|
||||
{
|
||||
const textDirection = getCurrentLanguageTextDirection();
|
||||
|
||||
const cancelButton: Dialog.DialogButton = {
|
||||
text: tt('Cancel'),
|
||||
onClick: (dialog, event) => {
|
||||
if (cancelCallback) {
|
||||
@@ -265,8 +264,9 @@ export function useI18nUIComponents() {
|
||||
cancelCallback(inputValue, dialog, event);
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
};
|
||||
|
||||
const confirmButton: Dialog.DialogButton = {
|
||||
text: tt('OK'),
|
||||
onClick: (dialog, event) => {
|
||||
if (confirmCallback) {
|
||||
@@ -274,8 +274,15 @@ export function useI18nUIComponents() {
|
||||
confirmCallback(inputValue, dialog, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
f7ready((f7) => {
|
||||
f7.dialog.create({
|
||||
title: tt('global.app.title'),
|
||||
text: tt(message),
|
||||
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
|
||||
animate: isEnableAnimate(),
|
||||
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -190,6 +190,11 @@ import {
|
||||
getAllFilteredAccountsBalance
|
||||
} from '@/lib/account.ts';
|
||||
|
||||
import {
|
||||
getSessionCurrentLanguageKey,
|
||||
setSessionCurrentLanguageKey
|
||||
} from '@/lib/settings.ts';
|
||||
|
||||
import services from '@/lib/services.ts';
|
||||
import logger from '@/lib/logger.ts';
|
||||
|
||||
@@ -1961,14 +1966,31 @@ export function useI18n() {
|
||||
}
|
||||
});
|
||||
|
||||
setSessionCurrentLanguageKey(languageKey);
|
||||
services.setLocale(languageKey);
|
||||
document.querySelector('html')?.setAttribute('lang', languageKey);
|
||||
|
||||
if (document.querySelector('html')?.getAttribute('data-dir-mode') === 'isolate') {
|
||||
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
|
||||
if (location.search.includes('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 defaultFirstDayOfWeekName = getDefaultFirstDayOfWeek();
|
||||
@@ -2003,11 +2025,15 @@ export function useI18n() {
|
||||
}
|
||||
|
||||
function initLocale(lastUserLanguage?: string, timezone?: string): LocaleDefaultSettings | null {
|
||||
const sessionLanguageKey: string = getSessionCurrentLanguageKey();
|
||||
let localeDefaultSettings: LocaleDefaultSettings | null = null;
|
||||
|
||||
if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
|
||||
logger.info(`Last user language is ${lastUserLanguage}`);
|
||||
localeDefaultSettings = setLanguage(lastUserLanguage, true);
|
||||
} else if (sessionLanguageKey && getLanguageInfo(sessionLanguageKey)) {
|
||||
logger.info(`Session language is ${sessionLanguageKey}`);
|
||||
localeDefaultSettings = setLanguage(sessionLanguageKey, true);
|
||||
} else {
|
||||
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
|
||||
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 '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 '@/styles/mobile/global.css';
|
||||
import '@/styles/mobile/font-size-default.css';
|
||||
import '@/styles/mobile/font-size-small.css';
|
||||
import '@/styles/mobile/font-size-large.css';
|
||||
import '@/styles/mobile/font-size-x-large.css';
|
||||
import '@/styles/mobile/font-size-xx-large.css';
|
||||
import '@/styles/mobile/font-size-xxx-large.css';
|
||||
import '@/styles/mobile/font-size-xxxx-large.css';
|
||||
import '@/styles/mobile/amount-color.css';
|
||||
import '@/styles/mobile/global.scss';
|
||||
import '@/styles/mobile/font-size-default.scss';
|
||||
import '@/styles/mobile/font-size-small.scss';
|
||||
import '@/styles/mobile/font-size-large.scss';
|
||||
import '@/styles/mobile/font-size-x-large.scss';
|
||||
import '@/styles/mobile/font-size-xx-large.scss';
|
||||
import '@/styles/mobile/font-size-xxx-large.scss';
|
||||
import '@/styles/mobile/font-size-xxxx-large.scss';
|
||||
import '@/styles/mobile/amount-color.scss';
|
||||
|
||||
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: 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 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>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -21,6 +21,38 @@ input[type=number] {
|
||||
}
|
||||
|
||||
/** 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 {
|
||||
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 **/
|
||||
.dp__theme_light {
|
||||
--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 **/
|
||||
.navbar .navbar-compact-icons.right a + a {
|
||||
margin-left: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.toolbar-item-auto-size .toolbar-inner {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-inline-start: 16px;
|
||||
padding-inline-end: 16px;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
@@ -402,11 +438,22 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
.list .item-content .list-item-checked-icon {
|
||||
font-size: var(--ebk-list-item-checked-icon-font-size);
|
||||
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 {
|
||||
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 {
|
||||
@@ -435,7 +482,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
}
|
||||
|
||||
.icon-after-text {
|
||||
margin-left: 6px;
|
||||
margin-inline-start: 6px;
|
||||
}
|
||||
|
||||
.icon-after-text i.icon {
|
||||
@@ -443,12 +490,22 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
}
|
||||
|
||||
.badge.right-bottom-icon {
|
||||
margin-left: -12px;
|
||||
margin-inline-start: -12px;
|
||||
margin-top: 14px;
|
||||
width: 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 {
|
||||
font-size: 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;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -18px;
|
||||
margin-inline-start: -18px;
|
||||
margin-top: -8px;
|
||||
border-radius: 3px;
|
||||
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 {
|
||||
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 {
|
||||
display: block;
|
||||
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-bottom: var(--f7-list-item-padding-vertical);
|
||||
}
|
||||
|
||||
.list-item-with-multi-item .list-item-subitem:first-child .item-inner {
|
||||
padding-left: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
.combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
|
||||
margin-left: auto;
|
||||
html:not([dir="rtl"]) .combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
|
||||
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 {
|
||||
@@ -576,7 +637,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
}
|
||||
|
||||
.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 {
|
||||
@@ -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-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 {
|
||||
@@ -603,13 +664,13 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
.nested-list-item .nested-list-item-title {
|
||||
width: 100%;
|
||||
flex-shrink: 1;
|
||||
margin-right: var(--f7-list-item-media-margin);
|
||||
margin-inline-end: var(--f7-list-item-media-margin);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.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 {
|
||||
@@ -618,8 +679,8 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
display: flex;
|
||||
font-size: var(--f7-list-item-after-font-size);
|
||||
color: var(--f7-list-item-after-text-color);
|
||||
margin-left: auto;
|
||||
padding-left: var(--f7-list-item-after-padding);
|
||||
margin-inline-start: auto;
|
||||
padding-inline-start: var(--f7-list-item-after-padding);
|
||||
}
|
||||
|
||||
.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 {
|
||||
padding-right: var(--f7-safe-area-right) !important;
|
||||
padding-inline-end: var(--f7-safe-area-right) !important;
|
||||
}
|
||||
|
||||
/** Fix @vuepic/vue-datepicker style issue **/
|
||||
@@ -683,6 +744,10 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .dp__main .dp__btn.dp--arrow-btn-nav {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
/* statistics-list */
|
||||
.statistics-list-item-overview-amount {
|
||||
margin-top: 2px;
|
||||
@@ -709,7 +774,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
.statistics-percent {
|
||||
font-size: 0.7em;
|
||||
opacity: 0.6;
|
||||
margin-left: 6px;
|
||||
margin-inline-start: 6px;
|
||||
}
|
||||
|
||||
.statistics-item-end {
|
||||
@@ -719,7 +784,7 @@ i.icon.la, i.icon.las, i.icon.lab {
|
||||
}
|
||||
|
||||
.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 {
|
||||
@@ -21,7 +21,7 @@
|
||||
<p class="no-margin">
|
||||
<span class="month-expense" v-if="loading">0.00 USD</span>
|
||||
<span class="month-expense" v-else-if="!loading">{{ transactionOverview && transactionOverview.thisMonth ? getDisplayExpenseAmount(transactionOverview.thisMonth) : '-' }}</span>
|
||||
<f7-link class="margin-left-half" @click="showAmountInHomePage = !showAmountInHomePage">
|
||||
<f7-link class="margin-inline-start-half" @click="showAmountInHomePage = !showAmountInHomePage">
|
||||
<f7-icon class="ebk-hide-icon" :f7="showAmountInHomePage ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
|
||||
</f7-link>
|
||||
</p>
|
||||
@@ -314,11 +314,11 @@ init();
|
||||
}
|
||||
|
||||
.home-summary-misc > span {
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.home-summary-misc > span:last-child {
|
||||
margin-right: 0;
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
.dark .home-summary-card {
|
||||
@@ -348,7 +348,7 @@ init();
|
||||
}
|
||||
|
||||
.overview-transaction-list .overview-transaction-footer > span {
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.overview-transaction-list .overview-transaction-amount {
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
</template>
|
||||
|
||||
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
|
||||
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start-half">
|
||||
<f7-list>
|
||||
<f7-list-item :title="subCategory.name"
|
||||
:key="subIdx"
|
||||
|
||||
@@ -773,6 +773,6 @@ init();
|
||||
}
|
||||
|
||||
.subaccount-delete-button {
|
||||
margin-left: auto;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<p class="no-margin">
|
||||
<span class="net-assets" v-if="loading">0.00 USD</span>
|
||||
<span class="net-assets" v-else-if="!loading">{{ netAssets }}</span>
|
||||
<f7-link class="margin-left-half" @click="showAccountBalance = !showAccountBalance">
|
||||
<f7-link class="margin-inline-start-half" @click="showAccountBalance = !showAccountBalance">
|
||||
<f7-icon class="ebk-hide-icon" :f7="showAccountBalance ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
|
||||
</f7-link>
|
||||
</p>
|
||||
@@ -44,7 +44,7 @@
|
||||
<f7-list-item group-title :sortable="false">
|
||||
<small>
|
||||
<span>Account Category</span>
|
||||
<span style="margin-left: 10px">0.00 USD</span>
|
||||
<span style="margin-inline-start: 10px">0.00 USD</span>
|
||||
</small>
|
||||
</f7-list-item>
|
||||
<f7-list-item class="nested-list-item" after="0.00 USD" link="#"
|
||||
@@ -77,7 +77,7 @@
|
||||
<f7-list-item group-title :sortable="false">
|
||||
<small>
|
||||
<span>{{ tt(accountCategory.name) }}</span>
|
||||
<span style="margin-left: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
|
||||
<span style="margin-inline-start: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
|
||||
</small>
|
||||
</f7-list-item>
|
||||
<f7-list-item swipeout
|
||||
@@ -137,16 +137,20 @@
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
<f7-swipeout-actions left v-if="sortable">
|
||||
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||
:right="textDirection === TextDirection.RTL"
|
||||
v-if="sortable">
|
||||
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-horizontal"
|
||||
overswipe close @click="hide(account, !account.hidden)">
|
||||
<f7-icon :f7="account.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
<f7-swipeout-actions right v-if="!sortable">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="!sortable">
|
||||
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(account)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="primary" close :text="tt('More')" @click="showMoreActionSheetForAccount(account)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(account, false)">
|
||||
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(account, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
@@ -207,6 +211,7 @@ import { useAccountListPageBaseBase } from '@/views/base/accounts/AccountListPag
|
||||
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { AccountType, AccountCategory } from '@/core/account.ts';
|
||||
import type { Account, AccountShowingIds } from '@/models/account.ts';
|
||||
|
||||
@@ -216,7 +221,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
@@ -244,6 +249,7 @@ const showMoreActionSheet = ref<boolean>(false);
|
||||
const showDeleteActionSheet = ref<boolean>(false);
|
||||
const displayOrderSaving = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const firstShowingIds = computed<AccountShowingIds>(() => accountsStore.getFirstShowingIds(showHidden.value));
|
||||
const lastShowingIds = computed<AccountShowingIds>(() => accountsStore.getLastShowingIds(showHidden.value));
|
||||
const hasAnyVisibleAccount = computed<boolean>(() => accountsStore.allVisibleAccountsCount > 0);
|
||||
@@ -487,11 +493,11 @@ init();
|
||||
}
|
||||
|
||||
.account-overview-info > span {
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.account-overview-info > span:last-child {
|
||||
margin-right: 0;
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
.account-list {
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
</div>
|
||||
<div class="account-balance flex-shrink-1">
|
||||
<span>Balance</span>
|
||||
<span style="margin-left: 4px">0.00 USD</span>
|
||||
<span style="margin-inline-start: 4px">0.00 USD</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -229,14 +229,16 @@
|
||||
</div>
|
||||
<div class="account-balance flex-shrink-1">
|
||||
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
|
||||
<span style="margin-left: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
|
||||
<span style="margin-inline-start: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<f7-swipeout-actions right v-if="item.type == 'transaction' && item.transaction">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="item.type == 'transaction' && item.transaction">
|
||||
<f7-swipeout-button color="primary" close
|
||||
:text="tt('Duplicate')"
|
||||
v-if="item.transaction.type !== TransactionType.ModifyBalance"
|
||||
@@ -245,7 +247,7 @@
|
||||
:text="tt('Edit')"
|
||||
v-if="item.transaction.editable && item.transaction.type !== TransactionType.ModifyBalance"
|
||||
@click="editTransaction(item.transaction)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right"
|
||||
<f7-swipeout-button color="red" class="padding-horizontal"
|
||||
v-if="item.transaction.editable"
|
||||
@click="removeTransaction(item.transaction, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
@@ -260,7 +262,7 @@
|
||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||
<div></div>
|
||||
<div class="align-self-flex-end">
|
||||
<span style="margin-right: 4px;">{{ tt('Time Granularity') }}</span>
|
||||
<span style="margin-inline-end: 4px;">{{ tt('Time Granularity') }}</span>
|
||||
<f7-link :class="{ 'disabled': loading }" href="#" popover-open=".chart-data-date-aggregation-type-popover-menu">{{ chartDataDateAggregationTypeDisplayName }}</f7-link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -352,6 +354,7 @@ import { useAccountsStore } from '@/stores/account.ts';
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
|
||||
import { AccountType } from '@/core/account.ts';
|
||||
import { TransactionType } from '@/core/transaction.ts';
|
||||
@@ -386,7 +389,14 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime, formatNumberToLocalizedNumerals } = useI18n();
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getAllDateRanges,
|
||||
formatUnixTimeToLongDateTime,
|
||||
formatNumberToLocalizedNumerals
|
||||
} = useI18n();
|
||||
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
@@ -440,6 +450,7 @@ const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
|
||||
topPosition: 0
|
||||
});
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
|
||||
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
|
||||
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
|
||||
@@ -708,11 +719,11 @@ init();
|
||||
}
|
||||
|
||||
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content {
|
||||
padding-left: 0 !important;
|
||||
padding-inline-start: 0 !important;
|
||||
}
|
||||
|
||||
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner {
|
||||
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
|
||||
padding-inline-start: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
|
||||
}
|
||||
|
||||
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner:after {
|
||||
@@ -725,7 +736,7 @@ init();
|
||||
}
|
||||
|
||||
.list.reconciliation-statement-list li.transaction-info .account-balance {
|
||||
margin-left: 4px;
|
||||
margin-inline-start: 4px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -48,15 +48,19 @@
|
||||
</f7-badge>
|
||||
</ItemIcon>
|
||||
</template>
|
||||
<f7-swipeout-actions left v-if="sortable">
|
||||
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||
:right="textDirection === TextDirection.RTL"
|
||||
v-if="sortable">
|
||||
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-horizontal"
|
||||
overswipe close @click="hide(category, !category.hidden)">
|
||||
<f7-icon :f7="category.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
<f7-swipeout-actions right v-if="!sortable">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="!sortable">
|
||||
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(category)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(category, false)">
|
||||
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(category, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
@@ -96,6 +100,7 @@ import { useCategoryListPageBase } from '@/views/base/categories/CategoryListPag
|
||||
|
||||
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { CategoryType } from '@/core/category.ts';
|
||||
import type { TransactionCategory } from '@/models/transaction_category.ts';
|
||||
|
||||
@@ -110,7 +115,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
const { loading, primaryCategoryId, currentPrimaryCategory } = useCategoryListPageBase();
|
||||
|
||||
@@ -127,6 +132,8 @@ const showDeleteActionSheet = ref<boolean>(false);
|
||||
const displayOrderModified = ref<boolean>(false);
|
||||
const displayOrderSaving = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
|
||||
const categories = computed<TransactionCategory[]>(() => {
|
||||
if (!primaryCategoryId.value || primaryCategoryId.value === '' || primaryCategoryId.value === '0') {
|
||||
if (!transactionCategoriesStore.allTransactionCategories || !transactionCategoriesStore.allTransactionCategories[categoryType.value]) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
</template>
|
||||
|
||||
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
|
||||
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start">
|
||||
<f7-list>
|
||||
<f7-list-item :title="subCategory.name"
|
||||
:key="subIdx"
|
||||
|
||||
@@ -62,17 +62,19 @@
|
||||
@swipeout:closed="onExchangeRateSwipeoutClosed()">
|
||||
<template #title>
|
||||
<div class="no-padding no-margin">
|
||||
<span style="margin-right: 5px">{{ exchangeRate.currencyDisplayName }}</span>
|
||||
<span style="margin-inline-end: 5px">{{ exchangeRate.currencyDisplayName }}</span>
|
||||
<small class="smaller">{{ exchangeRate.currencyCode }}</small>
|
||||
</div>
|
||||
</template>
|
||||
<f7-swipeout-actions right v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
|
||||
<f7-swipeout-button color="primary" close
|
||||
:text="tt('Set as Base')"
|
||||
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
|
||||
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
|
||||
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right"
|
||||
<f7-swipeout-button color="red" class="padding-horizontal"
|
||||
@click="remove(exchangeRate, false)"
|
||||
v-if="exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
@@ -134,6 +136,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
|
||||
|
||||
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { NumeralSystem } from '@/core/numeral.ts';
|
||||
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
|
||||
|
||||
@@ -149,6 +152,7 @@ const props = defineProps<{
|
||||
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getCurrentNumeralSystemType,
|
||||
getCurrencyName,
|
||||
formatAmountToLocalizedNumerals,
|
||||
@@ -180,6 +184,7 @@ const showBaseAmountSheet = ref<boolean>(false);
|
||||
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
|
||||
const showDeleteActionSheet = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
|
||||
const baseAmountFontSizeClass = computed<string>(() => {
|
||||
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
</template>
|
||||
|
||||
<template #root>
|
||||
<ul class="padding-left"
|
||||
<ul class="padding-inline-start"
|
||||
v-if="account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id])">
|
||||
<f7-list-item checkbox
|
||||
:title="subAccount.name"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
v-for="categorizedItems in ALL_APPLICATION_CLOUD_SETTINGS"
|
||||
@change="updateSettingsSelected(categorizedItems, $event.target.checked)">
|
||||
<template #root>
|
||||
<ul class="padding-left">
|
||||
<ul class="padding-inline-start">
|
||||
<f7-list-item checkbox
|
||||
:disabled="loading || enabling || disabling"
|
||||
:title="tt(settingItem.settingName)"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<f7-icon f7="app_fill"></f7-icon>
|
||||
</template>
|
||||
<template #root>
|
||||
<ul class="padding-left">
|
||||
<ul class="padding-inline-start">
|
||||
<f7-list-item checkbox class="disabled" title="Sub Category Name"
|
||||
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
|
||||
<template #media>
|
||||
@@ -91,7 +91,7 @@
|
||||
</template>
|
||||
|
||||
<template #root>
|
||||
<ul class="padding-left"
|
||||
<ul class="padding-inline-start"
|
||||
v-if="(showHidden && categoryType.allSubCategories[category.id]) || categoryType.allVisibleSubCategoryCounts[category.id]">
|
||||
<f7-list-item checkbox
|
||||
:title="subCategory.name"
|
||||
|
||||
@@ -93,7 +93,10 @@
|
||||
<div class="display-flex justify-content-space-between">
|
||||
<div class="fontsize-minimum">A</div>
|
||||
<div class="fontsize-maximum">A</div>
|
||||
<div class="fontsize-default" :style="`left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">{{ tt('Default') }}</div>
|
||||
<div class="fontsize-default"
|
||||
:style="textDirection === TextDirection.LTR ? `left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)` : `right: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">
|
||||
{{ tt('Default') }}
|
||||
</div>
|
||||
</div>
|
||||
<f7-range
|
||||
:min="FontSize.MinimumFontSize.type"
|
||||
@@ -120,6 +123,7 @@ import { useI18n } from '@/locales/helpers.ts';
|
||||
|
||||
import { useSettingsStore } from '@/stores/setting.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { FontSize } from '@/core/font.ts';
|
||||
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
|
||||
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
|
||||
@@ -128,13 +132,21 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getWeekdayShortName,
|
||||
formatUnixTimeToLongYearMonth,
|
||||
formatUnixTimeToShortTime,
|
||||
formatAmountToLocalizedNumeralsWithCurrency
|
||||
} = useI18n();
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const currentUnixTime = ref<number>(getCurrentUnixTime());
|
||||
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
|
||||
|
||||
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
|
||||
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
|
||||
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
|
||||
const currentDayOfMonth = computed<number>(() => getDay(getLocalDatetimeFromUnixTime(currentUnixTime.value)));
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
|
||||
<f7-card v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.categoricalChartType === CategoricalChartType.Pie.type">
|
||||
<f7-card-header class="no-border display-block">
|
||||
<div class="statistics-chart-header full-line text-align-right">
|
||||
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
|
||||
<div :class="{ 'statistics-chart-header': true, 'full-line': true, 'text-align-right': textDirection === TextDirection.LTR, 'text-align-left': textDirection === TextDirection.RTL}">
|
||||
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</f7-card-header>
|
||||
@@ -104,7 +104,7 @@
|
||||
{{ totalAmountName }}
|
||||
</div>
|
||||
<div class="align-self-flex-end">
|
||||
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
|
||||
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -196,7 +196,7 @@
|
||||
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
|
||||
<div></div>
|
||||
<div class="align-self-flex-end">
|
||||
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
|
||||
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
|
||||
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,13 +239,13 @@
|
||||
|
||||
<f7-toolbar tabbar bottom class="toolbar-item-auto-size">
|
||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(-1)">
|
||||
<f7-icon f7="arrow_left_square"></f7-icon>
|
||||
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading || query.chartDataType === ChartDataType.AccountTotalAssets.type || query.chartDataType === ChartDataType.AccountTotalLiabilities.type }" popover-open=".date-popover-menu">
|
||||
<span :class="{ 'tabbar-item-changed': isQueryDateRangeChanged }">{{ queryDateRangeName }}</span>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(1)">
|
||||
<f7-icon f7="arrow_right_square"></f7-icon>
|
||||
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
|
||||
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
|
||||
@@ -343,6 +343,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
|
||||
import { useStatisticsStore } from '@/stores/statistics.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
|
||||
import {
|
||||
StatisticsAnalysisType,
|
||||
@@ -367,7 +368,13 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getAllCategoricalChartTypes, formatPercentToLocalizedNumerals } = useI18n();
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getAllCategoricalChartTypes,
|
||||
formatPercentToLocalizedNumerals
|
||||
} = useI18n();
|
||||
|
||||
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
@@ -414,6 +421,8 @@ const showCustomDateRangeSheet = ref<boolean>(false);
|
||||
const showCustomMonthRangeSheet = ref<boolean>(false);
|
||||
const showMoreActionSheet = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
|
||||
const allChartTypes = computed<TypeAndDisplayName[]>(() => {
|
||||
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
|
||||
return getAllCategoricalChartTypes();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="display-flex">
|
||||
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half">Tag Name</div>
|
||||
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half">Tag Name</div>
|
||||
</div>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
@@ -46,11 +46,11 @@
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="display-flex">
|
||||
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half"
|
||||
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half"
|
||||
v-if="editingTag.id !== tag.id">
|
||||
{{ tag.name }}
|
||||
</div>
|
||||
<f7-input class="list-title-input padding-left-half"
|
||||
<f7-input class="list-title-input padding-inline-start-half"
|
||||
type="text"
|
||||
:placeholder="tt('Tag Title')"
|
||||
v-else-if="editingTag.id === tag.id"
|
||||
@@ -67,7 +67,7 @@
|
||||
v-if="editingTag.id === tag.id"
|
||||
@click="save(editingTag)">
|
||||
</f7-button>
|
||||
<f7-button class="no-padding margin-left-half"
|
||||
<f7-button class="no-padding margin-inline-start-half"
|
||||
raised fill
|
||||
icon-f7="xmark"
|
||||
color="gray"
|
||||
@@ -75,15 +75,19 @@
|
||||
@click="cancelSave(editingTag)">
|
||||
</f7-button>
|
||||
</template>
|
||||
<f7-swipeout-actions left v-if="sortable && editingTag.id !== tag.id">
|
||||
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||
:right="textDirection === TextDirection.RTL"
|
||||
v-if="sortable && editingTag.id !== tag.id">
|
||||
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-horizontal"
|
||||
overswipe close @click="hide(tag, !tag.hidden)">
|
||||
<f7-icon :f7="tag.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
<f7-swipeout-actions right v-if="!sortable && editingTag.id !== tag.id">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="!sortable && editingTag.id !== tag.id">
|
||||
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(tag)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(tag, false)">
|
||||
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(tag, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
@@ -95,7 +99,7 @@
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="display-flex">
|
||||
<f7-input class="list-title-input padding-left-half"
|
||||
<f7-input class="list-title-input padding-inline-start-half"
|
||||
type="text"
|
||||
:placeholder="tt('Tag Title')"
|
||||
v-model:value="newTag.name"
|
||||
@@ -110,7 +114,7 @@
|
||||
color="blue"
|
||||
@click="save(newTag)">
|
||||
</f7-button>
|
||||
<f7-button class="no-padding margin-left-half"
|
||||
<f7-button class="no-padding margin-inline-start-half"
|
||||
raised fill
|
||||
icon-f7="xmark"
|
||||
color="gray"
|
||||
@@ -152,6 +156,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
||||
|
||||
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { TransactionTag } from '@/models/transaction_tag.ts';
|
||||
|
||||
import {
|
||||
@@ -164,7 +169,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const transactionTagsStore = useTransactionTagsStore();
|
||||
@@ -181,6 +186,7 @@ const showDeleteActionSheet = ref<boolean>(false);
|
||||
const displayOrderModified = ref<boolean>(false);
|
||||
const displayOrderSaving = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
|
||||
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
|
||||
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
|
||||
@@ -413,7 +419,7 @@ init();
|
||||
|
||||
<style>
|
||||
.tag-item-list.list .item-media + .item-inner {
|
||||
margin-left: 5px;
|
||||
margin-inline-start: 5px;
|
||||
}
|
||||
|
||||
.transaction-tag-list-item-content {
|
||||
|
||||
@@ -46,15 +46,19 @@
|
||||
</f7-badge>
|
||||
</f7-icon>
|
||||
</template>
|
||||
<f7-swipeout-actions left v-if="sortable">
|
||||
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
|
||||
:right="textDirection === TextDirection.RTL"
|
||||
v-if="sortable">
|
||||
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-horizontal"
|
||||
overswipe close @click="hide(template, !template.hidden)">
|
||||
<f7-icon :f7="template.hidden ? 'eye' : 'eye_slash'"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
<f7-swipeout-actions right v-if="!sortable">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="!sortable">
|
||||
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(template)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(template, false)">
|
||||
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(template, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
</f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
@@ -93,6 +97,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
||||
|
||||
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { TemplateType } from '@/core/template.ts';
|
||||
import { TransactionTemplate } from '@/models/transaction_template.ts';
|
||||
|
||||
@@ -108,7 +113,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection } = useI18n();
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const transactionTemplatesStore = useTransactionTemplatesStore();
|
||||
@@ -124,6 +129,7 @@ const showDeleteActionSheet = ref<boolean>(false);
|
||||
const displayOrderModified = ref<boolean>(false);
|
||||
const displayOrderSaving = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const templates = computed<TransactionTemplate[]>(() => transactionTemplatesStore.allTransactionTemplates[templateType.value] || []);
|
||||
const firstShowingId = computed<string | null>(() => getFirstShowingId(templates.value, showHidden.value));
|
||||
const lastShowingId = computed<string | null>(() => getLastShowingId(templates.value, showHidden.value));
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<template #title>
|
||||
<div class="list-item-custom-title" v-if="hasAvailableExpenseCategories">
|
||||
<span>{{ getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
|
||||
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
|
||||
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
|
||||
<span>{{ getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
|
||||
</div>
|
||||
<div class="list-item-custom-title" v-else-if="!hasAvailableExpenseCategories">
|
||||
@@ -137,7 +137,7 @@
|
||||
<template #title>
|
||||
<div class="list-item-custom-title" v-if="hasAvailableIncomeCategories">
|
||||
<span>{{ getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
|
||||
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
|
||||
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
|
||||
<span>{{ getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
|
||||
</div>
|
||||
<div class="list-item-custom-title" v-else-if="!hasAvailableIncomeCategories">
|
||||
@@ -169,7 +169,7 @@
|
||||
<template #title>
|
||||
<div class="list-item-custom-title" v-if="hasAvailableTransferCategories">
|
||||
<span>{{ getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
|
||||
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
|
||||
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
|
||||
<span>{{ getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
|
||||
</div>
|
||||
<div class="list-item-custom-title" v-else-if="!hasAvailableTransferCategories">
|
||||
@@ -1252,8 +1252,8 @@ init();
|
||||
|
||||
<style>
|
||||
.category-separate-icon.icon {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
margin-inline-start: 5px;
|
||||
margin-inline-end: 5px;
|
||||
font-size: var(--ebk-category-separate-icon-font-size);
|
||||
line-height: 16px;
|
||||
color: var(--f7-color-gray-tint);
|
||||
@@ -1292,19 +1292,19 @@ init();
|
||||
}
|
||||
|
||||
.transaction-edit-timezone-name {
|
||||
padding-left: 4px;
|
||||
padding-inline-start: 4px;
|
||||
}
|
||||
|
||||
.transaction-edit-tag {
|
||||
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.chip.transaction-edit-tag .chip-media+.chip-label {
|
||||
margin-left: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.chip.transaction-edit-tag .chip-media i.icon {
|
||||
|
||||
@@ -47,13 +47,13 @@
|
||||
|
||||
<f7-toolbar tabbar bottom class="toolbar-item-auto-size transaction-list-toolbar">
|
||||
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, -1)">
|
||||
<f7-icon f7="arrow_left_square"></f7-icon>
|
||||
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': loading }" popover-open=".date-popover-menu">
|
||||
<span :class="{ 'tabbar-item-changed': query.dateType !== DateRange.All.type }">{{ queryDateRangeName }}</span>
|
||||
</f7-link>
|
||||
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, 1)">
|
||||
<f7-icon f7="arrow_right_square"></f7-icon>
|
||||
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
|
||||
</f7-link>
|
||||
<f7-link class="tabbar-text-with-ellipsis" popover-open=".category-popover-menu" :class="{ 'disabled': query.type === 1 }">
|
||||
<span :class="{ 'tabbar-item-changed': query.categoryIds }">{{ queryCategoryName }}</span>
|
||||
@@ -285,14 +285,15 @@
|
||||
<span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(transaction)})` }}</span>
|
||||
<span v-if="transaction.sourceAccount">·</span>
|
||||
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
|
||||
<f7-icon f7="arrow_right" class="transaction-account-arrow" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
|
||||
<f7-icon class="transaction-account-arrow icon-with-direction" f7="arrow_right" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
|
||||
<span v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id">{{ transaction.destinationAccount.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<f7-swipeout-actions right>
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR">
|
||||
<f7-swipeout-button color="primary" close
|
||||
:text="tt('Duplicate')"
|
||||
v-if="transaction.type !== TransactionType.ModifyBalance"
|
||||
@@ -301,7 +302,7 @@
|
||||
:text="tt('Edit')"
|
||||
v-if="transaction.editable"
|
||||
@click="edit(transaction)"></f7-swipeout-button>
|
||||
<f7-swipeout-button color="red" class="padding-left padding-right"
|
||||
<f7-swipeout-button color="red" class="padding-horizontal"
|
||||
v-if="transaction.editable"
|
||||
@click="remove(transaction, false)">
|
||||
<f7-icon f7="trash"></f7-icon>
|
||||
@@ -398,7 +399,7 @@
|
||||
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
|
||||
</template>
|
||||
<f7-accordion-content>
|
||||
<f7-list dividers class="padding-left">
|
||||
<f7-list dividers class="padding-inline-start">
|
||||
<f7-list-item :class="{ 'list-item-selected': query.categoryIds === category.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[category.id] }"
|
||||
:title="tt('All')" @click="changeCategoryFilter(category.id)">
|
||||
<template #media>
|
||||
@@ -520,7 +521,7 @@
|
||||
v-for="filterType in AmountFilterType.values()"
|
||||
@click="changeAmountFilter(filterType.type)">
|
||||
<template #after>
|
||||
<span class="margin-right-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
|
||||
<span class="margin-inline-end-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
|
||||
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)"></f7-icon>
|
||||
</template>
|
||||
</f7-list-item>
|
||||
@@ -617,6 +618,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
|
||||
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
|
||||
|
||||
import type { TypeAndDisplayName } from '@/core/base.ts';
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import {
|
||||
type TimeRangeAndDateType,
|
||||
DateRangeScene,
|
||||
@@ -662,6 +664,7 @@ const props = defineProps<{
|
||||
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getAllShortWeekdayNames,
|
||||
getAllTransactionTagFilterTypes,
|
||||
getWeekdayShortName
|
||||
@@ -739,6 +742,7 @@ const showCustomDateRangeSheet = ref<boolean>(false);
|
||||
const showCustomMonthSheet = ref<boolean>(false);
|
||||
const showDeleteActionSheet = ref<boolean>(false);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
|
||||
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
|
||||
|
||||
@@ -1511,7 +1515,7 @@ init();
|
||||
|
||||
<style>
|
||||
.transaction-list-toolbar .toolbar-inner {
|
||||
padding-right: 8px;
|
||||
padding-inline-end: 8px;
|
||||
}
|
||||
|
||||
.list.transaction-amount-list .transaction-amount-statistics {
|
||||
@@ -1520,17 +1524,17 @@ init();
|
||||
}
|
||||
|
||||
.list.transaction-amount-list .transaction-amount-statistics > span {
|
||||
margin-left: 8px;
|
||||
margin-inline-start: 8px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .item-media + .item-inner {
|
||||
margin-left: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .actual-item-inner {
|
||||
width: 100%;
|
||||
margin-left: 10px;
|
||||
margin-inline-start: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -1540,7 +1544,7 @@ init();
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-date {
|
||||
width: var(--ebk-transaction-date-width);
|
||||
margin-right: 6px;
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-day {
|
||||
@@ -1550,6 +1554,10 @@ init();
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-day {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-day-of-week {
|
||||
opacity: 0.6;
|
||||
font-size: var(--ebk-transaction-day-of-week-font-size);
|
||||
@@ -1569,14 +1577,14 @@ init();
|
||||
--f7-chip-height: var(--ebk-transaction-tag-chip-height);
|
||||
--f7-chip-text-color: var(--f7-list-item-footer-text-color);
|
||||
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .chip.transaction-tag .chip-media+.chip-label {
|
||||
margin-left: 0;
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-footer {
|
||||
@@ -1588,15 +1596,21 @@ init();
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-footer > span {
|
||||
margin-right: 4px;
|
||||
unicode-bidi: isolate;
|
||||
margin-inline-end: 4px;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
|
||||
font-size: var(--ebk-transaction-account-arrow-font-size);
|
||||
margin-right: 4px;
|
||||
margin-inline-end: 4px;
|
||||
margin-top: var(--ebk-transaction-account-arrow-margin-top);
|
||||
}
|
||||
|
||||
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
|
||||
margin-inline-end: 0;
|
||||
margin-inline-start: 4px;
|
||||
}
|
||||
|
||||
.list.transaction-info-list li.transaction-info .transaction-amount {
|
||||
color: var(--f7-list-item-after-text-color);
|
||||
overflow: hidden;
|
||||
@@ -1613,7 +1627,7 @@ init();
|
||||
}
|
||||
|
||||
.more-popover-menu .transaction-tag-name {
|
||||
padding-right: 4px;
|
||||
padding-inline-end: 4px;
|
||||
font-size: var(--f7-list-item-title-font-size);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,6 +184,6 @@ reloadUserDataStatistics();
|
||||
|
||||
<style>
|
||||
.export-file-type-list.list > ul > li > .item-content {
|
||||
padding-left: 0;
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
<template #after>
|
||||
<small>{{ session.lastSeenDateTime }}</small>
|
||||
</template>
|
||||
<f7-swipeout-actions right v-if="!session.isCurrent">
|
||||
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
|
||||
:right="textDirection === TextDirection.LTR"
|
||||
v-if="!session.isCurrent">
|
||||
<f7-swipeout-button color="red" :text="tt('Log Out')" @click="revoke(session)"></f7-swipeout-button>
|
||||
</f7-swipeout-actions>
|
||||
</f7-list-item>
|
||||
@@ -51,6 +53,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
|
||||
|
||||
import { useTokensStore } from '@/stores/token.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
|
||||
|
||||
import { isEquals } from '@/lib/common.ts';
|
||||
@@ -73,7 +76,7 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, formatUnixTimeToLongDateTime } = useI18n();
|
||||
const { tt, getCurrentLanguageTextDirection, formatUnixTimeToLongDateTime } = useI18n();
|
||||
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const tokensStore = useTokensStore();
|
||||
@@ -82,6 +85,8 @@ const tokens = ref<TokenInfoResponse[]>([]);
|
||||
const loading = ref<boolean>(true);
|
||||
const loadingError = ref<unknown | null>(null);
|
||||
|
||||
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
|
||||
|
||||
const sessions = computed<MobilePageSessionInfo[]>(() => {
|
||||
const sessions: MobilePageSessionInfo[] = [];
|
||||
|
||||
|
||||
@@ -526,6 +526,7 @@ import { useRootStore } from '@/stores/index.ts';
|
||||
import { useUserStore } from '@/stores/user.ts';
|
||||
import { useAccountsStore } from '@/stores/account.ts';
|
||||
|
||||
import { TextDirection } from '@/core/text.ts';
|
||||
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
|
||||
|
||||
import type { UserProfileResponse } from '@/models/user.ts';
|
||||
@@ -538,7 +539,15 @@ const props = defineProps<{
|
||||
f7router: Router.Router;
|
||||
}>();
|
||||
|
||||
const { tt, getAllLanguageOptions, getAllCurrencies, getCurrencyName, formatFiscalYearStartToLongDay } = useI18n();
|
||||
const {
|
||||
tt,
|
||||
getCurrentLanguageTextDirection,
|
||||
getAllLanguageOptions,
|
||||
getAllCurrencies,
|
||||
getCurrencyName,
|
||||
formatFiscalYearStartToLongDay
|
||||
} = useI18n();
|
||||
|
||||
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
|
||||
|
||||
const {
|
||||
@@ -661,6 +670,8 @@ function save(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldTextDirection: TextDirection = getCurrentLanguageTextDirection();
|
||||
|
||||
saving.value = true;
|
||||
showLoading(() => saving.value);
|
||||
|
||||
@@ -671,7 +682,10 @@ function save(): void {
|
||||
|
||||
doAfterProfileUpdate(response.user);
|
||||
showToast('Your profile has been successfully updated');
|
||||
router.back();
|
||||
|
||||
if (oldTextDirection === getCurrentLanguageTextDirection()) {
|
||||
router.back(); // if text direction is changed, the page will be reloaded, so it don't need to go back
|
||||
}
|
||||
}).catch(error => {
|
||||
saving.value = false;
|
||||
hideLoading();
|
||||
|
||||
+66
-2
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
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 vuetify from 'vite-plugin-vuetify';
|
||||
import { VitePWA } from 'vite-plugin-pwa';
|
||||
@@ -15,6 +15,53 @@ const SRC_DIR = resolve(__dirname, './src');
|
||||
const PUBLIC_DIR = resolve(__dirname, './public');
|
||||
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(() => {
|
||||
const licenseContent = fs.readFileSync('./LICENSE', { encoding: 'utf-8' });
|
||||
const buildUnixTime = process.env['buildUnixTime'] || '';
|
||||
@@ -44,6 +91,21 @@ export default defineConfig(() => {
|
||||
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({
|
||||
vueTsc: true
|
||||
}),
|
||||
@@ -141,7 +203,9 @@ export default defineConfig(() => {
|
||||
input: {
|
||||
index: resolve(SRC_DIR, 'index.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: {
|
||||
assetFileNames: assetInfo => {
|
||||
|
||||
Reference in New Issue
Block a user