"use client"; import { useEffect, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { CodeSelect } from "@/entities/code/ui/code-select"; import { verificationTargetManagementApi } from "@/entities/statistics/api/verification-target-management-service"; import type { NumericColumnDto, VerificationTargetManagementResponse, } from "@/entities/statistics/model/verification-target-management-interface"; import { type VerificationTargetManagementFormData, verificationTargetManagementSchema, } from "@/entities/statistics/model/verification-target-management-schema"; import { Button, Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@common/components"; import type { TabValue } from "./VerificationArticleManagement"; interface VerificationTargetDialogProps { tabValue: TabValue; open: boolean; onOpenChange: (open: boolean) => void; data: VerificationTargetManagementResponse | null; onSave: (data: VerificationTargetManagementResponse) => void; onDelete: (vrfcTrgtSn: number) => void; } export function VerificationTargetDialog({ tabValue, open, onOpenChange, data, onSave, onDelete, }: VerificationTargetDialogProps) { const { control, handleSubmit, reset, watch, getValues, setValue } = useForm({ resolver: zodResolver(verificationTargetManagementSchema), defaultValues: data || { vrfcMthdCd: tabValue, statsCd: "", vrfcTrgtNm: "", schmNm: "", tblNm: "", colNm: "", pkColNm: "", useYn: "Y", }, }); const watchStatsCd = watch("statsCd"); const [isColumnDialogOpen, setIsColumnDialogOpen] = useState(false); const [numericColumns, setNumericColumns] = useState( [], ); useEffect(() => { if (open) { reset( data || { vrfcMthdCd: tabValue, statsCd: "", vrfcTrgtNm: "", schmNm: "", tblNm: "", colNm: "", pkColNm: "", useYn: "Y", }, ); } else { setNumericColumns([]); } }, [data, open, reset, tabValue]); function onSubmit(formData: VerificationTargetManagementFormData) { onSave({ ...(data || {}), ...formData, } as VerificationTargetManagementResponse); } function handleDelete() { if (data?.vrfcTrgtSn) { onDelete(data.vrfcTrgtSn); } } async function handleSearchTableMetadata(e?: React.MouseEvent) { e?.preventDefault(); const statsCd = getValues("statsCd"); if (!statsCd) { alert("통계항목을 선택해주세요."); return; } try { const metadata = await verificationTargetManagementApi.getTableInfo(statsCd); setValue("schmNm", metadata.schmNm, { shouldValidate: true }); setValue("tblNm", metadata.tblNm, { shouldValidate: true }); if (metadata.pkColumns && metadata.pkColumns.length > 0) { setValue("pkColNm", metadata.pkColumns.join(", "), { shouldValidate: true, }); } setNumericColumns(metadata.numericColumns || []); setIsColumnDialogOpen(true); } catch (error) { alert("테이블 정보를 조회하는 중 오류가 발생했습니다."); console.error(error); } } function handleOpenColumnDialog(e?: React.MouseEvent) { e?.preventDefault(); if (numericColumns.length === 0) { handleSearchTableMetadata(); } else { setIsColumnDialogOpen(true); } } function handleSelectColumn(colNm: string) { setValue("colNm", colNm, { shouldValidate: true }); setIsColumnDialogOpen(false); } return ( <> {data ? "검증 항목 상세" : "검증 항목 등록"}
통계항목
( )} />
검증명 ( )} />
스키마명 (
)} />
테이블명 (
)} />
컬럼명
( )} />
PK 키 (
)} />
{tabValue !== "IMR" && ( 중요도 계수(μ) (
field.onChange( e.target .value ? Number( e .target .value, ) : null, ) } placeholder="(0 ~ 1, 0.1 단위)" />
)} />
백분위수 기준값(pct) (
field.onChange( e.target .value ? Number( e .target .value, ) : null, ) } placeholder="(0 ~ 0.5, 0.01 단위)" />
)} />
)} {tabValue !== "IMR" && ( 스케일 조정 계수(A) (
field.onChange( e.target .value ? Number( e .target .value, ) : null, ) } placeholder="(0 ~ 1, 0.01 단위)" />
)} />
임계 계수(c) (
field.onChange( e.target .value ? Number( e .target .value, ) : null, ) } placeholder="(0 ~ 100, 1 단위)" />
)} />
)}
{data && ( )}
숫자형 컬럼 목록
컬럼명 데이터 타입 코멘트 선택 {numericColumns.length === 0 ? ( 조회된 숫자형 컬럼이 없습니다. ) : ( numericColumns.map((col, idx) => ( {col.columnName} {col.dataType} {col.columnComment} )) )}
); }