149 lines
4.5 KiB
TypeScript
149 lines
4.5 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback } from "react";
|
|
|
|
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
|
|
|
import { useAlertStore } from "@/shared/lib";
|
|
import { useCnstpSeMngPage, useSaveMultiCnstpSeMng } from "@/entities/cnstp";
|
|
import {
|
|
Button,
|
|
Skeleton,
|
|
Table,
|
|
TableBody,
|
|
TableHead,
|
|
TableHeader,
|
|
TableRow,
|
|
} from "@common/components";
|
|
|
|
import { cnstpGridConfig } from "../lib/configs/cnstp-config";
|
|
import { useSeGridRows } from "../lib/use-se-grid-rows";
|
|
import type { CnstpSeRow } from "../model/cnstp/cnstp-se-row-types";
|
|
|
|
import { CnstpSeRowComponent } from "./cnstp-se-row";
|
|
|
|
function CnstpCodeTabPanel() {
|
|
const { confirm } = useConfirm();
|
|
const alert = useAlertStore((state) => state.setMessage);
|
|
|
|
const pageQuery = useCnstpSeMngPage({
|
|
page: 0,
|
|
size: 500,
|
|
sort: "sortSeq,asc",
|
|
});
|
|
|
|
const saveMultiMutation = useSaveMultiCnstpSeMng();
|
|
|
|
const handlePersist = useCallback(
|
|
async (payload: Parameters<typeof saveMultiMutation.mutateAsync>[0]) => {
|
|
await saveMultiMutation.mutateAsync(payload);
|
|
},
|
|
[saveMultiMutation],
|
|
);
|
|
|
|
const {
|
|
displayRows,
|
|
canSave,
|
|
updateRow,
|
|
addRootRow,
|
|
addChildRow,
|
|
removeDraft,
|
|
markDeleted,
|
|
resetFromServer,
|
|
save,
|
|
} = useSeGridRows(cnstpGridConfig, {
|
|
serverContent: pageQuery.data?.content,
|
|
onAlert: alert,
|
|
onSave: handlePersist,
|
|
});
|
|
|
|
const handleDelete = async (row: CnstpSeRow) => {
|
|
if (!(await confirm("삭제하시겠습니까?"))) return;
|
|
|
|
if (row.isNew) {
|
|
removeDraft(row.rowKey);
|
|
return;
|
|
}
|
|
|
|
markDeleted(row.rowKey);
|
|
};
|
|
|
|
const handleSave = async () => {
|
|
if (!(await confirm("저장하시겠습니까?"))) return;
|
|
|
|
const saved = await save();
|
|
if (!saved) return;
|
|
|
|
alert("저장되었습니다.");
|
|
const result = await pageQuery.refetch();
|
|
resetFromServer(result.data?.content ?? []);
|
|
};
|
|
|
|
const isSaving = saveMultiMutation.isPending;
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<div className="flex flex-wrap items-center justify-end gap-3 px-4">
|
|
<Button type="button" color="green" onClick={addRootRow}>
|
|
코드 추가
|
|
</Button>
|
|
<Button type="button" disabled={!canSave || isSaving} onClick={handleSave}>
|
|
저장
|
|
</Button>
|
|
</div>
|
|
|
|
{pageQuery.isPending ? (
|
|
<div className="flex flex-col gap-2 px-4 pb-4">
|
|
<Skeleton className="h-[4rem]" />
|
|
<Skeleton className="h-[16rem]" />
|
|
</div>
|
|
) : displayRows.length === 0 ? (
|
|
<p className="py-8 text-center text-lg text-muted-foreground">
|
|
등록된 코드가 없습니다. [코드 추가]로 1단계 코드를 등록하세요.
|
|
</p>
|
|
) : (
|
|
<div className="max-h-[60rem] overflow-y-auto px-4 pb-4 pt-1">
|
|
<Table caption="공사코드 목록으로 코드, 코드명, 설명, 숫자 여부, 소숫점 단위, 사용 여부, 정렬순서, 구분, 관리 정보 제공" className="w-full">
|
|
<colgroup>
|
|
<col width="14%" />
|
|
<col width="16%" />
|
|
<col width="26%" />
|
|
<col width="11%" />
|
|
<col width="8%" />
|
|
<col width="8%" />
|
|
<col width="11%" />
|
|
</colgroup>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead scope="col">코드</TableHead>
|
|
<TableHead scope="col">코드명</TableHead>
|
|
<TableHead scope="col">설명</TableHead>
|
|
<TableHead scope="col">숫자 여부</TableHead>
|
|
<TableHead scope="col">소숫점 단위</TableHead>
|
|
<TableHead scope="col">사용 여부</TableHead>
|
|
<TableHead scope="col">정렬순서</TableHead>
|
|
<TableHead scope="col">구분</TableHead>
|
|
<TableHead scope="col">관리</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{displayRows.map(({ row, depth }) => (
|
|
<CnstpSeRowComponent
|
|
key={row.rowKey}
|
|
row={row}
|
|
depth={depth}
|
|
onChange={(patch) => updateRow(row.rowKey, patch)}
|
|
onAddChild={() => addChildRow(row)}
|
|
onDelete={() => handleDelete(row)}
|
|
/>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export { CnstpCodeTabPanel };
|