fix(editor): Show shared with me only on multi user instances (#16770)

This commit is contained in:
Nikhil Kuriakose
2025-07-03 09:07:11 +02:00
committed by GitHub
parent e54613f75f
commit 29bf4a46bd
2 changed files with 56 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import { createProjectListItem } from '@/__tests__/data/projects';
import ProjectsNavigation from '@/components/Projects/ProjectNavigation.vue';
import { useProjectsStore } from '@/stores/projects.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
vi.mock('vue-router', async () => {
const actual = await vi.importActual('vue-router');
@@ -64,6 +65,7 @@ const renderComponent = createComponentRenderer(ProjectsNavigation, {
let projectsStore: ReturnType<typeof mockedStore<typeof useProjectsStore>>;
let settingsStore: ReturnType<typeof mockedStore<typeof useSettingsStore>>;
let usersStore: ReturnType<typeof mockedStore<typeof useUsersStore>>;
const personalProjects = Array.from({ length: 3 }, createProjectListItem);
const teamProjects = Array.from({ length: 3 }, () => createProjectListItem('team'));
@@ -74,6 +76,7 @@ describe('ProjectsNavigation', () => {
projectsStore = mockedStore(useProjectsStore);
settingsStore = mockedStore(useSettingsStore);
usersStore = mockedStore(useUsersStore);
});
it('should not throw an error', () => {
@@ -226,4 +229,43 @@ describe('ProjectsNavigation', () => {
expect(getByTestId('add-first-project-button')).toBeVisible();
expect(getByTestId('add-first-project-button').classList.contains('collapsed')).toBe(true);
});
it('should not render shared menu item when only one verified user', async () => {
// Only one verified user
usersStore.allUsers = [
{ id: '1', isPendingUser: false, isDefaultUser: false, mfaEnabled: false },
{ id: '2', isPendingUser: true, isDefaultUser: false, mfaEnabled: false },
];
projectsStore.teamProjectsLimit = -1;
projectsStore.isTeamProjectFeatureEnabled = true;
const { queryByTestId } = renderComponent({
props: {
collapsed: false,
},
});
// The shared menu item should not be rendered
expect(queryByTestId('project-shared-menu-item')).not.toBeInTheDocument();
});
it('should render shared menu item when more than one verified user', async () => {
// Only one verified user
usersStore.allUsers = [
{ id: '1', isPendingUser: false, isDefaultUser: false, mfaEnabled: false },
{ id: '2', isPendingUser: true, isDefaultUser: false, mfaEnabled: false },
{ id: '3', isPendingUser: false, isDefaultUser: false, mfaEnabled: false },
];
projectsStore.teamProjectsLimit = -1;
projectsStore.isTeamProjectFeatureEnabled = true;
const { getByTestId } = renderComponent({
props: {
collapsed: false,
},
});
// The shared menu item should not be rendered
expect(getByTestId('project-shared-menu-item')).toBeInTheDocument();
});
});

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { computed } from 'vue';
import { computed, onBeforeMount } from 'vue';
import type { IMenuItem } from '@n8n/design-system/types';
import { useI18n } from '@n8n/i18n';
import { VIEWS } from '@/constants';
@@ -7,6 +7,7 @@ import { useProjectsStore } from '@/stores/projects.store';
import type { ProjectListItem } from '@/types/projects.types';
import { useGlobalEntityCreation } from '@/composables/useGlobalEntityCreation';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
type Props = {
collapsed: boolean;
@@ -20,10 +21,14 @@ const globalEntityCreation = useGlobalEntityCreation();
const projectsStore = useProjectsStore();
const settingsStore = useSettingsStore();
const usersStore = useUsersStore();
const isCreatingProject = computed(() => globalEntityCreation.isCreatingProject.value);
const displayProjects = computed(() => globalEntityCreation.displayProjects.value);
const isFoldersFeatureEnabled = computed(() => settingsStore.isFoldersFeatureEnabled);
const hasMultipleVerifiedUsers = computed(
() => usersStore.allUsers.filter((user) => user.isPendingUser === false).length > 1,
);
const home = computed<IMenuItem>(() => ({
id: 'home',
@@ -78,6 +83,10 @@ const activeTabId = computed(() => {
: projectsStore.projectNavActiveId) ?? undefined
);
});
onBeforeMount(async () => {
await usersStore.fetchUsers();
});
</script>
<template>
@@ -99,7 +108,10 @@ const activeTabId = computed(() => {
data-test-id="project-personal-menu-item"
/>
<N8nMenuItem
v-if="projectsStore.isTeamProjectFeatureEnabled || isFoldersFeatureEnabled"
v-if="
(projectsStore.isTeamProjectFeatureEnabled || isFoldersFeatureEnabled) &&
hasMultipleVerifiedUsers
"
:item="shared"
:compact="props.collapsed"
:active-tab="activeTabId"