mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 02:21:13 +00:00
fix(editor): Follow-up fixes to projects side menu (#11327)
This commit is contained in:
@@ -147,7 +147,8 @@ describe('ProjectsNavigation', () => {
|
|||||||
expect(uiStore.goToUpgrade).toHaveBeenCalledWith('rbac', 'upgrade-rbac');
|
expect(uiStore.goToUpgrade).toHaveBeenCalledWith('rbac', 'upgrade-rbac');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show "Projects" title and projects if the user has access to any team project', async () => {
|
it('should show "Projects" title and Personal project when the feature is enabled', async () => {
|
||||||
|
projectsStore.isTeamProjectFeatureEnabled = true;
|
||||||
projectsStore.myProjects = [...personalProjects, ...teamProjects];
|
projectsStore.myProjects = [...personalProjects, ...teamProjects];
|
||||||
|
|
||||||
const { getByRole, getAllByTestId, getByTestId } = renderComponent({
|
const { getByRole, getAllByTestId, getByTestId } = renderComponent({
|
||||||
@@ -158,11 +159,12 @@ describe('ProjectsNavigation', () => {
|
|||||||
|
|
||||||
expect(getByRole('heading', { level: 3, name: 'Projects' })).toBeVisible();
|
expect(getByRole('heading', { level: 3, name: 'Projects' })).toBeVisible();
|
||||||
expect(getByTestId('project-personal-menu-item')).toBeVisible();
|
expect(getByTestId('project-personal-menu-item')).toBeVisible();
|
||||||
|
expect(getByTestId('project-personal-menu-item').querySelector('svg')).toBeVisible();
|
||||||
expect(getAllByTestId('project-menu-item')).toHaveLength(teamProjects.length);
|
expect(getAllByTestId('project-menu-item')).toHaveLength(teamProjects.length);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not show "Projects" title when the menu is collapsed', async () => {
|
it('should not show "Projects" title when the menu is collapsed', async () => {
|
||||||
projectsStore.myProjects = [...personalProjects, ...teamProjects];
|
projectsStore.isTeamProjectFeatureEnabled = true;
|
||||||
|
|
||||||
const { queryByRole } = renderComponent({
|
const { queryByRole } = renderComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -173,8 +175,8 @@ describe('ProjectsNavigation', () => {
|
|||||||
expect(queryByRole('heading', { level: 3, name: 'Projects' })).not.toBeInTheDocument();
|
expect(queryByRole('heading', { level: 3, name: 'Projects' })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not show "Projects" title when there are no available projects', async () => {
|
it('should not show "Projects" title when the feature is not enabled', async () => {
|
||||||
projectsStore.myProjects = [];
|
projectsStore.isTeamProjectFeatureEnabled = false;
|
||||||
|
|
||||||
const { queryByRole } = renderComponent({
|
const { queryByRole } = renderComponent({
|
||||||
props: {
|
props: {
|
||||||
@@ -184,4 +186,17 @@ describe('ProjectsNavigation', () => {
|
|||||||
|
|
||||||
expect(queryByRole('heading', { level: 3, name: 'Projects' })).not.toBeInTheDocument();
|
expect(queryByRole('heading', { level: 3, name: 'Projects' })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not show project icons when the menu is collapsed', async () => {
|
||||||
|
projectsStore.isTeamProjectFeatureEnabled = true;
|
||||||
|
|
||||||
|
const { getByTestId } = renderComponent({
|
||||||
|
props: {
|
||||||
|
collapsed: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getByTestId('project-personal-menu-item')).toBeVisible();
|
||||||
|
expect(getByTestId('project-personal-menu-item').querySelector('svg')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const addProject = computed<IMenuItem>(() => ({
|
|||||||
const getProjectMenuItem = (project: ProjectListItem) => ({
|
const getProjectMenuItem = (project: ProjectListItem) => ({
|
||||||
id: project.id,
|
id: project.id,
|
||||||
label: project.name,
|
label: project.name,
|
||||||
icon: 'layer-group',
|
icon: props.collapsed ? undefined : 'layer-group',
|
||||||
route: {
|
route: {
|
||||||
to: {
|
to: {
|
||||||
name: VIEWS.PROJECTS_WORKFLOWS,
|
name: VIEWS.PROJECTS_WORKFLOWS,
|
||||||
@@ -57,7 +57,7 @@ const getProjectMenuItem = (project: ProjectListItem) => ({
|
|||||||
const personalProject = computed<IMenuItem>(() => ({
|
const personalProject = computed<IMenuItem>(() => ({
|
||||||
id: projectsStore.personalProject?.id ?? '',
|
id: projectsStore.personalProject?.id ?? '',
|
||||||
label: locale.baseText('projects.menu.personal'),
|
label: locale.baseText('projects.menu.personal'),
|
||||||
icon: 'user',
|
icon: props.collapsed ? undefined : 'user',
|
||||||
route: {
|
route: {
|
||||||
to: {
|
to: {
|
||||||
name: VIEWS.PROJECTS_WORKFLOWS,
|
name: VIEWS.PROJECTS_WORKFLOWS,
|
||||||
@@ -119,16 +119,20 @@ onMounted(async () => {
|
|||||||
data-test-id="project-home-menu-item"
|
data-test-id="project-home-menu-item"
|
||||||
/>
|
/>
|
||||||
</ElMenu>
|
</ElMenu>
|
||||||
<hr v-if="displayProjects.length || canCreateProjects" class="mt-m mb-m" />
|
<hr v-if="projectsStore.isTeamProjectFeatureEnabled" class="mt-m mb-m" />
|
||||||
<N8nText
|
<N8nText
|
||||||
v-if="!props.collapsed && displayProjects.length"
|
v-if="!props.collapsed && projectsStore.isTeamProjectFeatureEnabled"
|
||||||
:class="$style.projectsLabel"
|
:class="$style.projectsLabel"
|
||||||
tag="h3"
|
tag="h3"
|
||||||
bold
|
bold
|
||||||
>
|
>
|
||||||
<span>{{ locale.baseText('projects.menu.title') }}</span>
|
<span>{{ locale.baseText('projects.menu.title') }}</span>
|
||||||
</N8nText>
|
</N8nText>
|
||||||
<ElMenu v-if="displayProjects.length" :collapse="props.collapsed" :class="$style.projectItems">
|
<ElMenu
|
||||||
|
v-if="projectsStore.isTeamProjectFeatureEnabled"
|
||||||
|
:collapse="props.collapsed"
|
||||||
|
:class="$style.projectItems"
|
||||||
|
>
|
||||||
<N8nMenuItem
|
<N8nMenuItem
|
||||||
:item="personalProject"
|
:item="personalProject"
|
||||||
:compact="props.collapsed"
|
:compact="props.collapsed"
|
||||||
@@ -154,7 +158,7 @@ onMounted(async () => {
|
|||||||
placement="right"
|
placement="right"
|
||||||
:disabled="projectsStore.canCreateProjects"
|
:disabled="projectsStore.canCreateProjects"
|
||||||
>
|
>
|
||||||
<ElMenu :collapse="props.collapsed" class="pl-xs pr-xs">
|
<ElMenu :collapse="props.collapsed" class="pl-xs pr-xs mb-m">
|
||||||
<N8nMenuItem
|
<N8nMenuItem
|
||||||
:item="addProject"
|
:item="addProject"
|
||||||
:compact="props.collapsed"
|
:compact="props.collapsed"
|
||||||
@@ -182,7 +186,7 @@ onMounted(async () => {
|
|||||||
</i18n-t>
|
</i18n-t>
|
||||||
</template>
|
</template>
|
||||||
</N8nTooltip>
|
</N8nTooltip>
|
||||||
<hr v-if="displayProjects.length || canCreateProjects" class="mt-m mb-m" />
|
<hr v-if="projectsStore.isTeamProjectFeatureEnabled" class="mb-m" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { createComponentRenderer } from '@/__tests__/render';
|
|||||||
import { createTestProject } from '@/__tests__/data/projects';
|
import { createTestProject } from '@/__tests__/data/projects';
|
||||||
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
|
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
|
||||||
import { useProjectsStore } from '@/stores/projects.store';
|
import { useProjectsStore } from '@/stores/projects.store';
|
||||||
|
import { ProjectTypes } from '@/types/projects.types';
|
||||||
|
|
||||||
vi.mock('vue-router', () => {
|
vi.mock('vue-router', () => {
|
||||||
const params = {};
|
const params = {};
|
||||||
@@ -47,7 +48,7 @@ describe('ProjectTabs', () => {
|
|||||||
expect(queryByText('Project settings')).not.toBeInTheDocument();
|
expect(queryByText('Project settings')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render project tab Settings if user has permissions', () => {
|
it('should render project tab Settings if user has permissions and current project is of type Team', () => {
|
||||||
route.params.projectId = '123';
|
route.params.projectId = '123';
|
||||||
projectsStore.setCurrentProject(createTestProject({ scopes: ['project:update'] }));
|
projectsStore.setCurrentProject(createTestProject({ scopes: ['project:update'] }));
|
||||||
const { getByText } = renderComponent();
|
const { getByText } = renderComponent();
|
||||||
@@ -66,4 +67,16 @@ describe('ProjectTabs', () => {
|
|||||||
expect(getByText('Credentials')).toBeInTheDocument();
|
expect(getByText('Credentials')).toBeInTheDocument();
|
||||||
expect(queryByText('Project settings')).not.toBeInTheDocument();
|
expect(queryByText('Project settings')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render project tabs without Settings if project is the Personal project', () => {
|
||||||
|
route.params.projectId = '123';
|
||||||
|
projectsStore.setCurrentProject(
|
||||||
|
createTestProject({ type: ProjectTypes.Personal, scopes: ['project:update'] }),
|
||||||
|
);
|
||||||
|
const { queryByText, getByText } = renderComponent();
|
||||||
|
|
||||||
|
expect(getByText('Workflows')).toBeInTheDocument();
|
||||||
|
expect(getByText('Credentials')).toBeInTheDocument();
|
||||||
|
expect(queryByText('Project settings')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { VIEWS } from '@/constants';
|
|||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { useProjectsStore } from '@/stores/projects.store';
|
import { useProjectsStore } from '@/stores/projects.store';
|
||||||
import { getResourcePermissions } from '@/permissions';
|
import { getResourcePermissions } from '@/permissions';
|
||||||
|
import { ProjectTypes } from '@/types/projects.types';
|
||||||
|
|
||||||
const locale = useI18n();
|
const locale = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -50,7 +51,11 @@ const options = computed(() => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (projectId && projectPermissions.value.update) {
|
if (
|
||||||
|
projectId &&
|
||||||
|
projectPermissions.value.update &&
|
||||||
|
projectsStore.currentProject?.type === ProjectTypes.Team
|
||||||
|
) {
|
||||||
tabs.push({
|
tabs.push({
|
||||||
label: locale.baseText('projects.settings'),
|
label: locale.baseText('projects.settings'),
|
||||||
value: VIEWS.PROJECT_SETTINGS,
|
value: VIEWS.PROJECT_SETTINGS,
|
||||||
|
|||||||
Reference in New Issue
Block a user