Files
frontend/apps/as/src/pages/esntl-atch-file-mng/ui/esntl-atch-file-list.tsx
T
2026-10-11 12:58:04 +09:00

167 lines
5.1 KiB
TypeScript

"use client";
import { useCallback, useMemo, useState } from "react";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
import { useDataTable } from "@/shared/lib";
import { useDownloadAttachmentByAtflCd } from "@/entities/attach";
import { useCodeList } from "@/entities/code";
import {
type EsntlAtchFileMng,
type EsntlAtchFileMngSearchParams,
useCreateEsntlAtchFileMng,
useDeleteEsntlAtchFileMng,
useEsntlAtchFileMngPage,
useUpdateEsntlAtchFileMng,
} from "@/entities/esntl";
import { Button } from "@common/components";
import { createEsntlAtchFileColumns } from "../model/esntl-atch-file-columns";
import {
EsntlAtchFileFormDialog,
type EsntlAtchFileFormValues,
} from "./esntl-atch-file-form-dialog";
interface EsntlAtchFileListProps {
searchParams: EsntlAtchFileMngSearchParams;
pagination: PaginationState;
onPaginationChange: (pagination: PaginationState) => void;
}
function EsntlAtchFileList({
searchParams,
pagination,
onPaginationChange,
}: EsntlAtchFileListProps) {
const { confirm } = useConfirm();
const { data: docSeCodes } = useCodeList("ASDOCSE");
const { mutate: downloadTemplate } = useDownloadAttachmentByAtflCd();
const [dialogMode, setDialogMode] = useState<"create" | "edit" | null>(null);
const [editingRow, setEditingRow] = useState<EsntlAtchFileMng | null>(null);
const createMutation = useCreateEsntlAtchFileMng();
const updateMutation = useUpdateEsntlAtchFileMng();
const deleteMutation = useDeleteEsntlAtchFileMng();
const queryParams = useMemo(() => {
return {
docSeComCd: searchParams.docSeComCd,
page: pagination.pageIndex,
size: pagination.pageSize,
sort: searchParams.sort,
};
}, [searchParams, pagination]);
const pageQuery = useEsntlAtchFileMngPage(queryParams);
const handleDelete = useCallback(
async (row: EsntlAtchFileMng) => {
if (!(await confirm("삭제하시겠습니까?"))) return;
await deleteMutation.mutateAsync(row.esntlAtchFileId);
},
[confirm, deleteMutation],
);
const handleDownloadTemplate = useCallback(
(atflCd: string) => {
downloadTemplate(atflCd);
},
[downloadTemplate],
);
const columns = useMemo(
() =>
createEsntlAtchFileColumns({
docSeCodes,
onEdit: (row) => {
setEditingRow(row);
setDialogMode("edit");
},
onDelete: handleDelete,
onDownloadTemplate: handleDownloadTemplate,
}),
[docSeCodes, handleDelete, handleDownloadTemplate],
);
const { tableComponent } = useDataTable({
query: pageQuery,
tableOptions: {
columns,
state: { pagination },
onPaginationChange: (updater) => {
const next = typeof updater === "function" ? updater(pagination) : updater;
onPaginationChange(next);
},
getCoreRowModel: getCoreRowModel(),
manualPagination: true,
},
dataTableOptions: {
caption: "필수첨부파일 목록으로 필수첨부파일아이디, 문서구분, 필수첨부파일명, 필수첨부여부, 비고, 양식 내려받기, 관리 정보 제공",
viewPagination: true,
},
});
const handleFormSubmit = async (values: EsntlAtchFileFormValues) => {
if (!values.docSeComCd || !values.esntlAtchFileNm || !values.esntlAtchYn) return;
const body = {
docSeComCd: values.docSeComCd,
esntlAtchFileNm: values.esntlAtchFileNm,
esntlAtchYn: values.esntlAtchYn,
esntlAtchFileRmrk: values.esntlAtchFileRmrk || undefined,
atchFileGroupId: values.atchFileGroupId || undefined,
};
if (dialogMode === "create") {
if (!(await confirm("등록하시겠습니까?"))) return;
await createMutation.mutateAsync(body);
} else if (dialogMode === "edit" && editingRow) {
await updateMutation.mutateAsync({
esntlAtchFileId: editingRow.esntlAtchFileId,
body,
});
}
setDialogMode(null);
setEditingRow(null);
};
const handleOpenCreate = () => {
setEditingRow(null);
setDialogMode("create");
};
return (
<section className="card card-border mx-0 bg-background pt-0">
<div className="card-header flex items-center justify-between">
<h3 className="text-2xl font-semibold">필수첨부파일 목록</h3>
<Button type="button" color="green" onClick={handleOpenCreate}>
등록
</Button>
</div>
{tableComponent}
{dialogMode ? (
<EsntlAtchFileFormDialog
mode={dialogMode}
open={Boolean(dialogMode)}
onOpenChange={(open) => {
if (!open) {
setDialogMode(null);
setEditingRow(null);
}
}}
initial={dialogMode === "edit" ? editingRow : null}
isSubmitting={createMutation.isPending || updateMutation.isPending}
onSubmit={handleFormSubmit}
/>
) : null}
</section>
);
}
export { EsntlAtchFileList };