[as frontend] 체크리스트 뷰시 rvw_stp_com_cd.리뷰단계코드및, 업무구분별로 뷰단에서 보이는 부분정리

This commit is contained in:
2026-06-04 11:02:43 +09:00
parent 2a8c2ae542
commit bb7cce47ac
@@ -55,6 +55,13 @@ const getRoleStepCount = (dtlInstCd?: string): number => {
return mapped ? REVIEW_STEP_ROLE_RANK[mapped] : 0;
};
// 업무구분 코드 -> 표시명 매핑 (체크리스트 그룹 표시용)
const TASK_CODE_LABELS: Record<string, string> = {
RE: "재이용수",
SP: "하수관로",
SF: "하수처리시설",
};
const normalizeChecklistResultMap = (
raw: unknown,
): Record<ReviewStepCode, any[]> => {
@@ -122,6 +129,13 @@ function CnfmViewPage({ id }: { id: string }) {
[visibleStepCount],
);
const [selectedReviewStep, setSelectedReviewStep] = useState<ReviewStepCode>("LOCAL");
// selected task code for header filtering (null = none selected)
const [selectedTaskCode, setSelectedTaskCode] = useState<string | null>(null);
// derive available task codes from checklist results
const taskCodes = useMemo(() => {
return Array.from(new Set((cklstAll ?? []).map((r: any) => (r as any).taskSeComCd).filter(Boolean)));
}, [cklstAll]);
useEffect(() => {
if (visibleReviewStepCodes.length === 0) return;
@@ -130,10 +144,28 @@ function CnfmViewPage({ id }: { id: string }) {
}
}, [selectedReviewStep, visibleReviewStepCodes]);
// when checklist result task codes change, default selectedTaskCode to first available code
useEffect(() => {
if (!taskCodes || taskCodes.length === 0) {
if (selectedTaskCode !== null) setSelectedTaskCode(null);
return;
}
if (!selectedTaskCode || !taskCodes.includes(selectedTaskCode)) {
setSelectedTaskCode(taskCodes[0]);
}
}, [taskCodes, selectedTaskCode]);
const selectedChecklistRows = useMemo(() => {
if (visibleReviewStepCodes.length === 0) return [];
return cklstResultMap[selectedReviewStep] ?? [];
}, [cklstResultMap, selectedReviewStep, visibleReviewStepCodes.length]);
const rows = (cklstResultMap[selectedReviewStep] ?? []).filter((r: any) =>
selectedTaskCode ? (r.taskSeComCd ?? "") === selectedTaskCode : true,
);
return rows
.slice()
.sort((a: any, b: any) =>
(a.cklstArtclSn ?? 0) - (b.cklstArtclSn ?? 0) || (a.sortSeq ?? 0) - (b.sortSeq ?? 0) || (a.cklstRvwSn ?? 0) - (b.cklstRvwSn ?? 0),
);
}, [cklstResultMap, selectedReviewStep, visibleReviewStepCodes.length, selectedTaskCode]);
const [viewCheckResults, setViewCheckResults] = useState<Record<string, string>>({});
const [viewCheckComments, setViewCheckComments] = useState<Record<string, string>>({});
@@ -142,7 +174,7 @@ function CnfmViewPage({ id }: { id: string }) {
const results: Record<string, string> = {};
const comments: Record<string, string> = {};
(selectedChecklistRows ?? []).forEach((row: any) => {
const key = `${row.cklstSn}_${row.cklstRvwSn}_${row.rvwStpComCd ?? "LOCAL"}`;
const key = `${row.taskSeComCd ?? ""}_${row.cklstSn}_${row.cklstArtclSn ?? ""}_${row.cklstRvwSn}_${row.rvwStpComCd ?? "LOCAL"}`;
if (row.rvwRsltAnmlyYn === "Y" || row.rvwRsltAnmlyYn === "N") results[key] = row.rvwRsltAnmlyYn;
if (row.picRvwCn) comments[key] = String(row.picRvwCn);
});
@@ -387,6 +419,24 @@ function CnfmViewPage({ id }: { id: string }) {
{/* 체크리스트 */}
<div className="cnfm-card p-4">
<h3 className="text-[1.5rem] font-bold text-gray-700">체크리스트</h3>
<div className="mb-3 mt-2 flex flex-wrap gap-2">
{Array.from(new Set(taskCodes)).map((code) => {
const name = TASK_CODE_LABELS[code] ?? code;
const active = selectedTaskCode === code;
return (
<button
key={code}
type="button"
className={`rounded border px-3 py-1 text-[1.2rem] font-semibold ${
active ? "border-blue-500 bg-blue-50 text-blue-700" : "border-gray-300 bg-white text-gray-600"
}`}
onClick={() => setSelectedTaskCode(code)}
>
{name}
</button>
);
})}
</div>
<div className="mb-3 mt-2 flex flex-wrap gap-2">
{visibleReviewStepCodes.length === 0 ? (
<span className="text-[1.2rem] text-gray-500">
@@ -446,7 +496,7 @@ function CnfmViewPage({ id }: { id: string }) {
</tr>
) : (
selectedChecklistRows.map((row: any) => {
const key = `${row.cklstSn}_${row.cklstRvwSn}_${row.rvwStpComCd ?? "LOCAL"}`;
const key = `${row.taskSeComCd ?? ""}_${row.cklstSn}_${row.cklstArtclSn ?? ""}_${row.cklstRvwSn}_${row.rvwStpComCd ?? "LOCAL"}`;
const hasResult = row.rvwRsltAnmlyYn === "Y" || row.rvwRsltAnmlyYn === "N";
const showRadios = row.bchckUseYn === "Y" ;