desktop version supports rtl

This commit is contained in:
MaysWind
2025-08-18 00:45:26 +08:00
parent 4eff3a337f
commit c00770201b
57 changed files with 502 additions and 371 deletions
+44 -44
View File
@@ -52,12 +52,12 @@
<v-card variant="flat" min-height="920">
<template #title>
<div class="title-and-toolbar d-flex align-center text-no-wrap">
<v-btn class="mr-3 d-md-none" density="compact" color="default" variant="plain"
<v-btn class="me-3 d-md-none" density="compact" color="default" variant="plain"
:ripple="false" :icon="true" @click="showNav = !showNav">
<v-icon :icon="mdiMenu" size="24" />
</v-btn>
<span>{{ tt('Transaction List') }}</span>
<v-btn class="ml-3" color="default" variant="outlined"
<v-btn class="ms-3" color="default" variant="outlined"
:disabled="loading || !canAddTransaction" @click="add()">
{{ tt('Add') }}
<v-menu activator="parent" :open-on-hover="true" v-if="allTransactionTemplates && allTransactionTemplates.length">
@@ -70,7 +70,7 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-3" color="default" variant="outlined"
<v-btn class="ms-3" color="default" variant="outlined"
:disabled="loading" @click="importTransaction"
v-if="isDataImportingEnabled()">
{{ tt('Import') }}
@@ -87,7 +87,7 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-3" color="default" variant="outlined"
<v-btn class="ms-3" color="default" variant="outlined"
:disabled="loading || exportingData || !transactions || !transactions.length || transactions.length < 1" v-if="!isDataImportingEnabled() && isDataExportingEnabled()">
{{ tt('Export') }}
<v-menu activator="parent">
@@ -104,7 +104,7 @@
</v-menu>
</v-btn>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" :loading="loading" @click="reload(true, false)">
class="ms-2" :icon="true" :loading="loading" @click="reload(true, false)">
<template #loader>
<v-progress-circular indeterminate size="20"/>
</template>
@@ -112,7 +112,7 @@
<v-tooltip activator="parent">{{ tt('Refresh') }}</v-tooltip>
</v-btn>
<v-spacer/>
<div class="transaction-keyword-filter ml-2">
<div class="transaction-keyword-filter ms-2">
<v-text-field density="compact" :disabled="loading"
:prepend-inner-icon="mdiMagnify"
:append-inner-icon="searchKeyword !== query.keyword ? mdiCheck : undefined"
@@ -128,36 +128,36 @@
<v-card-text class="pt-0">
<div class="transaction-list-datetime-range d-flex align-center">
<span class="text-body-1">{{ tt('Date Range') }}</span>
<span class="text-body-1 transaction-list-datetime-range-text ml-2"
<span class="text-body-1 transaction-list-datetime-range-text ms-2"
v-if="!query.minTime && !query.maxTime">
<span class="text-sm">{{ tt('All') }}</span>
</span>
<span class="text-body-1 transaction-list-datetime-range-text ml-2"
<span class="text-body-1 transaction-list-datetime-range-text ms-2"
v-else-if="query.minTime || query.maxTime">
<v-btn class="mr-1" size="x-small"
<v-btn class="button-icon-with-direction me-1" size="x-small"
density="compact" color="default" variant="outlined"
:icon="mdiArrowLeft" :disabled="loading"
@click="shiftDateRange(query.minTime, query.maxTime, -1)"/>
<span class="text-sm">{{ `${queryMinTime} - ${queryMaxTime}` }}</span>
<v-btn class="ml-1" size="x-small"
<v-btn class="button-icon-with-direction ms-1" size="x-small"
density="compact" color="default" variant="outlined"
:icon="mdiArrowRight" :disabled="loading"
@click="shiftDateRange(query.minTime, query.maxTime, 1)"/>
</span>
<v-spacer/>
<div class="skeleton-no-margin d-flex align-center" v-if="showTotalAmountInTransactionListPage && currentMonthTotalAmount">
<span class="ml-2 text-subtitle-1">{{ queryAllFilterAccountIdsCount ? tt('Total Inflows') : tt('Total Income') }}</span>
<span class="text-income ml-2" v-if="loading">
<span class="ms-2 text-subtitle-1">{{ queryAllFilterAccountIdsCount ? tt('Total Inflows') : tt('Total Income') }}</span>
<span class="text-income ms-2" v-if="loading">
<v-skeleton-loader type="text" style="width: 60px" :loading="true"></v-skeleton-loader>
</span>
<span class="text-income ml-2" v-else-if="!loading">
<span class="text-income ms-2" v-else-if="!loading">
{{ currentMonthTotalAmount.income }}
</span>
<span class="text-subtitle-1 ml-3">{{ queryAllFilterAccountIdsCount ? tt('Total Outflows') : tt('Total Expense') }}</span>
<span class="text-expense ml-2" v-if="loading">
<span class="text-subtitle-1 ms-3">{{ queryAllFilterAccountIdsCount ? tt('Total Outflows') : tt('Total Expense') }}</span>
<span class="text-expense ms-2" v-if="loading">
<v-skeleton-loader type="text" style="width: 60px" :loading="true"></v-skeleton-loader>
</span>
<span class="text-expense ml-2" v-else-if="!loading">
<span class="text-expense ms-2" v-else-if="!loading">
{{ currentMonthTotalAmount.expense }}
</span>
</div>
@@ -217,10 +217,10 @@
<v-list-item-title class="cursor-pointer"
@click="changeDateFilter(dateRange.type)">
<div class="d-flex align-center">
<span class="text-sm ml-3">{{ dateRange.displayName }}</span>
<span class="text-sm ms-3">{{ dateRange.displayName }}</span>
</div>
</v-list-item-title>
<div class="ml-3 smaller" v-if="((dateRange.isBillingCycle || dateRange.type === DateRange.Custom.type) && query.dateType === dateRange.type) && query.minTime && query.maxTime">
<div class="ms-3 smaller" v-if="((dateRange.isBillingCycle || dateRange.type === DateRange.Custom.type) && query.dateType === dateRange.type) && query.minTime && query.maxTime">
<span>{{ queryMinTime }}</span>
<span>&nbsp;-&nbsp;</span>
<br/>
@@ -253,7 +253,7 @@
@click="changeCategoryFilter('')">
<div class="d-flex align-center">
<v-icon :icon="mdiViewGridOutline" />
<span class="text-sm ml-3">{{ tt('All') }}</span>
<span class="text-sm ms-3">{{ tt('All') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -265,7 +265,7 @@
@click="showFilterCategoryDialog = true">
<div class="d-flex align-center">
<v-icon :icon="mdiVectorArrangeBelow" />
<span class="text-sm ml-3">{{ tt('Multiple Categories') }}</span>
<span class="text-sm ms-3">{{ tt('Multiple Categories') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -287,7 +287,7 @@
<v-list-item-title>
<div class="d-flex align-center">
<ItemIcon icon-type="category" size="24px" :icon-id="category.icon" :color="category.color"></ItemIcon>
<span class="text-sm ml-3">{{ category.name }}</span>
<span class="text-sm ms-3">{{ category.name }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -302,7 +302,7 @@
@click="changeCategoryFilter(category.id)">
<div class="d-flex align-center">
<v-icon :icon="mdiViewGridOutline" />
<span class="text-sm ml-3">{{ tt('All') }}</span>
<span class="text-sm ms-3">{{ tt('All') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -319,7 +319,7 @@
@click="changeCategoryFilter(subCategory.id)">
<div class="d-flex align-center">
<ItemIcon icon-type="category" size="24px" :icon-id="subCategory.icon" :color="subCategory.color"></ItemIcon>
<span class="text-sm ml-3">{{ subCategory.name }}</span>
<span class="text-sm ms-3">{{ subCategory.name }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -349,7 +349,7 @@
<v-list-item-title class="cursor-pointer"
@click="changeAmountFilter('')">
<div class="d-flex align-center">
<span class="text-sm ml-3">{{ tt('All') }}</span>
<span class="text-sm ms-3">{{ tt('All') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -362,18 +362,18 @@
<v-list-item-title class="cursor-pointer"
@click="currentAmountFilterType = filterType.type">
<div class="d-flex align-center">
<span class="text-sm ml-3">{{ tt(filterType.name) }}</span>
<span class="text-sm ml-4" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`) && currentAmountFilterType !== filterType.type">{{ queryAmount }}</span>
<amount-input class="transaction-amount-filter-value ml-4" density="compact"
<span class="text-sm ms-3">{{ tt(filterType.name) }}</span>
<span class="text-sm ms-4" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`) && currentAmountFilterType !== filterType.type">{{ queryAmount }}</span>
<amount-input class="transaction-amount-filter-value ms-4" density="compact"
:currency="defaultCurrency"
v-model="currentAmountFilterValue1"
v-if="currentAmountFilterType === filterType.type"/>
<span class="ml-2 mr-2" v-if="currentAmountFilterType === filterType.type && filterType.paramCount === 2">~</span>
<span class="ms-2 me-2" v-if="currentAmountFilterType === filterType.type && filterType.paramCount === 2">~</span>
<amount-input class="transaction-amount-filter-value" density="compact"
:currency="defaultCurrency"
v-model="currentAmountFilterValue2"
v-if="currentAmountFilterType === filterType.type && filterType.paramCount === 2"/>
<v-btn class="ml-2" density="compact" color="primary" variant="tonal"
<v-btn class="ms-2" density="compact" color="primary" variant="tonal"
@click="changeAmountFilter(filterType.type)"
v-if="currentAmountFilterType === filterType.type">{{ tt('Apply') }}</v-btn>
</div>
@@ -402,7 +402,7 @@
@click="changeAccountFilter('')">
<div class="d-flex align-center">
<v-icon :icon="mdiViewGridOutline" />
<span class="text-sm ml-3">{{ tt('All') }}</span>
<span class="text-sm ms-3">{{ tt('All') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -414,7 +414,7 @@
@click="showFilterAccountDialog = true">
<div class="d-flex align-center">
<v-icon :icon="mdiVectorArrangeBelow" />
<span class="text-sm ml-3">{{ tt('Multiple Accounts') }}</span>
<span class="text-sm ms-3">{{ tt('Multiple Accounts') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -430,7 +430,7 @@
@click="changeAccountFilter(account.id)">
<div class="d-flex align-center">
<ItemIcon icon-type="account" size="24px" :icon-id="account.icon" :color="account.color"></ItemIcon>
<span class="text-sm ml-3">{{ account.name }}</span>
<span class="text-sm ms-3">{{ account.name }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -457,7 +457,7 @@
@click="changeTagFilter('')">
<div class="d-flex align-center">
<v-icon :icon="mdiViewGridOutline" />
<span class="text-sm ml-3">{{ tt('All') }}</span>
<span class="text-sm ms-3">{{ tt('All') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -468,7 +468,7 @@
@click="changeTagFilter('none')">
<div class="d-flex align-center">
<v-icon :icon="mdiBorderNoneVariant" />
<span class="text-sm ml-3">{{ tt('Without Tags') }}</span>
<span class="text-sm ms-3">{{ tt('Without Tags') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -480,7 +480,7 @@
@click="showFilterTagDialog = true">
<div class="d-flex align-center">
<v-icon :icon="mdiVectorArrangeBelow" />
<span class="text-sm ml-3">{{ tt('Multiple Tags') }}</span>
<span class="text-sm ms-3">{{ tt('Multiple Tags') }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -497,7 +497,7 @@
@click="changeTagFilterType(filterType.type)">
<div class="d-flex align-center">
<v-icon size="24" :icon="filterType.icon"/>
<span class="text-sm ml-3">{{ filterType.displayName }}</span>
<span class="text-sm ms-3">{{ filterType.displayName }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -515,7 +515,7 @@
@click="changeTagFilter(transactionTag.id)">
<div class="d-flex align-center">
<v-icon size="24" :icon="mdiPound"/>
<span class="text-sm ml-3">{{ transactionTag.name }}</span>
<span class="text-sm ms-3">{{ transactionTag.name }}</span>
</div>
</v-list-item-title>
</v-list-item>
@@ -549,7 +549,7 @@
<td :colspan="showTagInTransactionListPage ? 6 : 5" class="font-weight-bold">
<div class="d-flex align-center">
<span>{{ getDisplayLongDate(transaction) }}</span>
<v-chip class="ml-1" color="default" size="x-small"
<v-chip class="ms-1" color="default" size="x-small"
v-if="transaction.dayOfWeek">
{{ getWeekdayLongName(transaction.dayOfWeek) }}
</v-chip>
@@ -572,13 +572,13 @@
:color="transaction.category.color"
v-if="transaction.category && transaction.category.color"></ItemIcon>
<v-icon size="24" :icon="mdiPencilBoxOutline" v-else-if="!transaction.category || !transaction.category.color" />
<span class="ml-2" v-if="transaction.type === TransactionType.ModifyBalance">
<span class="ms-2" v-if="transaction.type === TransactionType.ModifyBalance">
{{ tt('Modify Balance') }}
</span>
<span class="ml-2" v-else-if="transaction.type !== TransactionType.ModifyBalance && transaction.category">
<span class="ms-2" v-else-if="transaction.type !== TransactionType.ModifyBalance && transaction.category">
{{ transaction.category.name }}
</span>
<span class="ml-2" v-else-if="transaction.type !== TransactionType.ModifyBalance && !transaction.category">
<span class="ms-2" v-else-if="transaction.type !== TransactionType.ModifyBalance && !transaction.category">
{{ getTransactionTypeName(transaction.type, 'Transaction') }}
</span>
</div>
@@ -591,7 +591,7 @@
<td class="transaction-table-column-account">
<div class="d-flex align-center">
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
<v-icon class="mx-1" size="13" :icon="mdiArrowRight" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></v-icon>
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></v-icon>
<span v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id">{{ transaction.destinationAccount.name }}</span>
</div>
</td>
@@ -1828,11 +1828,11 @@ init(props);
.transaction-table .transaction-table-column-category .v-btn .v-btn__append,
.transaction-table .transaction-table-column-account .v-btn .v-btn__append {
margin-left: 0in;
margin-inline-start: 0in;
}
.transaction-table .transaction-table-column-tags .v-chip.transaction-tag {
margin-right: 4px;
margin-inline-end: 4px;
margin-top: 2px;
margin-bottom: 2px;
}
@@ -5,9 +5,9 @@
<div class="d-flex align-center justify-center">
<div class="d-flex w-100 align-center justify-center">
<h4 class="text-h4">{{ tt('Import Transactions') }}</h4>
<v-progress-circular indeterminate size="22" class="ml-2" v-if="loading"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="loading"></v-progress-circular>
</div>
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
:icon="true" :disabled="loading || submitting"
v-if="currentStep === 'defineColumn'">
<v-icon :icon="mdiDotsVertical" />
@@ -22,7 +22,7 @@
</v-list>
</v-menu>
</v-btn>
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
:icon="true" :disabled="loading || submitting"
v-if="currentStep === 'checkData'">
<v-icon :icon="mdiFilterOutline" />
@@ -110,7 +110,7 @@
</v-list>
</v-menu>
</v-btn>
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
:icon="true" :disabled="loading || submitting"
v-if="currentStep === 'checkData'">
<v-icon :icon="mdiDotsVertical" />
@@ -281,9 +281,9 @@
<v-col cols="12" md="12" class="mb-0 pb-0" v-if="exportFileGuideDocumentUrl">
<a :href="exportFileGuideDocumentUrl" :class="{ 'disabled': submitting }" target="_blank">
<v-icon :icon="mdiHelpCircleOutline" size="16" />
<span class="ml-1" v-if="fileType === 'dsv' || fileType === 'dsv_data'">{{ tt('How to import this file?') }}</span>
<span class="ml-1" v-if="fileType !== 'dsv' && fileType !== 'dsv_data'">{{ tt('How to export this file?') }}</span>
<span class="ml-1" v-if="exportFileGuideDocumentLanguageName">[{{ exportFileGuideDocumentLanguageName }}]</span>
<span class="ms-1" v-if="fileType === 'dsv' || fileType === 'dsv_data'">{{ tt('How to import this file?') }}</span>
<span class="ms-1" v-if="fileType !== 'dsv' && fileType !== 'dsv_data'">{{ tt('How to export this file?') }}</span>
<span class="ms-1" v-if="exportFileGuideDocumentLanguageName">[{{ exportFileGuideDocumentLanguageName }}]</span>
</a>
</v-col>
</v-row>
@@ -332,10 +332,10 @@
<v-btn color="secondary" density="compact" variant="outlined"
:append-icon="parsedFileDataColumnMapping.includeHeader ? mdiCheck : mdiClose"
@click="parsedFileDataColumnMapping.toggleIncludeHeader()">{{ tt('Include Header Line') }}</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
:disabled="!parsedFileDataColumnMapping || !parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionType) || !parsedFileAllTransactionTypes">
<span>{{ tt('Transaction Type Mapping') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionType) && parsedFileAllTransactionTypes">({{ getObjectOwnFieldCount(parsedFileValidMappedTransactionTypes) || tt('None') }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionType) && parsedFileAllTransactionTypes">({{ getObjectOwnFieldCount(parsedFileValidMappedTransactionTypes) || tt('None') }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500"
:close-on-content-click="false">
<v-list class="pa-0">
@@ -363,10 +363,10 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
:disabled="!parsedFileDataColumnMapping || !parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTime)">
<span>{{ tt('Time Format') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTime)">({{ parsedFileDataColumnMapping.timeFormat || parsedFileAutoDetectedTimeFormat || tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTime)">({{ parsedFileDataColumnMapping.timeFormat || parsedFileAutoDetectedTimeFormat || tt('Unknown') }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500">
<v-list>
<v-list-item key="auto"
@@ -374,8 +374,8 @@
@click="parsedFileDataColumnMapping.timeFormat = ''">
<v-list-item-title class="cursor-pointer">
<span>{{ tt('Auto detect') }}</span>
<span class="ml-1" v-if="parsedFileAutoDetectedTimeFormat">({{ parsedFileAutoDetectedTimeFormat }})</span>
<span class="ml-1" v-if="!parsedFileAutoDetectedTimeFormat">({{ tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileAutoDetectedTimeFormat">({{ parsedFileAutoDetectedTimeFormat }})</span>
<span class="ms-1" v-if="!parsedFileAutoDetectedTimeFormat">({{ tt('Unknown') }})</span>
</v-list-item-title>
</v-list-item>
<v-list-item :key="dateTimeFormat.format"
@@ -389,10 +389,10 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTimezone)">
<span>{{ tt('Timezone Format') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTimezone)">({{ KnownDateTimezoneFormat.valueOf(parsedFileDataColumnMapping.timezoneFormat || parsedFileAutoDetectedTimezoneFormat || '')?.name || tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.TransactionTimezone)">({{ KnownDateTimezoneFormat.valueOf(parsedFileDataColumnMapping.timezoneFormat || parsedFileAutoDetectedTimezoneFormat || '')?.name || tt('Unknown') }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500">
<v-list>
<v-list-item key="auto"
@@ -400,8 +400,8 @@
@click="parsedFileDataColumnMapping.timezoneFormat = ''">
<v-list-item-title class="cursor-pointer">
<span>{{ tt('Auto detect') }}</span>
<span class="ml-1" v-if="parsedFileAutoDetectedTimezoneFormat && KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')">({{ KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')?.name }})</span>
<span class="ml-1" v-if="!parsedFileAutoDetectedTimezoneFormat || !KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')">({{ tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileAutoDetectedTimezoneFormat && KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')">({{ KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')?.name }})</span>
<span class="ms-1" v-if="!parsedFileAutoDetectedTimezoneFormat || !KnownDateTimezoneFormat.valueOf(parsedFileAutoDetectedTimezoneFormat || '')">({{ tt('Unknown') }})</span>
</v-list-item-title>
</v-list-item>
<v-list-item :key="timezoneFormat.value"
@@ -415,10 +415,10 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
:disabled="!parsedFileDataColumnMapping || !parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.Amount)">
<span>{{ tt('Amount Format') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.Amount)">({{ KnownAmountFormat.valueOf(parsedFileDataColumnMapping.amountFormat || parsedFileAutoDetectedAmountFormat || '')?.format || tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.Amount)">({{ KnownAmountFormat.valueOf(parsedFileDataColumnMapping.amountFormat || parsedFileAutoDetectedAmountFormat || '')?.format || tt('Unknown') }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500">
<v-list>
<v-list-item key="auto"
@@ -426,8 +426,8 @@
@click="parsedFileDataColumnMapping.amountFormat = ''">
<v-list-item-title class="cursor-pointer">
<span>{{ tt('Auto detect') }}</span>
<span class="ml-1" v-if="parsedFileAutoDetectedAmountFormat && KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')">({{ KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')?.format }})</span>
<span class="ml-1" v-if="!parsedFileAutoDetectedAmountFormat || !KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')">({{ tt('Unknown') }})</span>
<span class="ms-1" v-if="parsedFileAutoDetectedAmountFormat && KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')">({{ KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')?.format }})</span>
<span class="ms-1" v-if="!parsedFileAutoDetectedAmountFormat || !KnownAmountFormat.valueOf(parsedFileAutoDetectedAmountFormat || '')">({{ tt('Unknown') }})</span>
</v-list-item-title>
</v-list-item>
<v-list-item :key="amountFormat.type"
@@ -441,10 +441,10 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.GeographicLocation)">
<span>{{ tt('Geographic Location Separator') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping.geoLocationOrder">({{ parsedFileDataColumnMapping.formatGeoLocation(tt('Latitude'), tt('Longitude')) }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping.geoLocationOrder">({{ parsedFileDataColumnMapping.formatGeoLocation(tt('Latitude'), tt('Longitude')) }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500"
:close-on-content-click="false">
<v-list class="pa-0">
@@ -475,10 +475,10 @@
</v-list>
</v-menu>
</v-btn>
<v-btn class="ml-2" color="secondary" density="compact" variant="outlined"
<v-btn class="ms-2" color="secondary" density="compact" variant="outlined"
v-if="parsedFileDataColumnMapping && parsedFileDataColumnMapping.isColumnMappingSet(ImportTransactionColumnType.Tags)">
<span>{{ tt('Transaction Tags Separator') }}</span>
<span class="ml-1" v-if="parsedFileDataColumnMapping.tagSeparator">({{ parsedFileDataColumnMapping.tagSeparator }})</span>
<span class="ms-1" v-if="parsedFileDataColumnMapping.tagSeparator">({{ parsedFileDataColumnMapping.tagSeparator }})</span>
<v-menu eager activator="parent" location="bottom" max-height="500">
<v-list>
<v-list-item :key="separator.value"
@@ -494,7 +494,7 @@
</v-btn>
<v-spacer/>
<span>{{ tt('Lines Per Page') }}</span>
<v-select class="ml-2" density="compact" max-width="100"
<v-select class="ms-2" density="compact" max-width="100"
item-title="title"
item-value="value"
:disabled="loading || submitting"
@@ -590,7 +590,7 @@
</template>
<template #item.time="{ item }">
<span>{{ getDisplayDateTime(item) }}</span>
<v-chip class="ml-1" variant="flat" color="secondary" size="x-small"
<v-chip class="ms-1" variant="flat" color="secondary" size="x-small"
v-if="item.utcOffset !== currentTimezoneOffsetMinutes">{{ getDisplayTimezone(item) }}</v-chip>
</template>
<template #item.type="{ value }">
@@ -607,11 +607,11 @@
:icon-id="allCategoriesMap[item.categoryId].icon"
:color="allCategoriesMap[item.categoryId].color"
v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]"></ItemIcon>
<span class="ml-2" v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]">
<span class="ms-2" v-if="item.type !== TransactionType.ModifyBalance && item.categoryId && item.categoryId !== '0' && allCategoriesMap[item.categoryId]">
{{ allCategoriesMap[item.categoryId].name }}
</span>
<div class="text-error font-italic" v-else-if="item.type !== TransactionType.ModifyBalance && (!item.categoryId || item.categoryId === '0' || !allCategoriesMap[item.categoryId])">
<v-icon class="mr-1" :icon="mdiAlertOutline"/>
<v-icon class="me-1" :icon="mdiAlertOutline"/>
<span>{{ item.originalCategoryName }}</span>
</div>
</div>
@@ -672,20 +672,20 @@
</template>
<template #item.sourceAmount="{ item }">
<span>{{ getTransactionDisplayAmount(item) }}</span>
<v-icon class="mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer && item.sourceAccountId !== item.destinationAccountId"></v-icon>
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer && item.sourceAccountId !== item.destinationAccountId"></v-icon>
<span v-if="item.type === TransactionType.Transfer && item.sourceAccountId !== item.destinationAccountId">{{ getTransactionDisplayDestinationAmount(item) }}</span>
</template>
<template #item.actualSourceAccountName="{ item }">
<div class="d-flex align-center" v-if="editingTransaction !== item">
<span v-if="item.sourceAccountId && item.sourceAccountId !== '0' && allAccountsMap[item.sourceAccountId]">{{ allAccountsMap[item.sourceAccountId].name }}</span>
<div class="text-error font-italic" v-else>
<v-icon class="mr-1" :icon="mdiAlertOutline"/>
<v-icon class="me-1" :icon="mdiAlertOutline"/>
<span>{{ item.originalSourceAccountName }}</span>
</div>
<v-icon class="mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
<span v-if="item.type === TransactionType.Transfer && item.destinationAccountId && item.destinationAccountId !== '0' && allAccountsMap[item.destinationAccountId]">{{allAccountsMap[item.destinationAccountId].name }}</span>
<div class="text-error font-italic" v-else-if="item.type === TransactionType.Transfer && (!item.destinationAccountId || item.destinationAccountId === '0' || !allAccountsMap[item.destinationAccountId])">
<v-icon class="mr-1" :icon="mdiAlertOutline"/>
<v-icon class="me-1" :icon="mdiAlertOutline"/>
<span>{{ item.originalDestinationAccountName }}</span>
</div>
</div>
@@ -706,7 +706,7 @@
:items="allVisibleCategorizedAccounts"
v-model="item.sourceAccountId">
</two-column-select>
<v-icon class="mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
<v-icon class="icon-with-direction mx-1" size="13" :icon="mdiArrowRight" v-if="item.type === TransactionType.Transfer"></v-icon>
<two-column-select density="compact" variant="plain"
primary-key-field="id" primary-value-field="category"
primary-title-field="name" primary-footer-field="displayBalance"
@@ -790,7 +790,7 @@
</span>
<v-spacer/>
<span>{{ tt('Transactions Per Page') }}</span>
<v-select class="ml-2" density="compact" max-width="100"
<v-select class="ms-2" density="compact" max-width="100"
item-title="title"
item-value="value"
:disabled="loading || submitting"
@@ -815,17 +815,19 @@
<v-btn color="secondary" variant="tonal" :disabled="loading || submitting"
:prepend-icon="mdiClose" @click="close(false)"
v-if="currentStep !== 'finalResult'">{{ tt('Cancel') }}</v-btn>
<v-btn color="primary" :disabled="loading || submitting || (!isImportDataFromTextbox && !importFile) || (isImportDataFromTextbox && !importData)"
<v-btn class="button-icon-with-direction" color="primary"
:disabled="loading || submitting || (!isImportDataFromTextbox && !importFile) || (isImportDataFromTextbox && !importData)"
:append-icon="!submitting ? mdiArrowRight : undefined" @click="parseData"
v-if="currentStep === 'defineColumn' || currentStep === 'uploadFile'">
{{ tt('Next') }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="submitting"></v-progress-circular>
</v-btn>
<v-btn color="teal" :disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
<v-btn class="button-icon-with-direction" color="teal"
:disabled="submitting || !!editingTransaction || selectedImportTransactionCount < 1 || selectedInvalidTransactionCount > 0"
:append-icon="!submitting ? mdiArrowRight : undefined" @click="submit"
v-if="currentStep === 'checkData'">
{{ (submitting && importProcess > 0 ? tt('format.misc.importingTransactions', { process: formatNumberToLocalizedNumerals(importProcess, 2) }) : tt('Import')) }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="submitting"></v-progress-circular>
</v-btn>
<v-btn color="secondary" variant="tonal"
:append-icon="mdiCheck"
@@ -2748,7 +2750,7 @@ defineExpose({
}
.import-transaction-table .v-chip.transaction-tag {
margin-right: 4px;
margin-inline-end: 4px;
margin-top: 2px;
margin-bottom: 2px;
}
@@ -9,7 +9,7 @@
<h4 class="text-h4" v-if="type === 'transferCategory'">{{ tt('Create Nonexistent Transfer Categories') }}</h4>
<h4 class="text-h4" v-if="type === 'tag'">{{ tt('Create Nonexistent Transaction Tags') }}</h4>
</div>
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
:disabled="submitting || !invalidItems || !invalidItems.length" :icon="true">
<v-icon :icon="mdiDotsVertical" />
<v-menu activator="parent">
@@ -53,7 +53,7 @@
<div class="w-100 d-flex justify-center gap-4">
<v-btn :disabled="submitting || !selectedNames || !selectedNames.length" @click="confirm">
{{ tt('OK') }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="submitting"></v-progress-circular>
</v-btn>
<v-btn color="secondary" variant="tonal" :disabled="submitting" @click="cancel">{{ tt('Cancel') }}</v-btn>
</div>
@@ -6,7 +6,7 @@
<div class="d-flex w-100 align-center justify-center">
<h4 class="text-h4">{{ tt('Batch Replace Categories / Accounts / Tags') }}</h4>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" :disabled="loading"
class="ms-2" :icon="true" :disabled="loading"
:loading="loading" @click="reload">
<template #loader>
<v-progress-circular indeterminate size="20"/>
@@ -15,7 +15,7 @@
<v-tooltip activator="parent">{{ tt('Refresh') }}</v-tooltip>
</v-btn>
</div>
<v-btn density="comfortable" color="default" variant="text" class="ml-2"
<v-btn density="comfortable" color="default" variant="text" class="ms-2"
:icon="true" :disabled="loading">
<v-icon :icon="mdiDotsVertical" />
<v-menu activator="parent" max-height="500">
@@ -14,7 +14,7 @@
<h4 class="text-h4" v-if="mode === 'replaceInvalidItems' && type === 'account'">{{ tt('Replace Invalid Accounts') }}</h4>
<h4 class="text-h4" v-if="mode === 'replaceInvalidItems' && type === 'tag'">{{ tt('Replace Invalid Transaction Tags') }}</h4>
<v-btn density="compact" color="default" variant="text" size="24"
class="ml-2" :icon="true" :disabled="loading"
class="ms-2" :icon="true" :disabled="loading"
:loading="loading" @click="reload">
<template #loader>
<v-progress-circular indeterminate size="20"/>
@@ -5,9 +5,9 @@
<div class="d-flex align-center justify-center">
<div class="d-flex w-100 align-center justify-center">
<h4 class="text-h4">{{ tt(title) }}</h4>
<v-progress-circular indeterminate size="22" class="ml-2" v-if="loading"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="loading"></v-progress-circular>
</div>
<v-btn density="comfortable" color="default" variant="text" class="ml-2" :icon="true"
<v-btn density="comfortable" color="default" variant="text" class="ms-2" :icon="true"
:disabled="loading || submitting" v-if="mode !== TransactionEditPageMode.View && (activeTab === 'basicInfo' || (activeTab === 'map' && isSupportGetGeoLocationByClick()))">
<v-icon :icon="mdiDotsVertical" />
<v-menu activator="parent">
@@ -80,7 +80,7 @@
</v-tabs>
</div>
<v-window class="d-flex flex-grow-1 disable-tab-transition w-100-window-container ml-md-5"
<v-window class="d-flex flex-grow-1 disable-tab-transition w-100-window-container ms-md-5"
v-model="activeTab">
<v-window-item value="basicInfo">
<v-form class="mt-2">
@@ -454,7 +454,7 @@
<v-btn :disabled="inputIsEmpty || loading || submitting"
v-if="mode !== TransactionEditPageMode.View" @click="save">
{{ tt(saveButtonTitle) }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="submitting"></v-progress-circular>
</v-btn>
</div>
</template>
@@ -485,7 +485,7 @@
<v-btn color="error" variant="tonal" :disabled="loading || submitting"
v-if="mode === TransactionEditPageMode.View && originalTransactionEditable" @click="remove">
{{ tt('Delete') }}
<v-progress-circular indeterminate size="22" class="ml-2" v-if="submitting"></v-progress-circular>
<v-progress-circular indeterminate size="22" class="ms-2" v-if="submitting"></v-progress-circular>
</v-btn>
<v-btn color="secondary" variant="tonal" :disabled="loading || submitting"
@click="cancel">{{ tt(cancelButtonTitle) }}</v-btn>