[st] feat: 검증 항목 관리 > 컬럼 검사 버튼 추가

This commit is contained in:
2026-03-20 14:45:02 +09:00
parent 57b16653d4
commit 6eb8a3baac
4 changed files with 183 additions and 91 deletions
@@ -19,6 +19,11 @@ import type {
} from "@/entities/statistics/model/verification-target-management-interface";
import {
Button,
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
Input,
Label,
Tabs,
@@ -58,6 +63,8 @@ function VerificationArticleManagement() {
const [dialogOpen, setDialogOpen] = useState(false);
const [selectedData, setSelectedData] =
useState<VerificationTargetManagementResponse | null>(null);
const [resultDialogOpen, setResultDialogOpen] = useState(false);
const [resultDialogMessage, setResultDialogMessage] = useState("");
const { data: verificationData } = useQuery({
queryKey: [ENDPOINT.STATVERIFY_SERVICE.VRFCTGT_MNG, searchParams],
@@ -172,6 +179,23 @@ function VerificationArticleManagement() {
},
});
const checkColumnsMutation = useMutation({
mutationFn: () =>
verificationTargetManagementApi.checkColumnsExist({
vrfcMthdCd: activeTab,
}),
onSuccess: (response) => {
setResultDialogMessage(
response.message || "컬럼 검사가 완료되었습니다.",
);
setResultDialogOpen(true);
},
onError: () => {
setResultDialogMessage("컬럼 검사 중 오류가 발생했습니다.");
setResultDialogOpen(true);
},
});
function handleRowClick(rowData: Record<string, string | number>) {
setSelectedData(
rowData as unknown as VerificationTargetManagementResponse,
@@ -205,101 +229,137 @@ function VerificationArticleManagement() {
}
}
async function handleCheckColumns() {
if (!(await confirm("컬럼 검사를 실행하시겠습니까?"))) return;
checkColumnsMutation.mutate();
}
return (
<Tabs
defaultValue="HB"
value={activeTab}
onValueChange={handleTabChange}
>
<TabsList>
<>
<Tabs
defaultValue="HB"
value={activeTab}
onValueChange={handleTabChange}
>
<TabsList>
{Object.entries(TAB_CONFIG).map(([key, config]) => (
<TabsTrigger
key={key}
value={config.value}
className="!px-[2rem] !py-[0.8rem] !text-[1.2rem]"
>
{config.label}
</TabsTrigger>
))}
</TabsList>
<div className="card card-border !mx-0">
<form onSubmit={handleSubmit}>
<div className="flex items-center gap-4">
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
통계항목
</Label>
<CodeSelect
upCd="STITEM"
value={statsCd}
onValueChange={setStatsCd}
placeholder="선택"
className="w-[16rem]"
/>
</div>
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
검증명
</Label>
<Input
value={vrfcTrgtNm}
onChange={(e) =>
setVrfcTrgtNm(e.target.value)
}
placeholder="검증명"
className="w-[20rem]"
/>
</div>
<div className="ml-auto flex gap-2">
<Button
type="button"
color="white"
className="h-[3.6rem]"
onClick={handleCheckColumns}
disabled={checkColumnsMutation.isPending}
>
컬럼 검사
</Button>
<Button
type="button"
className="h-[3.6rem]"
onClick={handleRegister}
>
등록
</Button>
<Button
type="submit"
color="green"
className="h-[3.6rem]"
>
조회
</Button>
<Button
type="button"
color="gray"
className="h-[3.6rem]"
onClick={handleInitialize}
>
초기화
</Button>
</div>
</div>
</form>
</div>
{Object.entries(TAB_CONFIG).map(([key, config]) => (
<TabsTrigger
key={key}
value={config.value}
className="!px-[2rem] !py-[0.8rem] !text-[1.2rem]"
>
{config.label}
</TabsTrigger>
<TabsContent key={key} value={config.value}>
<DataGrid
columnInfo={columnInfo}
rowData={rowData}
setRowData={() => {}}
onRowClick={handleRowClick}
isExcelImport={false}
/>
</TabsContent>
))}
</TabsList>
<div className="card card-border !mx-0">
<form onSubmit={handleSubmit}>
<div className="flex items-center gap-4">
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
통계항목
</Label>
<CodeSelect
upCd="STITEM"
value={statsCd}
onValueChange={setStatsCd}
placeholder="선택"
className="w-[16rem]"
/>
</div>
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
검증명
</Label>
<Input
value={vrfcTrgtNm}
onChange={(e) => setVrfcTrgtNm(e.target.value)}
placeholder="검증명"
className="w-[20rem]"
/>
</div>
<div className="ml-auto flex gap-2">
<Button
type="button"
className="h-[3.6rem] w-[80px]"
onClick={handleRegister}
>
등록
</Button>
<Button
type="submit"
color="green"
className="h-[3.6rem] w-[80px]"
>
조회
</Button>
<Button
type="button"
color="gray"
className="h-[3.6rem] w-[80px]"
onClick={handleInitialize}
>
초기화
</Button>
</div>
<VerificationTargetDialog
tabValue={activeTab}
open={dialogOpen}
onOpenChange={setDialogOpen}
data={selectedData}
onSave={handleSave}
onDelete={handleDelete}
/>
</Tabs>
<Dialog open={resultDialogOpen} onOpenChange={setResultDialogOpen}>
<DialogContent
className="max-w-[60rem]"
aria-describedby={undefined}
>
<DialogHeader>
<DialogTitle>컬럼 검사 결과</DialogTitle>
</DialogHeader>
<div className="max-h-[50rem] overflow-y-auto whitespace-pre-wrap break-words text-[1.4rem]">
{resultDialogMessage}
</div>
</form>
</div>
{Object.entries(TAB_CONFIG).map(([key, config]) => (
<TabsContent key={key} value={config.value}>
<DataGrid
columnInfo={columnInfo}
rowData={rowData}
setRowData={() => {}}
onRowClick={handleRowClick}
isExcelImport={false}
/>
</TabsContent>
))}
<VerificationTargetDialog
tabValue={activeTab}
open={dialogOpen}
onOpenChange={setDialogOpen}
data={selectedData}
onSave={handleSave}
onDelete={handleDelete}
/>
</Tabs>
<DialogFooter>
<Button onClick={() => setResultDialogOpen(false)}>
확인
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</>
);
}
@@ -3,6 +3,8 @@ import { ENDPOINT } from "@/shared/config";
import type {
VerificationTargetCodeResponse,
VerificationTargetManagementCheckColumnsParams,
VerificationTargetManagementCheckColumnsResponse,
VerificationTargetManagementService,
VerificationTargetManagementSearchParams,
VerificationTargetManagementListApiResponse,
@@ -45,6 +47,21 @@ export class VerificationTargetManagementApiService implements VerificationTarge
return response.data;
}
/**
* 검증 대상 컬럼 검사
* @param params 검사 조건 (vrfcMthdCd)
*/
public async checkColumnsExist(
params: VerificationTargetManagementCheckColumnsParams,
): Promise<VerificationTargetManagementCheckColumnsResponse> {
const response =
await client.get<VerificationTargetManagementCheckColumnsResponse>(
`${ENDPOINT.STATVERIFY_SERVICE.VRFCTGT_MNG}/check-columns`,
{ params },
);
return response.data;
}
/**
* 테이블 메타데이터 조회
* @param statsCd 통계항목 코드
@@ -58,6 +58,17 @@ export interface VerificationTargetManagementSearchParams {
sort?: string; // 정렬 조건 (예: "vrfcTrgtSn,desc")
}
// 검증 대상 컬럼 검사 검색 DTO
export interface VerificationTargetManagementCheckColumnsParams {
vrfcMthdCd: string; // 검증 방법 코드 (HB, IMR, VAL 등)
}
// 검증 대상 컬럼 검사 응답 DTO
export interface VerificationTargetManagementCheckColumnsResponse {
code: number; // 응답 코드 (정상: 0, 에러: -1)
message: string; // 응답 메시지
}
// 검증 대상 관리 저장 요청 DTO
export interface VerificationTargetManagementSaveRequest {
vrfcMthdCd: string; // 검증 방법 코드 (필수, 최대 10자)
@@ -109,6 +120,10 @@ export interface VerificationTargetManagementService {
vrfcTrgtSn: number,
): Promise<VerificationTargetManagementDetailApiResponse>;
checkColumnsExist(
params: VerificationTargetManagementCheckColumnsParams,
): Promise<VerificationTargetManagementCheckColumnsResponse>;
getVerificationTargetCodes(): Promise<VerificationTargetCodeResponse[]>;
saveVerificationTargetManagement(
+1 -1
View File
@@ -25,7 +25,7 @@
"baseUrl": "./src",
"paths": {
"@/*": ["./*"],
"@common/components": ["../../../packages/common/components/src/"],
"@common/components": ["../../../packages/common/components/dist/"],
"@common/config": ["../../../packages/common/config/dist/"],
"@common/network": ["../../../packages/common/network/"],
"@rsone/components": ["../../../packages/rsone/dist/"]