Files
sam-react-prod/src/components/hr/DepartmentManagement/DepartmentTreeItem.tsx
유병철 8f9507a665 feat: 다중 도메인 UI 개선 및 컴포넌트 리팩토링
- 게시판, HR, 설정, 차량관리, 건설, 견적 등 전반적 UI 개선
- FormField, TabChip, Select 등 공통 컴포넌트 개선
- 가격배분 edit 페이지 제거 및 상세 페이지 통합
- 체크리스트, 근태, 급여, 권한 관리 등 폼 개선

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 22:30:06 +09:00

120 lines
3.5 KiB
TypeScript

'use client';
import { memo } from 'react';
import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@/components/ui/button';
import { ChevronRight, ChevronDown, Plus, SquarePen, Trash2 } from 'lucide-react';
import type { DepartmentTreeItemProps } from './types';
/**
* 트리 행 (재귀 렌더링)
* - 무제한 깊이 지원
* - depth에 따른 동적 들여쓰기
*/
export const DepartmentTreeItem = memo(function DepartmentTreeItem({
department,
depth,
expandedIds,
selectedIds,
onToggleExpand,
onToggleSelect,
onAdd,
onEdit,
onDelete
}: DepartmentTreeItemProps) {
const hasChildren = department.children && department.children.length > 0;
const isExpanded = expandedIds.has(department.id);
const isSelected = selectedIds.has(department.id);
// 들여쓰기 계산 (depth * 24px)
const paddingLeft = depth * 24;
return (
<>
{/* 현재 행 */}
<div
className="group px-4 py-3 hover:bg-muted/50 transition-colors"
style={{ paddingLeft: `${paddingLeft + 16}px` }}
>
<div className="flex items-center gap-2">
{/* 펼침/접힘 버튼 */}
<Button
variant="ghost"
size="sm"
className={`h-6 w-6 p-0 shrink-0 ${!hasChildren ? 'invisible' : ''}`}
onClick={() => onToggleExpand(department.id)}
>
{isExpanded ? (
<ChevronDown className="h-4 w-4" />
) : (
<ChevronRight className="h-4 w-4" />
)}
</Button>
{/* 체크박스 */}
<Checkbox
checked={isSelected}
onCheckedChange={() => onToggleSelect(department.id)}
aria-label={`${department.name} 선택`}
className="shrink-0"
/>
{/* 부서명 */}
<span className="break-words">{department.name}</span>
</div>
{/* 작업 버튼 (선택 시 부서명 아래에 표시, 데스크톱: 호버 시에도 표시) */}
{isSelected && (
<div className="flex items-center gap-1 mt-2 ml-10">
<Button
variant="ghost"
size="sm"
className="h-7 w-7 p-0"
onClick={() => onAdd(department.id)}
title="하위 부서 추가"
>
<Plus className="h-4 w-4" />
</Button>
<Button
size="icon"
className="h-7 w-7"
onClick={() => onEdit(department)}
title="수정"
>
<SquarePen className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
className="h-7 w-7 p-0 text-destructive hover:text-destructive"
onClick={() => onDelete(department)}
title="삭제"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
)}
</div>
{/* 하위 부서 (재귀) */}
{hasChildren && isExpanded && (
<>
{department.children!.map(child => (
<DepartmentTreeItem
key={child.id}
department={child}
depth={depth + 1}
expandedIds={expandedIds}
selectedIds={selectedIds}
onToggleExpand={onToggleExpand}
onToggleSelect={onToggleSelect}
onAdd={onAdd}
onEdit={onEdit}
onDelete={onDelete}
/>
))}
</>
)}
</>
);
});