diff --git a/web/app/components/apps/creators-filter.tsx b/web/app/components/apps/creators-filter.tsx index 7a268c5136..4bcff660e5 100644 --- a/web/app/components/apps/creators-filter.tsx +++ b/web/app/components/apps/creators-filter.tsx @@ -103,7 +103,7 @@ const CreatorsFilter = ({ baseChipClassName, isSelected ? 'border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs hover:bg-state-base-hover' - : 'border-transparent bg-[#f9f9f9] text-text-tertiary hover:bg-components-input-bg-hover', + : 'border-transparent bg-components-input-bg-normal text-text-tertiary hover:bg-components-input-bg-hover', )} /> )} diff --git a/web/app/components/snippets/components/__tests__/snippet-layout.spec.tsx b/web/app/components/snippets/components/__tests__/snippet-layout.spec.tsx new file mode 100644 index 0000000000..3202c3dc43 --- /dev/null +++ b/web/app/components/snippets/components/__tests__/snippet-layout.spec.tsx @@ -0,0 +1,108 @@ +import type { ReactNode } from 'react' +import type { SnippetDetail } from '@/models/snippet' +import { render, screen } from '@testing-library/react' +import SnippetLayout from '../snippet-layout' + +const mockSetAppSidebarExpand = vi.fn() +const mockUseDocumentTitle = vi.fn() + +vi.mock('@/app/components/app/store', () => ({ + useStore: (selector: (state: { setAppSidebarExpand: typeof mockSetAppSidebarExpand }) => unknown) => selector({ + setAppSidebarExpand: mockSetAppSidebarExpand, + }), +})) + +vi.mock('@/hooks/use-breakpoints', () => ({ + default: () => 'desktop', + MediaType: { + mobile: 'mobile', + desktop: 'desktop', + }, +})) + +vi.mock('@/hooks/use-document-title', () => ({ + default: (title: string) => mockUseDocumentTitle(title), +})) + +vi.mock('@/app/components/app-sidebar', () => ({ + default: ({ + renderHeader, + renderNavigation, + }: { + renderHeader?: (mode: string) => ReactNode + renderNavigation?: (mode: string) => ReactNode + }) => ( +
+ {renderHeader?.('expand')} + {renderNavigation?.('expand')} +
+ ), +})) + +vi.mock('@/app/components/app-sidebar/nav-link', () => ({ + default: ({ name, href, active }: { name: string, href: string, active: boolean }) => ( + + {name} + + ), +})) + +vi.mock('@/app/components/app-sidebar/snippet-info', () => ({ + default: ({ snippet }: { snippet: SnippetDetail }) =>
{snippet.name}
, +})) + +const createSnippet = (overrides: Partial = {}): SnippetDetail => ({ + id: 'snippet-1', + name: 'Snippet Title', + description: 'Snippet description', + author: 'tester', + updatedAt: '2026-04-15', + usage: '42', + icon: 'emoji', + iconBackground: '#ffffff', + ...overrides, +}) + +describe('SnippetLayout', () => { + beforeEach(() => { + vi.clearAllMocks() + localStorage.clear() + }) + + describe('Document title', () => { + it('should set the document title to the snippet name when snippet detail is available', () => { + render( + +
content
+
, + ) + + expect(mockUseDocumentTitle).toHaveBeenCalledWith('Snippet Title') + }) + }) + + describe('Navigation', () => { + it('should render snippet navigation links', () => { + render( + +
content
+
, + ) + + expect(screen.getByRole('link', { name: 'snippet.sectionOrchestrate' })).toHaveAttribute('href', '/snippets/snippet-1/orchestrate') + expect(screen.getByRole('link', { name: 'snippet.sectionEvaluation' })).toHaveAttribute('href', '/snippets/snippet-1/evaluation') + expect(screen.getByRole('link', { name: 'snippet.sectionEvaluation' })).toHaveAttribute('aria-current', 'page') + }) + }) +}) diff --git a/web/app/components/snippets/components/snippet-layout.tsx b/web/app/components/snippets/components/snippet-layout.tsx index 37900f3969..2d03f3a065 100644 --- a/web/app/components/snippets/components/snippet-layout.tsx +++ b/web/app/components/snippets/components/snippet-layout.tsx @@ -16,6 +16,7 @@ import NavLink from '@/app/components/app-sidebar/nav-link' import SnippetInfo from '@/app/components/app-sidebar/snippet-info' import { useStore as useAppStore } from '@/app/components/app/store' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' +import useDocumentTitle from '@/hooks/use-document-title' type SnippetLayoutProps = { children: ReactNode @@ -45,6 +46,8 @@ const SnippetLayout = ({ const isMobile = media === MediaType.mobile const setAppSidebarExpand = useAppStore(state => state.setAppSidebarExpand) + useDocumentTitle(snippet.name || t('typeLabel')) + useEffect(() => { const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand' const mode = isMobile ? 'collapse' : 'expand'