allow pressing ESC or clicking outside to close add dialog when nothing is modified

This commit is contained in:
MaysWind
2025-03-31 00:00:16 +08:00
parent 433a225b9d
commit 0a5f8862ad
12 changed files with 106 additions and 17 deletions
+37
View File
@@ -81,6 +81,43 @@ export class Account implements AccountInfoResponse {
return !this.visible;
}
public equals(other: Account): boolean {
const isEqual = this.id === other.id &&
this.name === other.name &&
this.parentId === other.parentId &&
this.category === other.category &&
this.type === other.type &&
this.icon === other.icon &&
this.color === other.color &&
this.currency === other.currency &&
this.balance === other.balance &&
this.balanceTime === other.balanceTime &&
this.comment === other.comment &&
this.displayOrder === other.displayOrder &&
this.visible === other.visible &&
this.creditCardStatementDate === other.creditCardStatementDate;
if (!isEqual) {
return false;
}
if (this.subAccounts && other.subAccounts) {
if (this.subAccounts.length !== other.subAccounts.length) {
return false;
}
for (let i = 0; i < this.subAccounts.length; i++) {
if (!this.subAccounts[i].equals(other.subAccounts[i])) {
return false;
}
}
} else if ((this.subAccounts && this.subAccounts.length) || (other.subAccounts && other.subAccounts.length)) {
return false;
}
return true;
}
public fillFrom(other: Account): void {
this.id = other.id;
this.category = other.category;
+32
View File
@@ -37,6 +37,38 @@ export class TransactionCategory implements TransactionCategoryInfoResponse {
return !this.visible;
}
public equals(other: TransactionCategory): boolean {
const isEqual = this.id === other.id &&
this.name === other.name &&
this.parentId === other.parentId &&
this.type === other.type &&
this.icon === other.icon &&
this.color === other.color &&
this.comment === other.comment &&
this.displayOrder === other.displayOrder &&
this.visible === other.visible;
if (!isEqual) {
return false;
}
if (this.subCategories && other.subCategories) {
if (this.subCategories.length !== other.subCategories.length) {
return false;
}
for (let i = 0; i < this.subCategories.length; i++) {
if (!this.subCategories[i].equals(other.subCategories[i])) {
return false;
}
}
} else if ((this.subCategories && this.subCategories.length) || (other.subCategories && other.subCategories.length)) {
return false;
}
return true;
}
public fillFrom(other: TransactionCategory): void {
this.id = other.id;
this.name = other.name;
+1 -1
View File
@@ -248,7 +248,7 @@
</v-col>
</v-row>
<edit-dialog ref="editDialog" :persistent="true" />
<edit-dialog ref="editDialog" />
<confirm-dialog ref="confirmDialog"/>
<snack-bar ref="snackbar" />
@@ -1,5 +1,5 @@
<template>
<v-dialog :width="account.type === AccountType.MultiSubAccounts.type ? 1000 : 800" :persistent="!!persistent" v-model="showState">
<v-dialog :width="account.type === AccountType.MultiSubAccounts.type ? 1000 : 800" :persistent="isAccountModified" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-8">
<template #title>
<div class="d-flex align-center justify-center">
@@ -220,7 +220,6 @@ type ConfirmDialogType = InstanceType<typeof ConfirmDialog>;
type SnackBarType = InstanceType<typeof SnackBar>;
defineProps<{
persistent?: boolean;
show?: boolean;
}>();
@@ -270,6 +269,14 @@ const accountAmountTitle = computed<string>(() => {
}
});
const isAccountModified = computed<boolean>(() => {
if (!editAccountId.value) {
return !account.value.equals(Account.createNewAccount(userStore.currentUserDefaultCurrency, account.value.balanceTime ?? getCurrentUnixTime()));
} else {
return true;
}
});
let resolveFunc: ((value: AccountEditResponse) => void) | null = null;
let rejectFunc: ((reason?: unknown) => void) | null = null;
+1 -1
View File
@@ -183,7 +183,7 @@
</v-col>
</v-row>
<edit-dialog ref="editDialog" :persistent="true" />
<edit-dialog ref="editDialog" />
<preset-dialog :category-type="activeCategoryType" v-model:show="showPresetDialog"
@category:saved="onPresetCategorySaved" />
@@ -1,5 +1,5 @@
<template>
<v-dialog width="800" :persistent="!!persistent" v-model="showState">
<v-dialog width="800" :persistent="isCategoryModified" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-8">
<template #title>
<div class="d-flex align-center justify-center">
@@ -96,7 +96,7 @@
<script setup lang="ts">
import SnackBar from '@/components/desktop/SnackBar.vue';
import { ref, useTemplateRef } from 'vue';
import { ref, computed, useTemplateRef } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useCategoryEditPageBase } from '@/views/base/categories/CategoryEditPageBase.ts';
@@ -116,10 +116,6 @@ interface TransactionCategoryEditResponse {
type SnackBarType = InstanceType<typeof SnackBar>;
defineProps<{
persistent?: boolean;
}>();
const { tt } = useI18n();
const {
editCategoryId,
@@ -143,6 +139,14 @@ const showState = ref<boolean>(false);
let resolveFunc: ((value: TransactionCategoryEditResponse) => void) | null = null;
let rejectFunc: ((reason?: unknown) => void) | null = null;
const isCategoryModified = computed<boolean>(() => {
if (!editCategoryId.value) { // Add
return !category.value.equals(TransactionCategory.createNewCategory(category.value.type, category.value.parentId));
} else { // Edit
return true;
}
});
function open(options: { id?: string; parentId?: string; type?: CategoryType; currentCategory?: TransactionCategory }): Promise<TransactionCategoryEditResponse> {
showState.value = true;
loading.value = true;
@@ -1,5 +1,5 @@
<template>
<v-dialog width="800" :persistent="!!persistent" v-model="showState">
<v-dialog width="800" :persistent="submitting" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-8">
<template #title>
<div class="d-flex align-center justify-center">
@@ -73,7 +73,6 @@ type SnackBarType = InstanceType<typeof SnackBar>;
const props = defineProps<{
categoryType: CategoryType;
persistent?: boolean;
show: boolean;
}>();
+1 -1
View File
@@ -139,7 +139,7 @@
</v-col>
</v-row>
<edit-dialog ref="editDialog" :type="TransactionEditPageType.Template" :persistent="true" />
<edit-dialog ref="editDialog" :type="TransactionEditPageType.Template" />
<confirm-dialog ref="confirmDialog"/>
<snack-bar ref="snackbar" />
+1 -1
View File
@@ -557,7 +557,7 @@
v-model:show="showCustomDateRangeDialog"
@dateRange:change="changeCustomDateFilter"
@error="onShowDateRangeError" />
<edit-dialog ref="editDialog" :type="TransactionEditPageType.Transaction" :persistent="true" />
<edit-dialog ref="editDialog" :type="TransactionEditPageType.Transaction" />
<import-dialog ref="importDialog" :persistent="true" />
<v-dialog width="800" v-model="showFilterAccountDialog">
@@ -1,5 +1,5 @@
<template>
<v-dialog width="600" :persistent="!!submitting || !!selectedNames.length" v-model="showState">
<v-dialog width="600" :persistent="submitting || !!selectedNames.length" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-4">
<template #title>
<div class="d-flex align-center justify-center">
@@ -1,5 +1,5 @@
<template>
<v-dialog width="600" :persistent="!!loading || (mode === 'replaceInvalidItems' && !!sourceItem) || !!targetItem" v-model="showState">
<v-dialog width="600" :persistent="loading || (mode === 'replaceInvalidItems' && !!sourceItem) || !!targetItem" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-4">
<template #title>
<div class="d-flex align-center justify-center">
@@ -1,5 +1,5 @@
<template>
<v-dialog width="1000" :persistent="!!persistent && mode !== TransactionEditPageMode.View" v-model="showState">
<v-dialog width="1000" :persistent="isTransactionModified" v-model="showState">
<v-card class="pa-2 pa-sm-4 pa-md-8">
<template #title>
<div class="d-flex align-center justify-center">
@@ -626,6 +626,16 @@ const isAllFilteredTagHidden = computed<boolean>(() => {
return hiddenCount > 0;
});
const isTransactionModified = computed<boolean>(() => {
if (mode.value === TransactionEditPageMode.Add) {
return transactionsStore.isTransactionDraftModified(transaction.value, initCategoryId.value, initAccountId.value, initTagIds.value);
} else if (mode.value === TransactionEditPageMode.Edit) {
return true;
} else {
return false;
}
});
function setTransaction(newTransaction: Transaction | null, options: SetTransactionOptions, setContextData: boolean, convertContextTime: boolean): void {
setTransactionModelByTransaction(
transaction.value,