diff --git a/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md b/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md index f872890d0..24f7d8c75 100644 --- a/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md +++ b/apps/sn/docs/작업검증/SFR-010-004~SFR-010-007-조사사업/002-qa-SFR-010-004~007-조사사업-통합검증결과.md @@ -600,3 +600,17 @@ | 선형 시설 회귀 | 정적 통과 | 기존 스타일 뒤에 선형 선택 강조를 추가하는 순서 유지 | | 변경 공백·구문 검사 | 통과 | `git diff --check`, `node --check` 수행 | | 브라우저 수동 검증 | 대기 | 맨홀 클릭 후 보라색 맨홀 심볼과 선택 원이 함께 유지되는지 확인 필요 | + +## 38. 2026-08-28 사업등록·수정 양식 버튼 검증 + +| 검증 항목 | 결과 | 비고 | +|---|---|---| +| 사업등록 버튼 순서 | 정적 통과 | 양식다운로드 → 조사보고서 양식다운로드 → 저장 → 취소 | +| 저장 전 입력양식 | 정적 통과 | 사업 ID가 없어 비활성 | +| 저장 전 hover 안내 | 정적 통과 | 사업정보와 처리분구 저장 안내 표시 | +| 신규 저장 후 팝업 | 정적 통과 | 부모 목록 갱신 메시지 전송, 팝업 유지·입력 잠금·양식 활성 | +| 수정 버튼 순서 | 정적 통과 | 양식다운로드 → 저장 → 취소, 조사보고서 양식 미표시 | +| 수정 후 양식 | 정적 통과 | 저장된 최신 처리분구 기준 재생성 | +| 변경 파일 ESLint | 통과 | 오류·경고 0건 | +| `sn` TypeScript 검사 | 통과 | `tsc --noEmit`, 기존 설정값은 명령줄 `ignoreDeprecations=5.0`으로 보정 | +| 로그인 브라우저 | 대기 | 사업등록 저장 후 두 다운로드와 수정 팝업 버튼 3개 최종 확인 | diff --git a/apps/sn/docs/작업계획/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-작업카드.md b/apps/sn/docs/작업계획/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-작업카드.md index 39b63f5f3..f50dfac15 100644 --- a/apps/sn/docs/작업계획/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-작업카드.md +++ b/apps/sn/docs/작업계획/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-작업카드.md @@ -336,3 +336,13 @@ - 지도 피처 선택 강조는 조사유형 색과 분리하고 기존 공통 지도 선택 효과를 유지한다. - 관로 PDF는 새 브라우저 탭이 아니라 `exmnPipeReport` WindowPopup 안에서 표시한다. - 최종 완료 판정 전에는 지도 관로·맨홀 동시 ON/OFF, 필터 변경, 시설 선택, 관로 PDF 성공·실패 흐름의 로그인 브라우저 회귀가 필요하다. + +## 26. 2026-08-28 사업등록·수정 양식 버튼 계약 + +- 사업등록 진입은 `양식다운로드 → 조사보고서 양식다운로드 → 저장 → 취소` 순서를 사용한다. +- `양식다운로드`는 사업 저장 전 비활성이고, 저장 성공 후 팝업을 유지한 상태에서 처리분구별 입력양식을 생성·다운로드한다. +- 저장 전 비활성 양식다운로드에 마우스를 올리면 `사업정보와 처리분구를 먼저 저장해주세요.` 안내를 표시한다. +- `조사보고서 양식다운로드`는 사업 저장 여부와 무관하게 공통 원본 XLSX를 내려받는다. +- 수정 진입은 `양식다운로드 → 저장 → 취소`만 표시하고 조사보고서 공통 양식 버튼은 숨긴다. +- 수정 화면의 양식다운로드는 저장된 최신 처리분구 기준으로 입력양식을 다시 생성한다. +- 등록된 실제 사업보고서 PDF는 기존 조사목록의 보고서 열에서 다운로드하는 계약을 유지한다. diff --git a/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md b/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md index 24aa95c8c..0bb3a9c8a 100644 --- a/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md +++ b/apps/sn/docs/작업내용/SFR-010-004~SFR-010-007-조사사업/001-fe-SFR-010-004~007-조사사업-통합구현기록.md @@ -934,3 +934,13 @@ - Excel 데이터 내보내기는 `엑셀다운로드`, 입력 템플릿은 `양식다운로드`, 일반 첨부파일은 `다운로드`로 구분했다. - `StandardPopupLayout` 본문을 margin 기반 `space-y` 대신 `flex`와 `gap: 1.2rem`으로 변경했다. 자식 카드의 `!m-0` 때문에 간격이 0으로 덮이던 문제를 공통 레이아웃에서 해결했다. - 브라우저에서 조사사업 등록·수정의 `사업 정보`와 `사업대상 처리분구` 카드 사이 실제 간격이 모두 12px인 것을 확인했다. + +## 45. 2026-08-28 사업등록·수정 양식 버튼 분리 + +- 신규 사업등록 저장 성공 시 부모 목록에 `EXMN_BUSINESS_CREATED` 메시지를 전달하되 팝업은 닫지 않도록 변경했다. +- 저장 후 기존 `savedBusiness`와 `formLocked`를 사용해 입력은 잠그고 `양식다운로드`를 활성화한다. +- 저장 전 비활성 버튼은 hover 가능한 래퍼에서 `사업정보와 처리분구를 먼저 저장해주세요.` 안내를 제공한다. +- 사업등록 진입에서는 `양식다운로드`, `조사보고서 양식다운로드`, `저장`, `취소` 순서로 표시한다. +- 수정 진입에서는 `조사보고서 양식다운로드`를 숨기고 `양식다운로드`, `저장`, `취소`만 표시한다. +- 처리분구를 수정한 경우 기존 계약대로 먼저 저장한 뒤 최신 처리분구 기준 입력양식을 다시 생성한다. +- 공통 조사보고서 XLSX와 등록된 사업보고서 PDF의 다운로드 경로는 변경하지 않았다. diff --git a/apps/sn/src/features/exmn/ui/ExmnBusinessRegisterPopupPage.tsx b/apps/sn/src/features/exmn/ui/ExmnBusinessRegisterPopupPage.tsx index c6aa579a8..046a2956f 100644 --- a/apps/sn/src/features/exmn/ui/ExmnBusinessRegisterPopupPage.tsx +++ b/apps/sn/src/features/exmn/ui/ExmnBusinessRegisterPopupPage.tsx @@ -1,12 +1,10 @@ "use client"; -import LoadingOverlay from "@/components/ui/LoadingBar"; -import { getStartYearArray } from "@/components/ui/YearRangeSelectBox"; -import useStore from "@/store/useStore"; -import { - postPopupMessage, - postPopupMessageAndClose, -} from "@/features/windowPopup/lib/popupMessage"; +import { useEffect, useMemo, useRef, useState } from "react"; + +import { useConfirm } from "@frontend-opensource/use-react-hooks"; + +import { postPopupMessage } from "@/features/windowPopup/lib/popupMessage"; import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/windowPopup/model/types"; import { StandardFormField, @@ -22,8 +20,7 @@ import { SelectTrigger, SelectValue, } from "@common/components"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; -import { useEffect, useMemo, useRef, useState } from "react"; + import { createExmnBusiness, createExmnTemplates, @@ -40,6 +37,10 @@ import type { } from "../model/exmn-business-types"; import type { TrtdstSettingDto } from "../model/trtdst-types"; +import LoadingOverlay from "@/components/ui/LoadingBar"; +import { getStartYearArray } from "@/components/ui/YearRangeSelectBox"; +import useStore from "@/store/useStore"; + type Notice = { type: "success" | "error" | "info"; text: string } | null; interface ExmnBusinessRegisterPopupPageProps { @@ -92,6 +93,11 @@ export function ExmnBusinessRegisterPopupPage({ const [isLoading, setIsLoading] = useState(false); const [notice, setNotice] = useState(null); const formLocked = Boolean(savedBusiness) && !isEditMode; + /** 저장 전 비활성 양식버튼에 표시할 업무 안내와 활성 조건이다. */ + const templateDownloadReady = Boolean(savedBusiness?.exmnBizId); + const templateDownloadGuide = templateDownloadReady + ? undefined + : "사업정보와 처리분구를 먼저 저장해주세요."; /** 팝업 레이아웃은 BaseLayout 초기화를 거치지 않으므로 행정구역 공통코드를 직접 준비한다. */ useEffect(() => { @@ -326,10 +332,14 @@ export function ExmnBusinessRegisterPopupPage({ exmnBizId: persisted.exmnBizId, }; if (!isEditMode) { - postPopupMessageAndClose( + postPopupMessage( WINDOW_POPUP_MESSAGE_TYPE.EXMN_BUSINESS_CREATED, popupPayload, ); + setNotice({ + type: "success", + text: "사업정보를 등록했습니다. 조사 입력양식과 조사보고서 양식을 다운로드할 수 있습니다.", + }); return; } @@ -416,22 +426,29 @@ export function ExmnBusinessRegisterPopupPage({ showDefaultCancelAction={false} actions={ <> - - + + + {!isEditMode ? ( + + ) : null}