From cc3bc548c9995efc701eb8bafc116267f516e032 Mon Sep 17 00:00:00 2001 From: bicochan Date: Fri, 18 Sep 2026 16:27:51 +0900 Subject: [PATCH] =?UTF-8?q?[as]=20feat:=20=EC=9E=AC=EC=9B=90=ED=98=91?= =?UTF-8?q?=EC=9D=98=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../elapr/ui/elapr-apln-picker-grid.tsx | 7 +-- .../pages/fnrs-cnsltn/lib/button-config.ts | 27 +++++++--- .../ui/components/floating-action-buttons.tsx | 53 ++++++++++++++++--- .../components/pwrk-cnsltn-doc-mng-dialog.tsx | 4 +- .../pwrk-cnsltn-doc-pjtco-ajmt-table.tsx | 12 ++++- apps/as/src/shared/ui/uploaded-file-chip.tsx | 2 +- 6 files changed, 86 insertions(+), 19 deletions(-) diff --git a/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx b/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx index 7f7a88911..c8c84e1c6 100644 --- a/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx +++ b/apps/as/src/entities/elapr/ui/elapr-apln-picker-grid.tsx @@ -90,6 +90,7 @@ function ElaprAplnPickerGrid({ ? isExternalLoading : aplnQuery.isPending && Boolean(elaprTmpltId); const pickingRow = pickingRowKey ? rows.find((r) => r.rowKey === pickingRowKey) : undefined; + const excludedVisibleRows = visibleRows.filter((r) => r.atrzSeComCd !== "ATRZ01"); function handleDragEnd(event: DragEndEvent) { const { active, over } = event; @@ -149,7 +150,7 @@ function ElaprAplnPickerGrid({ ) : !isReady ? (

결재서식을 선택하세요.

- ) : visibleRows.length === 0 ? ( + ) : excludedVisibleRows.length === 0 ? (

등록된 결재선이 없습니다. [결재선 추가]로 결재자를 등록하세요.

@@ -174,10 +175,10 @@ function ElaprAplnPickerGrid({ r.rowKey)} + items={excludedVisibleRows.map((r) => r.rowKey)} strategy={verticalListSortingStrategy} > - {visibleRows.map((row, index) => ( + {excludedVisibleRows.map((row, index) => ( { if (needsAtrzResolve && isRvwLoginUserLoading) return []; @@ -317,12 +319,11 @@ function FloatingActionButtons({ return; } - const isResultReply = prgrsSttsComCd === "RR"; const payload = buildTechReviewReplyPayload( data, checklistFormState, "ENV", - isResultReply ? "EP" : "RB", + "EP", "CP", getReviewOpinionFormData(), opnrNm, @@ -336,6 +337,36 @@ function FloatingActionButtons({ techReviewOpinionRef?.current?.resetForm(); } + async function handleRvwOpnnRplyClick() { + const { percent } = computeReviewStepChecklistProgress( + data.cklstResultList ?? [], + checklistFormState.results, + "ENV", + ); + + if (percent !== 100) { + alert("모든 체크리스트 항목을 체크해야 검토 의견 회신이 가능합니다."); + return; + } + + const payload = buildTechReviewReplyPayload( + data, + checklistFormState, + "ENV", + "RB", + "CP", + getReviewOpinionFormData(), + opnrNm, + ); + + await executeAction({ + action: FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwOpnnRply, + request: payload, + successMessage: "검토 의견 회신이 완료되었습니다.", + }); + techReviewOpinionRef?.current?.resetForm(); + } + async function handleRqstTechRvwClick() { if (prgrsSttsComCd === "LE") { const { percent } = computeReviewStepChecklistProgress( @@ -365,7 +396,7 @@ function FloatingActionButtons({ await executeAction({ action: FNRS_CNSLTN_VIEW_BUTTON_ACTION.rqstActnRvw, request: payload, - successMessage: "조치결과 검토의뢰가 완료되었습니다.", + successMessage: "조치 결과 검토 의뢰가 완료되었습니다.", }); } @@ -570,6 +601,11 @@ function FloatingActionButtons({ 결과 회신 )} + {shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwOpnnRply) && ( + + )} {shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.rvwRply) && ( )} {shouldShowButton(FNRS_CNSLTN_VIEW_BUTTON_ACTION.fileSplmnt) && ( @@ -698,7 +734,11 @@ function FloatingActionButtons({ fnrsCnsltnDocNo={docNo} atrzSeComCdList={atrzSeComCdList} prgrsSttsComCd={prgrsSttsComCd} - canSave={needsElaprPrgrsCheck && !hasPendingApprovalRequest ? false : undefined} + canSave={ + (needsElaprPrgrsCheck && !hasPendingApprovalRequest) || viewOnlyPwrkCnsltnDoc + ? false + : null + } onClose={() => setActiveDialog(null)} /> @@ -837,6 +877,7 @@ const buttonActionHandlers: Record = rjct: handleChangePrgrsSttsComCd, sncnAprv: handleChangePrgrsSttsComCd, rvwRply: handleTechReview, + rvwOpnnRply: handleTechReview, rqstTechRvw: handleRequestExamine, fileSplmnt: handleDmndSplmnt, dsgntRvwr: handleDsgntRvwr, diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-mng-dialog.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-mng-dialog.tsx index 040d3ec40..a740f7356 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-mng-dialog.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-mng-dialog.tsx @@ -43,14 +43,14 @@ const PWRK_ATCH_FILE_KEY_PREFIX = "pwrk-cnsltn-doc::"; const APPROVER_ATRZ_SE_COM_CDS = new Set(["ATRZ03", "ATRZ99"]); -const VIEW_ONLY_PRGRS_STTS_COM_CDS = new Set(["RA", "RR", "EP", "TA"]); +const VIEW_ONLY_PRGRS_STTS_COM_CDS = new Set(["TP", "RA", "RR", "EP", "TA"]); interface PwrkCnsltnDocMngDialogProps { open: boolean; fnrsCnsltnDocNo: string; atrzSeComCdList?: string[]; prgrsSttsComCd?: string; - canSave?: boolean; + canSave?: boolean | null; onClose: () => void; } diff --git a/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-pjtco-ajmt-table.tsx b/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-pjtco-ajmt-table.tsx index cc0c9ba35..bd1cf6120 100644 --- a/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-pjtco-ajmt-table.tsx +++ b/apps/as/src/pages/fnrs-cnsltn/ui/components/pwrk-cnsltn-doc-pjtco-ajmt-table.tsx @@ -43,11 +43,21 @@ function PwrkCnsltnDocPjtcoAjmtTable({ return ( + + + + + 구분 검증결과 - 검증금액 + +
+ 검증금액 + (단위: 백만 원) +
+
diff --git a/apps/as/src/shared/ui/uploaded-file-chip.tsx b/apps/as/src/shared/ui/uploaded-file-chip.tsx index a7eb6fa22..82be5d581 100644 --- a/apps/as/src/shared/ui/uploaded-file-chip.tsx +++ b/apps/as/src/shared/ui/uploaded-file-chip.tsx @@ -12,7 +12,7 @@ interface UploadedFileChipProps { function UploadedFileChip({ fileName, isUploading = false, onRemove }: UploadedFileChipProps) { return ( -
+
{fileName}