mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-13 05:47:31 -08:00
fix(editor): Handling router errors when navigation is canceled by user (#5271)
* 🔨 Handling router errors in main sidebar, removing unused code * 🔨 Handling router errors in modals
This commit is contained in:
parent
731ce96621
commit
911d656f99
|
@ -104,15 +104,7 @@ import { workflowHelpers } from '@/mixins/workflowHelpers';
|
||||||
import { workflowRun } from '@/mixins/workflowRun';
|
import { workflowRun } from '@/mixins/workflowRun';
|
||||||
|
|
||||||
import mixins from 'vue-typed-mixins';
|
import mixins from 'vue-typed-mixins';
|
||||||
import {
|
import { ABOUT_MODAL_KEY, VERSIONS_MODAL_KEY, VIEWS } from '@/constants';
|
||||||
MODAL_CANCEL,
|
|
||||||
MODAL_CLOSE,
|
|
||||||
MODAL_CONFIRMED,
|
|
||||||
ABOUT_MODAL_KEY,
|
|
||||||
VERSIONS_MODAL_KEY,
|
|
||||||
VIEWS,
|
|
||||||
PLACEHOLDER_EMPTY_WORKFLOW_ID,
|
|
||||||
} from '@/constants';
|
|
||||||
import { userHelpers } from '@/mixins/userHelpers';
|
import { userHelpers } from '@/mixins/userHelpers';
|
||||||
import { debounceHelper } from '@/mixins/debounce';
|
import { debounceHelper } from '@/mixins/debounce';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
@ -123,6 +115,7 @@ import { useUsersStore } from '@/stores/users';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { useVersionsStore } from '@/stores/versions';
|
import { useVersionsStore } from '@/stores/versions';
|
||||||
|
import { isNavigationFailure, NavigationFailureType, Route } from 'vue-router';
|
||||||
|
|
||||||
export default mixins(
|
export default mixins(
|
||||||
genericHelpers,
|
genericHelpers,
|
||||||
|
@ -371,25 +364,25 @@ export default mixins(
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'workflows': {
|
case 'workflows': {
|
||||||
if (this.$router.currentRoute.name !== VIEWS.WORKFLOWS) {
|
if (this.$router.currentRoute.name !== VIEWS.WORKFLOWS) {
|
||||||
this.$router.push({ name: VIEWS.WORKFLOWS });
|
this.goToRoute({ name: VIEWS.WORKFLOWS });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'templates': {
|
case 'templates': {
|
||||||
if (this.$router.currentRoute.name !== VIEWS.TEMPLATES) {
|
if (this.$router.currentRoute.name !== VIEWS.TEMPLATES) {
|
||||||
this.$router.push({ name: VIEWS.TEMPLATES });
|
this.goToRoute({ name: VIEWS.TEMPLATES });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'credentials': {
|
case 'credentials': {
|
||||||
if (this.$router.currentRoute.name !== VIEWS.CREDENTIALS) {
|
if (this.$router.currentRoute.name !== VIEWS.CREDENTIALS) {
|
||||||
this.$router.push({ name: VIEWS.CREDENTIALS });
|
this.goToRoute({ name: VIEWS.CREDENTIALS });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'executions': {
|
case 'executions': {
|
||||||
if (this.$router.currentRoute.name !== VIEWS.EXECUTIONS) {
|
if (this.$router.currentRoute.name !== VIEWS.EXECUTIONS) {
|
||||||
this.$router.push({ name: VIEWS.EXECUTIONS });
|
this.goToRoute({ name: VIEWS.EXECUTIONS });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -398,7 +391,7 @@ export default mixins(
|
||||||
if (defaultRoute) {
|
if (defaultRoute) {
|
||||||
const routeProps = this.$router.resolve({ name: defaultRoute });
|
const routeProps = this.$router.resolve({ name: defaultRoute });
|
||||||
if (this.$router.currentRoute.name !== defaultRoute) {
|
if (this.$router.currentRoute.name !== defaultRoute) {
|
||||||
this.$router.push(routeProps.route.path);
|
this.goToRoute(routeProps.route.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -419,55 +412,13 @@ export default mixins(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async createNewWorkflow(): Promise<void> {
|
goToRoute(route: string | { name: string }) {
|
||||||
const result = this.uiStore.stateIsDirty;
|
this.$router.push(route).catch((failure) => {
|
||||||
if (result) {
|
// Catch navigation failures caused by route guards
|
||||||
const confirmModal = await this.confirmModal(
|
if (!isNavigationFailure(failure)) {
|
||||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
console.error(failure);
|
||||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
|
|
||||||
'warning',
|
|
||||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.confirmButtonText'),
|
|
||||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.cancelButtonText'),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
if (confirmModal === MODAL_CONFIRMED) {
|
|
||||||
const saved = await this.saveCurrentWorkflow({}, false);
|
|
||||||
if (saved) await this.settingsStore.fetchPromptsData();
|
|
||||||
if (this.$router.currentRoute.name === VIEWS.NEW_WORKFLOW) {
|
|
||||||
this.$root.$emit('newWorkflow');
|
|
||||||
} else {
|
|
||||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
|
||||||
}
|
|
||||||
this.$showMessage({
|
|
||||||
title: this.$locale.baseText('mainSidebar.showMessage.handleSelect2.title'),
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
} else if (confirmModal === MODAL_CANCEL) {
|
|
||||||
this.uiStore.stateIsDirty = false;
|
|
||||||
if (this.$router.currentRoute.name === VIEWS.NEW_WORKFLOW) {
|
|
||||||
this.$root.$emit('newWorkflow');
|
|
||||||
} else {
|
|
||||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
|
||||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
|
||||||
}
|
|
||||||
this.$showMessage({
|
|
||||||
title: this.$locale.baseText('mainSidebar.showMessage.handleSelect2.title'),
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
} else if (confirmModal === MODAL_CLOSE) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
if (this.$router.currentRoute.name !== VIEWS.NEW_WORKFLOW) {
|
|
||||||
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
|
|
||||||
this.$router.push({ name: VIEWS.NEW_WORKFLOW });
|
|
||||||
}
|
|
||||||
this.$showMessage({
|
|
||||||
title: this.$locale.baseText('mainSidebar.showMessage.handleSelect3.title'),
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.$titleReset();
|
|
||||||
},
|
},
|
||||||
findFirstAccessibleSettingsRoute() {
|
findFirstAccessibleSettingsRoute() {
|
||||||
// Get all settings rotes by filtering them by pageCategory property
|
// Get all settings rotes by filtering them by pageCategory property
|
||||||
|
|
|
@ -155,6 +155,7 @@ import { useWorkflowsEEStore } from '@/stores/workflows.ee';
|
||||||
import { ITelemetryTrackProperties } from 'n8n-workflow';
|
import { ITelemetryTrackProperties } from 'n8n-workflow';
|
||||||
import { useUsageStore } from '@/stores/usage';
|
import { useUsageStore } from '@/stores/usage';
|
||||||
import { BaseTextKey } from '@/plugins/i18n';
|
import { BaseTextKey } from '@/plugins/i18n';
|
||||||
|
import { isNavigationFailure } from 'vue-router';
|
||||||
|
|
||||||
export default mixins(showMessage).extend({
|
export default mixins(showMessage).extend({
|
||||||
name: 'workflow-share-modal',
|
name: 'workflow-share-modal',
|
||||||
|
@ -427,7 +428,11 @@ export default mixins(showMessage).extend({
|
||||||
await this.usersStore.fetchUsers();
|
await this.usersStore.fetchUsers();
|
||||||
},
|
},
|
||||||
goToUsersSettings() {
|
goToUsersSettings() {
|
||||||
this.$router.push({ name: VIEWS.USERS_SETTINGS });
|
this.$router.push({ name: VIEWS.USERS_SETTINGS }).catch((failure) => {
|
||||||
|
if (!isNavigationFailure(failure)) {
|
||||||
|
console.error(failure);
|
||||||
|
}
|
||||||
|
});
|
||||||
this.modalBus.$emit('close');
|
this.modalBus.$emit('close');
|
||||||
},
|
},
|
||||||
trackTelemetry(data: ITelemetryTrackProperties) {
|
trackTelemetry(data: ITelemetryTrackProperties) {
|
||||||
|
|
Loading…
Reference in a new issue