[as frontend] 체크리스트 입력 3개* 단계별 입력 *3개 전부 표시되도록 화면 수정
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -111,6 +111,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 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<ReviewStepCode>("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<string | null>(null);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const [requiredFiles, setRequiredFiles] = useState<Record<RequiredAttachKey, RequiredAttachItem>>({});
|
||||
const requiredFileInputRefs = useRef<Record<RequiredAttachKey, HTMLInputElement | null>>({});
|
||||
|
||||
@@ -608,6 +624,7 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
const { data: cklstTree = [] } = useQuery<CklstTreeNode[]>({
|
||||
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<ReviewStepCode>();
|
||||
@@ -1506,9 +1545,27 @@ function CnfmRegistPage({ initialData }: { initialData?: any } = {}) {
|
||||
<div className="cnfm-card p-4">
|
||||
<div className="mb-3 flex items-center justify-between">
|
||||
<h3 className="text-[1.5rem] font-bold text-gray-700">체크리스트</h3>
|
||||
<button className="cnfm-btn-search text-[1.2rem]">
|
||||
{(cklstRows[0]?.cklstNm ?? taskSeComCdNm) + `(${cklstStats.completed}/${cklstStats.total})`}
|
||||
</button>
|
||||
<div className="flex gap-2 items-center">
|
||||
{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 (
|
||||
<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 className="text-[1.1rem] text-gray-500">{`(${cklstStats.completed}/${cklstStats.total})`}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{visibleReviewStepCodes.length === 0 ? (
|
||||
|
||||
Reference in New Issue
Block a user