wing-ops/docs/MENU-TAB-GUIDE.md
htlee 660591446b feat(admin): 메뉴 관리 드래그앤드롭 순서 변경 + 메뉴 탭 추가 가이드 문서
- @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>
2026-02-28 02:46:16 +09:00

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)
  • TopBarenabled && hasPermission 조건으로 탭을 필터링하고 order 순 정렬
  • App.tsxrenderView가 탭 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.tsDEFAULT_MENU_CONFIG 배열에 항목을 추가합니다.

const DEFAULT_MENU_CONFIG: MenuConfigItem[] = [
  // ... 기존 10개 메뉴 ...
  { id: 'monitoring', label: '실시간 모니터링', icon: '📡', enabled: true, order: 11 },
]

VALID_MENU_IDSDEFAULT_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.sqlmenu.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: 관리자 메뉴 관리에서 활성화

코드 배포 후:

  1. 관리자 계정으로 로그인
  2. 관리자 패널(⚙️) → 메뉴 관리 탭
  3. 새 메뉴가 목록에 표시됨
  4. 활성/비활성 토글, 순서, 라벨, 아이콘을 설정
  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 .)
  • 관리자 메뉴 관리에서 새 메뉴 표시 확인