"use client"; import React, { useEffect, useState } from "react"; import { ResizableDialog, ResizableDialogContent, ResizableDialogHeader, DialogDescription } from "@/components/ui/resizable-dialog"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/components/ui/table"; import { Checkbox } from "@/components/ui/checkbox"; import { Loader2, AlertCircle, ArrowRight } from "lucide-react"; import { getStepDataList, moveDataToNextStep } from "@/lib/api/flow"; import { toast } from "sonner"; interface FlowDataListModalProps { open: boolean; onOpenChange: (open: boolean) => void; flowId: number; stepId: number; stepName: string; allowDataMove?: boolean; onDataMoved?: () => void; // 데이터 이동 후 리프레시 } export function FlowDataListModal({ open, onOpenChange, flowId, stepId, stepName, allowDataMove = false, onDataMoved, }: FlowDataListModalProps) { const [data, setData] = useState([]); const [columns, setColumns] = useState([]); const [selectedRows, setSelectedRows] = useState>(new Set()); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [movingData, setMovingData] = useState(false); // 데이터 조회 useEffect(() => { if (!open) return; const loadData = async () => { try { setLoading(true); setError(null); setSelectedRows(new Set()); const response = await getStepDataList(flowId, stepId, 1, 100); if (!response.success) { throw new Error(response.message || "데이터를 불러올 수 없습니다"); } const rows = response.data?.records || []; setData(rows); // 컬럼 추출 (첫 번째 행에서) if (rows.length > 0) { setColumns(Object.keys(rows[0])); } else { setColumns([]); } } catch (err: any) { console.error("Failed to load flow data:", err); setError(err.message || "데이터를 불러오는데 실패했습니다"); } finally { setLoading(false); } }; loadData(); }, [open, flowId, stepId]); // 전체 선택/해제 const toggleAllSelection = () => { if (selectedRows.size === data.length) { setSelectedRows(new Set()); } else { setSelectedRows(new Set(data.map((_, index) => index))); } }; // 개별 행 선택/해제 const toggleRowSelection = (index: number) => { const newSelected = new Set(selectedRows); if (newSelected.has(index)) { newSelected.delete(index); } else { newSelected.add(index); } setSelectedRows(newSelected); }; // 선택된 데이터 이동 const handleMoveData = async () => { if (selectedRows.size === 0) { toast.error("이동할 데이터를 선택해주세요"); return; } try { setMovingData(true); // 선택된 행의 ID 추출 (가정: 각 행에 'id' 필드가 있음) const selectedDataIds = Array.from(selectedRows).map((index) => data[index].id); // 데이터 이동 API 호출 for (const dataId of selectedDataIds) { const response = await moveDataToNextStep(flowId, stepId, dataId); if (!response.success) { throw new Error(`데이터 이동 실패: ${response.message}`); } } toast.success(`${selectedRows.size}건의 데이터를 다음 단계로 이동했습니다`); // 모달 닫고 리프레시 onOpenChange(false); onDataMoved?.(); } catch (err: any) { console.error("Failed to move data:", err); toast.error(err.message || "데이터 이동에 실패했습니다"); } finally { setMovingData(false); } }; return ( {stepName} {data.length}건 이 단계에 해당하는 데이터 목록입니다
{loading ? (
데이터 로딩 중...
) : error ? (
{error}
) : data.length === 0 ? (
데이터가 없습니다
) : (
{allowDataMove && ( 0} onCheckedChange={toggleAllSelection} /> )} {columns.map((col) => ( {col} ))} {data.map((row, index) => ( {allowDataMove && ( toggleRowSelection(index)} /> )} {columns.map((col) => ( {row[col] !== null && row[col] !== undefined ? String(row[col]) : "-"} ))} ))}
)}
{allowDataMove && data.length > 0 && ( )}
); }