-
Notifications
You must be signed in to change notification settings - Fork 3
feat: 워크스페이스 purpose별 navigation 분기 구현 (#15) #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| // 목업 워크스페이스 데이터와 타입의 공개 API입니다. | ||
| export type { Workspace } from './model/workspace.types'; | ||
| export type { Workspace, WorkspacePurpose } from './model/workspace.types'; | ||
| export { mockWorkspace } from './model/mock-workspace'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| // Supabase 워크스페이스 데이터 연결 전 shell에서 사용하는 워크스페이스 타입입니다. | ||
| export type WorkspacePurpose = 'team-project' | 'side-project' | 'store-operation'; | ||
|
|
||
| export interface Workspace { | ||
| id: string; | ||
| name: string; | ||
| purpose: 'store-operation' | 'team-project' | 'side-project'; | ||
| purpose: WorkspacePurpose; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| // 워크스페이스 목적에 맞는 shell navigation 항목을 반환합니다. | ||
| import type { WorkspacePurpose } from '@/entities/workspace'; | ||
| import { workspaceNavigationByPurpose } from '@/widgets/workspace-shell/model/workspace-navigation'; | ||
|
|
||
| export function getWorkspaceNavigation(purpose: WorkspacePurpose) { | ||
| return workspaceNavigationByPurpose[purpose]; | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 워크스페이스 목적별 사이드바 메뉴 항목을 정의합니다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { WorkspacePurpose } from '@/entities/workspace'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Bell, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Calendar, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -7,6 +8,9 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LayoutDashboard, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MessageSquare, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Settings, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Rocket, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| FileText, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BarChart3, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type LucideIcon, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from 'lucide-react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -27,26 +31,32 @@ export const storeOperationNavigationItems: WorkspaceNavigationItem[] = [ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: 사이드 프로젝트 도메인을 만들 때 아래 메뉴를 별도 purpose 전용 사이드바로 연결합니다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // export const sideProjectNavigationItems: WorkspaceNavigationItem[] = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '대시보드', href: 'dashboard', icon: LayoutDashboard }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '스프린트 보드', href: 'sprint-board', icon: Rocket }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '캘린더', href: 'calendar', icon: Calendar }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '회의록', href: 'meeting-notes', icon: FileText }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '자료실', href: 'files', icon: FileBox }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '채팅', href: 'chat', icon: MessageSquare }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '진행률 차트', href: 'progress-chart', icon: BarChart3 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '설정', href: 'settings', icon: Settings }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const sideProjectNavigationItems: WorkspaceNavigationItem[] = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '대시보드', href: 'dashboard', icon: LayoutDashboard }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '스프린트 보드', href: 'sprint-board', icon: Rocket }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '캘린더', href: 'calendar', icon: Calendar }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '회의록', href: 'meeting-notes', icon: FileText }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '자료실', href: 'files', icon: FileBox }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '채팅', href: 'chat', icon: MessageSquare }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '진행률 차트', href: 'progress-chart', icon: BarChart3 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '설정', href: 'settings', icon: Settings }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: 팀 프로젝트 도메인을 만들 때 아래 메뉴를 별도 purpose 전용 사이드바로 연결합니다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // export const sideProjectNavigationItems: WorkspaceNavigationItem[] = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '대시보드', href: 'dashboard', icon: LayoutDashboard }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '프로젝트 관리', href: 'sprint-board', icon: Rocket }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '캘린더', href: 'calendar', icon: Calendar }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '공지', href: 'notices', icon: Bell }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '회의록', href: 'meeting-notes', icon: FileText }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '자료실', href: 'files', icon: FileBox }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '채팅', href: 'chat', icon: MessageSquare }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '진행률 차트', href: 'progress-chart', icon: BarChart3 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // { label: '설정', href: 'settings', icon: Settings }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const teamProjectNavigationItems: WorkspaceNavigationItem[] = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '대시보드', href: 'dashboard', icon: LayoutDashboard }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '프로젝트 관리', href: 'sprint-board', icon: Rocket }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '캘린더', href: 'calendar', icon: Calendar }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '공지', href: 'notices', icon: Bell }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '회의록', href: 'meeting-notes', icon: FileText }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '자료실', href: 'files', icon: FileBox }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '채팅', href: 'chat', icon: MessageSquare }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '진행률 차트', href: 'progress-chart', icon: BarChart3 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { label: '설정', href: 'settings', icon: Settings }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
45
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win TODO 주석이 이미 구현된 내용과 모순됩니다.
📝 제안-// TODO: 팀 프로젝트 도메인을 만들 때 아래 메뉴를 별도 purpose 전용 사이드바로 연결합니다.
+// team-project purpose 전용 navigation. 세부 페이지(예: 프로젝트 관리) 도메인이 추가되면 href/아이콘을 갱신하세요.
export const teamProjectNavigationItems: WorkspaceNavigationItem[] = [📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const workspaceNavigationByPurpose = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'store-operation': storeOperationNavigationItems, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'team-project': teamProjectNavigationItems, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'side-project': sideProjectNavigationItems, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } satisfies Record<WorkspacePurpose, WorkspaceNavigationItem[]>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+58
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial navigation 설정 위치는 현재로선 적절해 보입니다.
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,8 @@ | |
| import { useState } from 'react'; | ||
| import { WorkspaceHeader } from './WorkspaceHeader'; | ||
| import { WorkspaceSidebar } from './WorkspaceSidebar'; | ||
| import { mockWorkspace } from '@/entities/workspace'; | ||
| import { getWorkspaceNavigation } from '@/widgets/workspace-shell/lib/get-workspace-navigation'; | ||
|
|
||
| interface WorkspaceShellProps { | ||
| workspaceId: string; | ||
|
|
@@ -12,17 +14,21 @@ interface WorkspaceShellProps { | |
|
|
||
| export function WorkspaceShell({ workspaceId, children }: WorkspaceShellProps) { | ||
| const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false); | ||
| const workspace = mockWorkspace; // 나중에는 workspaceId로 Supabase 조회 | ||
| const navigationItems = getWorkspaceNavigation(workspace.purpose); | ||
|
Comment on lines
+17
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win 향후 Supabase 교체를 대비해 workspace 조회를 함수로 캡슐화하는 것을 고려하세요. 현재 ♻️ 제안- const workspace = mockWorkspace; // 나중에는 workspaceId로 Supabase 조회
+ const workspace = getWorkspace(workspaceId); // 현재는 mock, 추후 Supabase 조회로 교체// 예: src/entities/workspace/model/get-workspace.ts
export function getWorkspace(workspaceId: string): Workspace {
// TODO: Supabase 조회로 교체
return mockWorkspace;
}🤖 Prompt for AI Agents |
||
|
|
||
| return ( | ||
| <div className="flex h-screen overflow-hidden bg-[#f7f8fc]"> | ||
| <WorkspaceSidebar | ||
| workspace={workspace} | ||
| workspaceId={workspaceId} | ||
| isCollapsed={isSidebarCollapsed} | ||
| navigationItems={navigationItems} | ||
| onToggleCollapsed={() => setIsSidebarCollapsed((current) => !current)} | ||
| /> | ||
|
|
||
| <div className="flex h-screen min-w-0 flex-1 flex-col"> | ||
| <WorkspaceHeader /> | ||
| <WorkspaceHeader navigationItems={navigationItems} /> | ||
| <main className="min-h-0 flex-1 overflow-y-auto px-8 py-8">{children}</main> | ||
| </div> | ||
| </div> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
sideProjectNavigationItems와teamProjectNavigationItems의 항목 중복.두 배열은 대시보드/캘린더/회의록/자료실/채팅/진행률 차트/설정 7개 항목이 동일하고, 스프린트보드↔프로젝트관리 라벨 및 공지 유무만 다릅니다. 공통 항목을 추출하면 향후 두 배열이 따로 갱신되며 어긋나는 것을 방지할 수 있습니다.
♻️ 공통 항목 추출 예시
📝 Committable suggestion
🤖 Prompt for AI Agents