diff --git a/src/consts/api.ts b/src/consts/api.ts
index e84b2c9c..95b8be2e 100644
--- a/src/consts/api.ts
+++ b/src/consts/api.ts
@@ -17,6 +17,7 @@ export const AMAP_JAVASCRIPT_URL: string = 'https://webapi.amap.com/maps?v=2.0';
export enum KnownErrorCode {
ApiNotFound = 100001,
ValidatorError = 200000,
+ NothingWillBeUpdated = 200004,
UserEmailNotVerified = 201020,
TwoFactorAuthorizationPasscodeEmpty = 203005,
TransactionCannotCreateInThisTime = 205017,
diff --git a/src/views/desktop/insights/ExplorerPage.vue b/src/views/desktop/insights/ExplorerPage.vue
index a13219d7..92320399 100644
--- a/src/views/desktop/insights/ExplorerPage.vue
+++ b/src/views/desktop/insights/ExplorerPage.vue
@@ -74,7 +74,9 @@
{{ tt('Refresh') }}
-
{{ tt('Save Explorer') }}
@@ -171,7 +173,7 @@ import ExplorerRenameDialog from '@/views/desktop/insights/dialogs/ExplorerRenam
import EditDialog from '@/views/desktop/transactions/list/dialogs/EditDialog.vue';
import ExportDialog from '@/views/desktop/statistics/transaction/dialogs/ExportDialog.vue';
-import { ref, computed, useTemplateRef, watch } from 'vue';
+import { ref, computed, useTemplateRef, watch, nextTick } from 'vue';
import { useRouter, onBeforeRouteUpdate } from 'vue-router';
import { useDisplay } from 'vuetify';
@@ -187,6 +189,7 @@ import { type TransactionExplorerPartialFilter, type TransactionExplorerFilter,
import type { TypeAndDisplayName } from '@/core/base.ts';
import { type WeekDayValue, type LocalizedDateRange, DateRangeScene, DateRange } from '@/core/datetime.ts';
import { TimezoneTypeForStatistics } from '@/core/timezone.ts';
+import { KnownErrorCode } from '@/consts/api.ts';
import { type TransactionInsightDataItem, Transaction } from '@/models/transaction.ts';
import { InsightsExplorerBasicInfo, InsightsExplorer } from '@/models/explorer.ts';
@@ -270,6 +273,7 @@ const loading = ref(true);
const initing = ref(true);
const updating = ref(false);
const clientSessionId = ref('');
+const isCurrentExplorerModified = ref(false);
const alwaysShowNav = ref(display.mdAndUp.value);
const showNav = ref(display.mdAndUp.value);
const activeTab = ref('query');
@@ -375,6 +379,7 @@ function init(initProps: InsightsExplorerProps): void {
}
} else {
explorersStore.updateCurrentInsightsExplorer(InsightsExplorer.createNewExplorer(generateRandomUUID()));
+ isCurrentExplorerModified.value = true;
}
if (!needReload && !explorersStore.transactionExplorerStateInvalid && !explorersStore.insightsExplorerListStateInvalid) {
@@ -429,6 +434,7 @@ function createNewExplorer(): void {
}
explorersStore.updateCurrentInsightsExplorer(InsightsExplorer.createNewExplorer(generateRandomUUID()));
+ isCurrentExplorerModified.value = true;
router.push(getFilterLinkUrl());
}
@@ -443,6 +449,11 @@ function loadExplorer(explorerId: string): void {
explorerId: explorerId
}).then(explorer => {
explorersStore.updateCurrentInsightsExplorer(explorer);
+
+ nextTick(() => {
+ isCurrentExplorerModified.value = false;
+ });
+
loading.value = false;
router.push(getFilterLinkUrl());
}).catch(error => {
@@ -479,6 +490,10 @@ function doSaveExplorer(saveAs?: boolean): Promise {
clientSessionId.value = generateRandomUUID();
explorersStore.updateCurrentInsightsExplorer(newExplorer);
+ nextTick(() => {
+ isCurrentExplorerModified.value = false;
+ });
+
if (oldExplorerId !== newExplorer.id) {
router.push(getFilterLinkUrl());
}
@@ -487,6 +502,12 @@ function doSaveExplorer(saveAs?: boolean): Promise {
if (!error.processed) {
snackbar.value?.showError(error);
+
+ if (error.error && error.error.errorCode === KnownErrorCode.NothingWillBeUpdated) {
+ nextTick(() => {
+ isCurrentExplorerModified.value = false;
+ });
+ }
}
});
}
@@ -506,6 +527,10 @@ function hideExplorer(hidden: boolean): void {
}).then(() => {
updating.value = false;
currentExplorer.value.hidden = hidden;
+
+ nextTick(() => {
+ isCurrentExplorerModified.value = false;
+ });
}).catch(error => {
updating.value = false;
@@ -670,5 +695,15 @@ watch(activeTab, () => {
router.push(getFilterLinkUrl());
});
+watch(currentExplorer, () => {
+ if (initing.value || loading.value) {
+ return;
+ }
+
+ isCurrentExplorerModified.value = true;
+}, {
+ deep: true
+});
+
init(props);