Files
sam-docs/frontend/v1/org-chart-fe-guide.md
김보곤 85bc6e2f08 docs: [org-chart] 조직도 서비스 이관 기획서 및 React FE 가이드
- 이관 계획서 (API 완료, React 문서 제공)
- React FE 구현 가이드 (API 스펙, UI 설계, 드래그앤드롭)
- INDEX.md 업데이트
2026-03-22 17:22:14 +09:00

8.5 KiB

조직도 React 프론트엔드 구현 가이드

작성일: 2026-03-22 상태: API 완료, FE 구현 대기 대상: React (Next.js) 프론트엔드 개발자 페이지 URL: /hr/org-chart


1. 개요

MNG의 조직도 관리 기능을 React로 재구현한다. API는 이미 구현 완료(/v1/org-chart). 드래그 앤 드롭으로 직원 배치, 부서 순서/계층 변경, 부서 숨기기 기능을 제공한다.


2. API 엔드포인트

Method Path 설명
GET /v1/org-chart 조직도 전체 (트리+직원+통계)
GET /v1/org-chart/stats 통계 (전체/배치/미배치)
GET /v1/org-chart/unassigned?q= 미배치 직원 검색
POST /v1/org-chart/assign 직원 → 부서 배치
POST /v1/org-chart/unassign 직원 미배치 처리
PUT /v1/org-chart/reorder-employees 직원 일괄 이동
PUT /v1/org-chart/reorder-departments 부서 순서/계층 변경
PATCH /v1/org-chart/departments/{id}/toggle-hide 부서 숨기기 토글

Swagger UI: /api-docs → "OrgChart" 태그 참조


3. 응답 구조

3.1 GET /v1/org-chart

{
  "success": true,
  "data": {
    "company": {
      "name": "주일산업",
      "ceo_name": "홍길동"
    },
    "departments": [
      {
        "id": 1,
        "name": "경영지원팀",
        "code": "MGT",
        "parent_id": null,
        "sort_order": 1,
        "is_active": true,
        "orgchart_hidden": false,
        "children": [],
        "employees": [
          {
            "id": 5,
            "user_id": 3,
            "department_id": 1,
            "display_name": "김과장",
            "position_label": "과장"
          }
        ]
      }
    ],
    "hidden_departments": [
      { "id": 5, "name": "해외사업팀", "code": "OVS" }
    ],
    "unassigned": [
      { "id": 12, "user_id": 8, "display_name": "이사원", "position_label": "사원" }
    ],
    "stats": {
      "total": 50,
      "assigned": 42,
      "unassigned": 8
    }
  }
}

3.2 요청 바디 예시

POST /v1/org-chart/assign:

{ "employee_id": 5, "department_id": 3 }

PUT /v1/org-chart/reorder-employees:

{
  "moves": [
    { "employee_id": 5, "department_id": 3 },
    { "employee_id": 6, "department_id": null }
  ]
}

PUT /v1/org-chart/reorder-departments:

{
  "orders": [
    { "id": 1, "parent_id": null, "sort_order": 0 },
    { "id": 2, "parent_id": 1, "sort_order": 1 }
  ]
}

PATCH /v1/org-chart/departments/{id}/toggle-hide:

{ "hidden": true }

4. 컴포넌트 구조 (제안)

src/
├── app/[locale]/(protected)/hr/
│   └── org-chart/
│       └── page.tsx                    ← 페이지 진입점
├── components/hr/org-chart/
│   ├── index.tsx                       ← 메인 컨테이너
│   ├── OrgChartTree.tsx                ← 부서 트리 렌더링
│   ├── DepartmentNode.tsx              ← 부서 카드 (접기/펼치기, 숨기기)
│   ├── EmployeeCard.tsx                ← 직원 카드 (드래그 가능)
│   ├── UnassignedPanel.tsx             ← 미배치 직원 패널 (검색 포함)
│   ├── HiddenDepartmentsPanel.tsx      ← 숨겨진 부서 복원 패널
│   ├── OrgChartStats.tsx               ← 상단 통계 표시
│   ├── CompanyHeader.tsx               ← 회사명 + CEO 표시
│   ├── actions.ts                      ← Server Actions
│   └── types.ts                        ← TypeScript 타입 정의

