From 40073dacb2a3627ca2651cbbe7112c075bc0f605 Mon Sep 17 00:00:00 2001 From: mini Date: Wed, 12 Aug 2026 10:10:44 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=82=AC=EC=9D=B4=EB=93=9C=EB=B0=94?= =?UTF-8?q?=EC=97=90=20'=EA=B7=BC=EB=A1=9C=EC=9E=90'=20=EB=A9=94=EB=89=B4?= =?UTF-8?q?=20=EB=B3=B5=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전체 근로자 목록(/workers)으로 갈 방법이 사실상 없었다 — WorkListPage의 /workers 링크는 근로자가 0명일 때만 뜨는 EmptyState라 실사용에서는 절대 안 보임. 이미 있던 workers.svg 아이콘을 재사용해서 사이드바에 '근로자' 메뉴를 복원. closes #325 --- src/components/layout/AppLayout.test.tsx | 24 +++++++++++++++++------- src/components/layout/navItems.ts | 4 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/components/layout/AppLayout.test.tsx b/src/components/layout/AppLayout.test.tsx index 7c48095..18087eb 100644 --- a/src/components/layout/AppLayout.test.tsx +++ b/src/components/layout/AppLayout.test.tsx @@ -71,7 +71,9 @@ beforeEach(() => { vi.fn((input: RequestInfo | URL) => { const url = requestUrl(input) return Promise.resolve( - jsonResponse(url.includes('/notifications') ? EMPTY_NOTIFICATION_RESPONSE : EMPTY_TODAY_RESPONSE), + jsonResponse( + url.includes('/notifications') ? EMPTY_NOTIFICATION_RESPONSE : EMPTY_TODAY_RESPONSE, + ), ) }), ) @@ -82,7 +84,7 @@ afterEach(() => { }) describe('AppLayout', () => { - it('renders the current global navigation without a workers tab', () => { + it('renders the current global navigation including the workers tab', () => { localStorage.setItem('fowoco.onboarding.completed', 'true') renderLayout() @@ -90,7 +92,7 @@ describe('AppLayout', () => { for (const item of NAV_ITEMS) { expect(screen.getByRole('link', { name: item.label })).toBeInTheDocument() } - expect(screen.queryByRole('link', { name: '근로자' })).not.toBeInTheDocument() + expect(screen.getByRole('link', { name: '근로자' })).toHaveAttribute('href', '/workers') }) it('shows server-backed work shortcut counts and routes them to focused inbox views', async () => { @@ -169,7 +171,9 @@ describe('AppLayout', () => { it('shows the onboarding tour automatically on first visit', () => { renderLayout() - expect(screen.getByRole('dialog', { name: 'FOWOCO에 오신 것을 환영합니다' })).toBeInTheDocument() + expect( + screen.getByRole('dialog', { name: 'FOWOCO에 오신 것을 환영합니다' }), + ).toBeInTheDocument() }) it('does not show the onboarding tour again once completed', () => { @@ -184,10 +188,14 @@ describe('AppLayout', () => { renderLayout() await user.click(screen.getByRole('button', { name: '다음' })) - expect(screen.getByRole('dialog', { name: 'Today·업무함에서 우선순위를 확인하세요' })).toBeInTheDocument() + expect( + screen.getByRole('dialog', { name: 'Today·업무함에서 우선순위를 확인하세요' }), + ).toBeInTheDocument() await user.click(screen.getByRole('button', { name: '다음' })) - expect(screen.getByRole('dialog', { name: '무엇이든 요청하면 Agent가 초안을 준비합니다' })).toBeInTheDocument() + expect( + screen.getByRole('dialog', { name: '무엇이든 요청하면 Agent가 초안을 준비합니다' }), + ).toBeInTheDocument() await user.click(screen.getByRole('button', { name: '시작하기' })) @@ -215,6 +223,8 @@ describe('AppLayout', () => { await user.click(screen.getByRole('button', { name: '시작 가이드 다시 보기 →' })) expect(screen.queryByRole('dialog', { name: '도움말' })).not.toBeInTheDocument() - expect(screen.getByRole('dialog', { name: 'FOWOCO에 오신 것을 환영합니다' })).toBeInTheDocument() + expect( + screen.getByRole('dialog', { name: 'FOWOCO에 오신 것을 환영합니다' }), + ).toBeInTheDocument() }) }) diff --git a/src/components/layout/navItems.ts b/src/components/layout/navItems.ts index c1ffba4..6c1defa 100644 --- a/src/components/layout/navItems.ts +++ b/src/components/layout/navItems.ts @@ -3,6 +3,7 @@ import documentsIcon from './nav-icons/documents.svg' import settingsIcon from './nav-icons/settings.svg' import todayIcon from './nav-icons/today.svg' import workIcon from './nav-icons/work.svg' +import workersIcon from './nav-icons/workers.svg' export interface NavItem { label: string @@ -10,12 +11,11 @@ export interface NavItem { iconSrc: string } -// 공용 사이드바에는 주요 운영 진입점만 노출한다. 근로자 기능은 업무·문서 흐름에서 -// 컨텍스트로 진입하므로 전역 탭에서는 제외하고, 딥링크와 관련 라우트는 유지한다. // SettingsPage는 제거되어 "설정" 메뉴는 내 프로필 페이지로 연결된다. export const NAV_ITEMS: NavItem[] = [ { label: 'Today', to: '/dashboard', iconSrc: todayIcon }, { label: '업무함', to: '/tasks', iconSrc: workIcon }, + { label: '근로자', to: '/workers', iconSrc: workersIcon }, { label: '문서함', to: '/documents', iconSrc: documentsIcon }, { label: 'Agent 기록', to: '/agent', iconSrc: agentIcon }, { label: '설정', to: '/profile', iconSrc: settingsIcon },