diff --git a/apps/as/src/entities/cklst/model/cklst-mng-interface.ts b/apps/as/src/entities/cklst/model/cklst-mng-interface.ts index 7e3187ce7..f6c80e630 100644 --- a/apps/as/src/entities/cklst/model/cklst-mng-interface.ts +++ b/apps/as/src/entities/cklst/model/cklst-mng-interface.ts @@ -24,6 +24,8 @@ export interface CklstTreeNode { rvwCn: string; bchckUseYn: "Y" | "N"; sortSeq: number; + // optional: backend may include the taskSeComCd per node + taskSeComCd?: string; } export interface CklstTreeSearchParams { diff --git a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx index e134746d1..dd042ef29 100644 --- a/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx +++ b/apps/as/src/pages/instl-sncn/ui/cnfm-regist-page.tsx @@ -111,6 +111,13 @@ const getRoleStepCount = (dtlInstCd?: string): number => { return mapped ? REVIEW_STEP_ROLE_RANK[mapped] : 0; }; +// 업무구분 코드 -> 표시명 매핑 (체크리스트 그룹 표시용) +const TASK_CODE_LABELS: Record = { + RE: "재이용수", + SP: "하수관로", + SF: "하수처리시설", +}; + const normalizeChecklistResultRows = (payload: any): any[] => { // expect flat `cklstResultList` only const raw = payload?.cklstResultList ?? []; @@ -175,6 +182,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { return visibleReviewStepCodes.includes(step) ? step : null; }, [isModifyMode, userInfo?.dtlInstCd, visibleReviewStepCodes]); const [selectedReviewStep, setSelectedReviewStep] = useState("LOCAL"); + useEffect(() => { if (visibleReviewStepCodes.length === 0) return; @@ -245,6 +253,14 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { staleTime: Infinity, }); + // selected task code for header filtering (null = none selected) + const [selectedTaskCode, setSelectedTaskCode] = useState(null); + + + + + + const [requiredFiles, setRequiredFiles] = useState>({}); const requiredFileInputRefs = useRef>({}); @@ -608,6 +624,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { const { data: cklstTree = [] } = useQuery({ queryKey: ["cklstTree", docSeComCd, taskSeComCd], queryFn: async () => { + console.log("Fetching checklist tree with", { docSeComCd, taskSeComCd }); // support comma-separated task codes (e.g. "RE,SP") by splitting const raw = taskSeComCd ?? ""; const codes = raw @@ -639,7 +656,9 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { // bchckUseYn 필터 제거: 부모가 있는 자식 노드(bchckUseYn=N)도 트리에 포함 // cklstTree 내의 피드 taskSeComCd 에 따라서 그룹핑 되도록 해줘 - const useRows = cklstTree; + const useRows = selectedTaskCode + ? cklstTree.filter((r) => (r as any).taskSeComCd === selectedTaskCode) + : cklstTree; if (useRows.length === 0) return [] as CklstTreeNode[]; // artcl 단위로 분리하지 않고 전체 rows에서 단일 childMap을 구성한다. @@ -673,7 +692,26 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { walk(null); return ordered; - }, [cklstTree]); + }, [cklstTree, selectedTaskCode]); + + // when cklstTree changes, default selectedTaskCode to first available code + useEffect(() => { + const codes = Array.from( + new Set((cklstTree ?? []).map((r) => (r as any).taskSeComCd).filter(Boolean)), + ); + console.log("Available taskSeComCd codes in checklist tree:", codes); + + if (codes.length === 0) { + if (selectedTaskCode !== null) setSelectedTaskCode(null); + return; + } + + // if there's no selection yet, or the current selection is not in the new codes, + // pick the first available code + if (!selectedTaskCode || !codes.includes(selectedTaskCode)) { + setSelectedTaskCode(codes[0]); + } + }, [cklstTree, selectedTaskCode]); const cklstKey = (row: CklstTreeNode, rvwStpComCd?: string) => { const stepCode = rvwStpComCd ?? DEFAULT_RVW_STP_COM_CD; @@ -800,6 +838,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) { return { total, completed, percent }; }, [cklstRows, checkResults, selectedReviewStep]); + const toCklstSaveDtoList = () => { const persistedStepCodeSet = new Set(); @@ -1506,9 +1545,27 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {

체크리스트

- +
+ {Array.from(new Set((cklstTree ?? []).map((r) => (r as any).taskSeComCd).filter(Boolean))).map( + (code) => { + const name = TASK_CODE_LABELS[code] ?? code; + const active = selectedTaskCode === code; + return ( + + ); + }, + )} +
{`(${cklstStats.completed}/${cklstStats.total})`}
+
{visibleReviewStepCodes.length === 0 ? (