5. UI 구성 (MNG 참조)

MNG 조직도 UI: mng/resources/views/rd/org-chart.blade.php

5.1 화면 레이아웃

┌───────────────────────────────────────────────────────┐
│  조직도 관리          전체 50명 | 배치 42명 | 미배치 8명  │  ← 헤더 + 통계
├───────────────────────────────────────────────────────┤
│ ┌─미배치 직원──────┐  ┌─조직도 트리───────────────────┐ │
│ │ 🔍 검색          │  │ ┌──────────────────────────┐ │ │
│ │                  │  │ │ 회사명                    │ │ │
│ │ ▪ 이사원 (사원)  │  │ │ CEO: 홍길동               │ │ │
│ │ ▪ 박대리 (대리)  │  │ └──────────────────────────┘ │ │
│ │                  │  │                              │ │
│ │  (드래그 가능)   │  │ ┌─경영지원팀 (MGT)──────────┐ │ │
│ │                  │  │ │ 김과장 (과장) [미배치 ✕]   │ │ │
│ │                  │  │ │ 최대리 (대리) [미배치 ✕]   │ │ │
│ │                  │  │ └──────────────────────────┘ │ │
│ │                  │  │ ┌─생산팀 (PRD)───────────────┐ │ │
│ │                  │  │ │ ...                        │ │ │
│ │                  │  │ └────────────────────────────┘ │ │
│ └──────────────────┘  └──────────────────────────────┘ │
│ ┌─숨겨진 부서──────────────────────────────────────────┐ │
│ │ 해외사업팀 [복원]  영업3팀 [복원]                     │ │
│ └──────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘

5.2 인터랙션

동작 효과 API 호출
미배치 직원 → 부서 드래그 직원 배치 POST /assign 또는 PUT /reorder-employees
부서 내 직원 → 미배치 패널 드래그 직원 미배치 POST /unassign
부서 카드 드래그 (순서 변경) 부서 순서/계층 변경 PUT /reorder-departments
부서 카드 더블클릭 → "숨기기" 조직도에서 숨김 PATCH /departments/{id}/toggle-hide
숨겨진 부서 "복원" 클릭 조직도에 다시 표시 PATCH /departments/{id}/toggle-hide

6. 드래그 앤 드롭 구현

6.1 라이브러리 권장

  • @dnd-kit: React 전용, 접근성 지원, 트리 구조 지원
  • 대안: react-beautiful-dnd (유지보수 중단), react-dnd

6.2 핵심 구현 포인트

  1. 직원 드래그: 미배치 패널 ↔ 부서 카드 간 이동
  2. 부서 드래그: 부서 카드 간 순서/계층 변경 (parent_id + sort_order)
  3. 순환 참조 방지: 부서를 자기 자손에 드롭하면 무시 (API에서도 검증하지만 UI에서도 방지)
  4. Optimistic Update: 드래그 완료 시 로컬 상태 즉시 업데이트 → API 호출 → 실패 시 롤백

6.3 상태 관리

초기 로딩: GET /v1/org-chart → 로컬 상태 세팅
  ├── departments (트리 구조)
  ├── unassigned (미배치 직원 배열)
  ├── hiddenDepartments (숨겨진 부서 배열)
  ├── stats (통계)
  └── company (회사 정보)

변경 시: API 호출 → 성공 시 로컬 상태 업데이트

7. MNG 참고 파일

파일 설명
mng/app/Http/Controllers/RdController.php (L38-208) 조직도 컨트롤러 로직
mng/resources/views/rd/org-chart.blade.php 조직도 UI (Alpine.js + SortableJS)
mng/app/Models/Tenants/Department.php Department 모델 (options cast)

관련 문서

문서 경로
이관 계획서 dev/dev_plans/org-chart-service-migration-plan.md
조직도 시스템 (MNG) projects/org-chart/README.md
React 아키텍처 frontend/v1/01-architecture.md
API 패턴 frontend/v1/02-api-pattern.md
인증 흐름 frontend/v1/07-auth-flow.md

최종 업데이트: 2026-03-22