- @dnd-kit/core, @dnd-kit/sortable로 드래그앤드롭 순서 변경 지원 - SortableMenuItem 컴포넌트 분리, 드래그 핸들(grip) + DragOverlay 프리뷰 - 기존 UP/DOWN 버튼 유지 (드래그와 병행 사용) - docs/MENU-TAB-GUIDE.md: 새 메뉴 탭 추가 시 수정 파일 및 절차 가이드 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.0 KiB
6.0 KiB
WING 메뉴 탭 추가 가이드
새로운 메뉴 탭을 추가할 때 필요한 절차를 설명합니다.
메뉴 시스템 구조
DB: AUTH_SETTING (menu.config JSON)
↕ GET/PUT /api/menus
Backend: settingsService.ts (DEFAULT_MENU_CONFIG, VALID_MENU_IDS)
↕ API
Frontend: menuStore.ts → TopBar.tsx (탭 렌더링)
→ App.tsx (renderView 라우팅)
- DB가 메뉴 정의의 단일 소스 (id, label, icon, enabled, order)
- TopBar는
enabled && hasPermission조건으로 탭을 필터링하고order순 정렬 - App.tsx의
renderView가 탭 ID에 따라 뷰 컴포넌트를 매핑 - admin 탭은 메뉴 관리 대상에서 제외 (TopBar에서 별도 아이콘 버튼으로 접근)
수정 파일 요약
| 순서 | 파일 | 작업 | 필수 |
|---|---|---|---|
| 1 | frontend/src/components/views/XxxView.tsx |
뷰 컴포넌트 생성 | O |
| 2 | frontend/src/App.tsx |
MainTab 타입 + import + renderView | O |
| 3 | backend/src/settings/settingsService.ts |
DEFAULT_MENU_CONFIG에 항목 추가 | O |
| 4 | database/auth_init.sql |
menu.config 초기 JSON에 추가 | O |
| 5 | 관리자 UI | 메뉴 관리에서 활성화 | O |
Step 1: 뷰 컴포넌트 생성
frontend/src/components/views/ 에 새 뷰 컴포넌트를 생성합니다.
// frontend/src/components/views/MonitoringView.tsx
export function MonitoringView() {
return (
<div className="flex flex-1 overflow-hidden bg-bg-0">
<div className="flex-1 flex flex-col overflow-hidden p-6">
<h1 className="text-lg font-bold text-text-1 font-korean">실시간 모니터링</h1>
{/* 뷰 콘텐츠 */}
</div>
</div>
)
}
기존 뷰 컴포넌트(OilSpillView, WeatherView 등)의 레이아웃 패턴을 참고하세요.
Step 2: App.tsx 탭 등록
3가지를 수정합니다.
2-1. MainTab 타입에 ID 추가
// frontend/src/App.tsx (line 20)
// Before
export type MainTab = 'prediction' | 'hns' | ... | 'admin'
// After
export type MainTab = 'prediction' | 'hns' | ... | 'monitoring' | 'admin'
2-2. 뷰 컴포넌트 import
import { MonitoringView } from './components/views/MonitoringView'
2-3. renderView switch에 case 추가
const renderView = () => {
switch (activeMainTab) {
// ... 기존 case들 ...
case 'monitoring':
return <MonitoringView />
// ...
}
}
Step 3: 백엔드 메뉴 설정 등록
backend/src/settings/settingsService.ts의 DEFAULT_MENU_CONFIG 배열에 항목을 추가합니다.
const DEFAULT_MENU_CONFIG: MenuConfigItem[] = [
// ... 기존 10개 메뉴 ...
{ id: 'monitoring', label: '실시간 모니터링', icon: '📡', enabled: true, order: 11 },
]
VALID_MENU_IDS는 DEFAULT_MENU_CONFIG에서 자동 파생되므로 별도 수정 불필요합니다.
const VALID_MENU_IDS = DEFAULT_MENU_CONFIG.map(m => m.id) // 자동 포함됨
주의:
updateMenuConfig()은VALID_MENU_IDS.length개수 전체가 포함되어야 저장을 허용합니다. 기존 운영 DB에 새 메뉴가 없는 상태에서도getMenuConfig()의 fallback이 DEFAULT_MENU_CONFIG을 반환하므로 정상 동작합니다.
Step 4: DB 초기 데이터 업데이트
database/auth_init.sql의 menu.config 초기 JSON에 새 항목을 추가합니다.
INSERT INTO AUTH_SETTING (SETTING_KEY, SETTING_VAL, SETTING_DC, MDFCN_DTM) VALUES
('menu.config', '[
{"id":"prediction","label":"유출유 확산예측","icon":"🛢️","enabled":true,"order":1},
...기존 메뉴들...
{"id":"monitoring","label":"실시간 모니터링","icon":"📡","enabled":true,"order":11}
]', '메뉴 구성 설정', NOW())
ON CONFLICT (SETTING_KEY) DO NOTHING;
참고: 이 SQL은 신규 설치 시에만 적용됩니다. 기존 운영 DB는 관리자 UI에서 메뉴를 관리합니다.
Step 5: 관리자 메뉴 관리에서 활성화
코드 배포 후:
- 관리자 계정으로 로그인
- 관리자 패널(⚙️) → 메뉴 관리 탭
- 새 메뉴가 목록에 표시됨
- 활성/비활성 토글, 순서, 라벨, 아이콘을 설정
- "변경사항 저장" 클릭
기존 DB에 새 메뉴 ID가 없으면
getMenuConfig()가 DEFAULT_MENU_CONFIG fallback을 사용하여 새 메뉴가 자동으로 목록에 나타납니다.
실전 예시: "모니터링" 탭 추가
1. 뷰 컴포넌트 생성
# frontend/src/components/views/MonitoringView.tsx 파일 생성
2. App.tsx 수정 (3곳)
+ import { MonitoringView } from './components/views/MonitoringView'
- export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'admin'
+ export type MainTab = 'prediction' | 'hns' | 'rescue' | 'reports' | 'aerial' | 'assets' | 'scat' | 'incidents' | 'board' | 'weather' | 'monitoring' | 'admin'
const renderView = () => {
switch (activeMainTab) {
// ...
+ case 'monitoring':
+ return <MonitoringView />
case 'admin':
return <AdminView />
}
}
3. settingsService.ts 수정
const DEFAULT_MENU_CONFIG: MenuConfigItem[] = [
// ... 기존 메뉴들 ...
{ id: 'incidents', label: '통합조회', icon: '🔍', enabled: true, order: 10 },
+ { id: 'monitoring', label: '실시간 모니터링', icon: '📡', enabled: true, order: 11 },
]
4. auth_init.sql 수정
menu.config JSON에 새 항목 추가 (신규 설치용)
5. 배포 후 관리자 UI에서 활성화
체크리스트
- 뷰 컴포넌트 생성 (
frontend/src/components/views/) MainTab타입 업데이트 (App.tsx)- import 및 renderView switch case 추가 (
App.tsx) DEFAULT_MENU_CONFIG에 추가 (settingsService.ts)menu.config초기 JSON 업데이트 (auth_init.sql)- TypeScript 컴파일 통과 (
cd frontend && npx tsc --noEmit) - ESLint 통과 (
cd frontend && npx eslint .) - 관리자 메뉴 관리에서 새 메뉴 표시 확인