[as frontend] 체크리스트 뷰시 rvw_stp_com_cd.리뷰단계코드및, 업무구분별로 뷰단에서 보이는 부분정리
This commit is contained in:
@@ -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" ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user