mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-01 09:17:08 +02:00
fix(editor): Render fallback icon for projects without one in sidebar (#30572)
This commit is contained in:
parent
cebb78d515
commit
cd1bae84e9
|
|
@ -176,6 +176,23 @@ describe('ProjectsNavigation', () => {
|
|||
expect(getByText('Projects')).toBeVisible();
|
||||
});
|
||||
|
||||
it('should render a fallback icon for projects with no icon set', async () => {
|
||||
projectsStore.teamProjectsLimit = -1;
|
||||
const projectWithoutIcon = createProjectListItem('team');
|
||||
projectWithoutIcon.icon = null;
|
||||
projectsStore.myProjects = [projectWithoutIcon];
|
||||
|
||||
const { getAllByTestId } = renderComponent({
|
||||
props: {
|
||||
collapsed: false,
|
||||
},
|
||||
});
|
||||
|
||||
const items = getAllByTestId('project-menu-item');
|
||||
expect(items).toHaveLength(1);
|
||||
expect(items[0].querySelector('svg')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not render shared menu item when only one verified user', async () => {
|
||||
// Only one verified user
|
||||
usersStore.allUsers = [
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import type { IMenuItem } from '@n8n/design-system/types';
|
|||
import { useI18n } from '@n8n/i18n';
|
||||
import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue';
|
||||
import { useProjectsStore } from '../projects.store';
|
||||
import { DEFAULT_PROJECT_ICON } from '../projects.constants';
|
||||
import type { ProjectListItem } from '../projects.types';
|
||||
import { CHAT_VIEW } from '@/features/ai/chatHub/constants';
|
||||
import { useFavoritesStore } from '@/app/stores/favorites.store';
|
||||
|
|
@ -91,7 +92,7 @@ const shared = computed<IMenuItem>(() => ({
|
|||
const getProjectMenuItem = (project: ProjectListItem): IMenuItem => ({
|
||||
id: project.id,
|
||||
label: project.name ?? '',
|
||||
icon: project.icon as IMenuItem['icon'],
|
||||
icon: (project.icon as IMenuItem['icon']) ?? DEFAULT_PROJECT_ICON,
|
||||
route: {
|
||||
to: {
|
||||
name: VIEWS.PROJECTS_WORKFLOWS,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,10 @@ describe('useFavoriteNavItems', () => {
|
|||
|
||||
const { favoriteProjectItems } = useFavoriteNavItems();
|
||||
|
||||
expect(favoriteProjectItems.value[0].menuItem.icon).toBe('layers');
|
||||
expect(favoriteProjectItems.value[0].menuItem.icon).toEqual({
|
||||
type: 'icon',
|
||||
value: 'layers',
|
||||
});
|
||||
});
|
||||
|
||||
it('should use raw resourceId as item id (no prefix)', () => {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import type { IMenuItem } from '@n8n/design-system/types';
|
|||
import { VIEWS } from '@/app/constants';
|
||||
import { useFavoritesStore } from '@/app/stores/favorites.store';
|
||||
import { useProjectsStore } from '../projects.store';
|
||||
import { DEFAULT_PROJECT_ICON } from '../projects.constants';
|
||||
import type { Project } from '../projects.types';
|
||||
import { DATA_TABLE_DETAILS } from '@/features/core/dataTable/constants';
|
||||
import type { FavoriteResourceType } from '@/app/api/favorites';
|
||||
|
|
@ -46,7 +47,7 @@ export function useFavoriteNavItems() {
|
|||
menuItem: {
|
||||
id: f.resourceId,
|
||||
label: f.resourceName,
|
||||
icon: (project?.icon as IMenuItem['icon']) ?? ('layers' as IMenuItem['icon']),
|
||||
icon: (project?.icon as IMenuItem['icon']) ?? DEFAULT_PROJECT_ICON,
|
||||
route: { to: { name: VIEWS.PROJECTS_WORKFLOWS, params: { projectId: f.resourceId } } },
|
||||
},
|
||||
resourceId: f.resourceId,
|
||||
|
|
|
|||
|
|
@ -1 +1,5 @@
|
|||
import type { IconOrEmoji } from '@n8n/design-system/components/N8nIconPicker/types';
|
||||
|
||||
export const PROJECT_MOVE_RESOURCE_MODAL = 'projectMoveResourceModal';
|
||||
|
||||
export const DEFAULT_PROJECT_ICON: IconOrEmoji = { type: 'icon', value: 'layers' };
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useDebounceFn } from '@vueuse/core';
|
|||
import { useUsersStore } from '@/features/settings/users/users.store';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { type ResourceCounts, useProjectsStore } from '../projects.store';
|
||||
import { DEFAULT_PROJECT_ICON } from '../projects.constants';
|
||||
import type { Project, ProjectRelation, ProjectMemberData } from '../projects.types';
|
||||
import { useToast } from '@/app/composables/useToast';
|
||||
import { DEBOUNCE_TIME, getDebounceTime, VIEWS } from '@/app/constants';
|
||||
|
|
@ -84,10 +85,7 @@ const suppressNextSync = ref(false);
|
|||
|
||||
const nameInput = ref<InstanceType<typeof N8nFormInput> | null>(null);
|
||||
|
||||
const projectIcon = ref<IconOrEmoji>({
|
||||
type: 'icon',
|
||||
value: 'layers',
|
||||
});
|
||||
const projectIcon = ref<IconOrEmoji>({ ...DEFAULT_PROJECT_ICON });
|
||||
|
||||
const search = ref('');
|
||||
const membersTableState = ref<TableOptions>({
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user