diff --git a/packages/editor-ui/src/components/MainSidebar.vue b/packages/editor-ui/src/components/MainSidebar.vue index bb35959474..0ed9eaab58 100644 --- a/packages/editor-ui/src/components/MainSidebar.vue +++ b/packages/editor-ui/src/components/MainSidebar.vue @@ -219,7 +219,7 @@ const onUserActionToggle = (action: string) => { onLogout(); break; case 'settings': - void router.push({ name: VIEWS.PERSONAL_SETTINGS }); + void router.push({ name: VIEWS.SETTINGS }); break; default: break; diff --git a/packages/editor-ui/src/constants.ts b/packages/editor-ui/src/constants.ts index 0ee70b9929..a5236db849 100644 --- a/packages/editor-ui/src/constants.ts +++ b/packages/editor-ui/src/constants.ts @@ -487,6 +487,7 @@ export const enum VIEWS { SETUP = 'SetupView', FORGOT_PASSWORD = 'ForgotMyPasswordView', CHANGE_PASSWORD = 'ChangePasswordView', + SETTINGS = 'Settings', USERS_SETTINGS = 'UsersSettings', LDAP_SETTINGS = 'LdapSettings', PERSONAL_SETTINGS = 'PersonalSettings', diff --git a/packages/editor-ui/src/router.ts b/packages/editor-ui/src/router.ts index f3bf9f656a..cdf162717e 100644 --- a/packages/editor-ui/src/router.ts +++ b/packages/editor-ui/src/router.ts @@ -480,8 +480,10 @@ export const routes: RouteRecordRaw[] = [ }, { path: '/settings', + name: VIEWS.SETTINGS, component: SettingsView, props: true, + redirect: { name: VIEWS.USAGE }, children: [ { path: 'usage', diff --git a/packages/editor-ui/src/views/SettingsView.test.ts b/packages/editor-ui/src/views/SettingsView.test.ts new file mode 100644 index 0000000000..87875147f8 --- /dev/null +++ b/packages/editor-ui/src/views/SettingsView.test.ts @@ -0,0 +1,122 @@ +import { createTestingPinia } from '@pinia/testing'; +import { createRouter, createWebHistory } from 'vue-router'; +import userEvent from '@testing-library/user-event'; +import { createComponentRenderer } from '@/__tests__/render'; +import SettingsView from '@/views/SettingsView.vue'; +import { VIEWS } from '@/constants'; +import { routes as originalRoutes } from '@/router'; + +const component = { template: '
' }; +const settingsRoute = originalRoutes.find((route) => route.name === VIEWS.SETTINGS); + +const settingsRouteChildren = + settingsRoute?.children?.map(({ name, path }) => ({ + name, + path, + component, + })) ?? []; + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { + path: '/', + redirect: '/home', + }, + { + path: '/home', + name: 'Homepage', + redirect: '/home/workflows', + children: [ + { + path: 'workflows', + name: 'Workflows', + component, + }, + { + path: 'credentials', + name: 'Credentials', + component, + }, + { + path: 'executions', + name: 'Executions', + component, + }, + ], + }, + { + path: '/settings', + name: VIEWS.SETTINGS, + component: SettingsView, + props: true, + redirect: { name: VIEWS.USAGE }, + children: settingsRouteChildren, + }, + ], +}); + +const renderView = createComponentRenderer(SettingsView, { + pinia: createTestingPinia(), + global: { + plugins: [router], + }, +}); + +const renderApp = createComponentRenderer( + { + template: '', + }, + { + pinia: createTestingPinia(), + global: { + plugins: [router], + stubs: { + SettingsSidebar: { + template: '
', + }, + }, + }, + }, +); + +describe('SettingsView', () => { + it('should render the view without throwing', () => { + expect(() => renderView()).not.toThrow(); + }); + + test.each([ + ['/', ['/settings', '/settings/users'], '/home/workflows'], + ['/home', ['/settings', '/settings/users'], '/home/workflows'], + ['/home/workflows', ['/settings', '/settings/personal'], '/home/workflows'], + [ + '/home/credentials', + ['/settings', '/settings/personal', '/settings/api', '/settings/environments'], + '/home/credentials', + ], + ['/home/executions', ['/settings'], '/home/executions'], + ['/settings', [], '/home/workflows'], + [ + '/settings', + ['/settings/personal', '/settings/api', '/settings/environments'], + '/home/workflows', + ], + ['/settings/personal', [], '/home/workflows'], + ['/settings/usage', ['/settings/api', '/settings/environments'], '/home/workflows'], + ])( + 'should start from "%s" and visit %s routes and go back to "%s"', + async (startRoute, routes, expectedRoute) => { + const { getByTestId } = renderApp(); + + await router.push(startRoute); + + for (const route of routes) { + await router.push(route); + } + + await userEvent.click(getByTestId('back')); + + expect(router.currentRoute.value.path).toBe(expectedRoute); + }, + ); +}); diff --git a/packages/editor-ui/src/views/SettingsView.vue b/packages/editor-ui/src/views/SettingsView.vue index 3813d2cd91..da3fe44431 100644 --- a/packages/editor-ui/src/views/SettingsView.vue +++ b/packages/editor-ui/src/views/SettingsView.vue @@ -11,9 +11,16 @@ const router = useRouter(); const previousRoute = ref(); function onReturn() { - void router.push( - isRouteLocationRaw(previousRoute.value) ? previousRoute.value : { name: VIEWS.HOMEPAGE }, - ); + const resolvedSettingsRoute = router.resolve({ name: VIEWS.SETTINGS }); + const resolvedPreviousRoute = isRouteLocationRaw(previousRoute.value) + ? router.resolve(previousRoute.value) + : null; + const backRoute = + !resolvedPreviousRoute || resolvedPreviousRoute.path.startsWith(resolvedSettingsRoute.path) + ? { name: VIEWS.HOMEPAGE } + : resolvedPreviousRoute; + + void router.push(backRoute); } onMounted(() => {