From d8c53444519babef012aeebab29eaf42113f48dc Mon Sep 17 00:00:00 2001 From: mind-one001 Date: Tue, 11 Aug 2026 11:11:09 +0900 Subject: [PATCH] =?UTF-8?q?=EA=B4=80=EB=A7=9D=EB=8F=84=20=EB=B6=84?= =?UTF-8?q?=EC=84=9D=EB=8F=84=EA=B5=AC=20=EC=9C=84=EC=B9=98=20=EC=A1=B0?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../analysisMenu/AnalysisPopupMenu.tsx | 166 ++++++++++-------- apps/sn/app/(map-layout)/map/page.tsx | 8 +- .../001-fe-FE-MAP-우측도구배치-구현기록.md | 62 +++++++ 3 files changed, 156 insertions(+), 80 deletions(-) create mode 100644 apps/sn/docs/작업내용/FE-MAP-우측도구배치/001-fe-FE-MAP-우측도구배치-구현기록.md diff --git a/apps/sn/app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx b/apps/sn/app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx index 51bd9a5f1..d321dd5a4 100644 --- a/apps/sn/app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx +++ b/apps/sn/app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx @@ -3,8 +3,8 @@ import { useEffect, useState, type ComponentType, type ReactNode } from "react"; import { ChartColumnBig, - ChevronLeft, - ChevronRight, + ChevronDown, + ChevronUp, PanelsTopLeft, PencilRuler, Search, @@ -61,11 +61,19 @@ const ANALYSIS_POPUP_ITEMS: Array<{ { key: "infoSearch", label: "정보검색", icon: Search }, { key: "pipeAnalysisPopup", label: "관로분석", icon: ChartColumnBig }, { key: "floodPredictionMapPopup", label: "침수예측지도", icon: Waves }, - { key: "agedPipeStatusByCtpvPopup", label: "시도별 노후관로현황", icon: ChartColumnBig }, + { + key: "agedPipeStatusByCtpvPopup", + label: "시도별 노후관로현황", + icon: ChartColumnBig, + }, { key: "gisEditPopup", label: "GIS 편집", icon: PencilRuler }, { key: "gisManagementPopup", label: "GIS 관리", icon: Settings2 }, { key: "flowRiskPopup", label: "통수 위험", icon: TriangleAlert }, - { key: "inftwtResultPopup", label: "침입수 분석결과", renderIcon: InftwtMenuIcon }, + { + key: "inftwtResultPopup", + label: "침입수 분석결과", + renderIcon: InftwtMenuIcon, + }, { key: "rdiiResultPopup", label: "RDII 분석결과", icon: ChartColumnBig }, ]; @@ -78,7 +86,9 @@ export default function AnalysisPopupMenu({ initialActiveKey = null, }: Props) { const [isOpen, setIsOpen] = useState(true); - const [activeKey, setActiveKey] = useState(initialActiveKey); + const [activeKey, setActiveKey] = useState< + WindowPopupKey | "infoSearch" | null + >(initialActiveKey); useEffect(() => { if (!isGisEditActive && activeKey === "gisEditPopup") { @@ -98,87 +108,91 @@ export default function AnalysisPopupMenu({ }, [initialActiveKey]); return ( -
-
- {isOpen ? ( -
-
-
- - 분석도구 -
-
+
+
+
+
+ + 분석도구 +
-
- {ANALYSIS_POPUP_ITEMS.map((item) => { - const Icon = item.icon; - const isActive = item.key === "gisEditPopup" + +
+ + {isOpen ? ( +
+ {ANALYSIS_POPUP_ITEMS.map((item) => { + const Icon = item.icon; + const isActive = + item.key === "gisEditPopup" ? isGisEditActive : activeKey === item.key; - return ( - - ); - })} -
+ const popupWindow = onOpenPopup(item.key); + if (!popupWindow) { + setActiveKey(null); + return; + } + + const closeWatcher = window.setInterval(() => { + if (!popupWindow.closed) return; + window.clearInterval(closeWatcher); + setActiveKey((currentKey) => + currentKey === item.key ? null : currentKey, + ); + }, 300); + }} + > + {item.renderIcon ? item.renderIcon({ isActive }) : null} + {Icon ? ( + + ) : null} + {item.label} + + ); + })}
) : null} - -
); diff --git a/apps/sn/app/(map-layout)/map/page.tsx b/apps/sn/app/(map-layout)/map/page.tsx index 380a6b2af..c5963e0ba 100644 --- a/apps/sn/app/(map-layout)/map/page.tsx +++ b/apps/sn/app/(map-layout)/map/page.tsx @@ -7850,7 +7850,7 @@ const Map = () => { .sn-map-control-layout .mapbtn { top: auto; right: 15px; - bottom: 451px; + bottom: 439px; } .sn-map-control-layout .custom-toolbar { @@ -7860,12 +7860,12 @@ const Map = () => { .sn-map-control-layout .tool-bar { top: auto; right: 15px; - bottom: 248px; + bottom: 230px; } .sn-map-control-layout .zoom-level-control { - right: 16px; - bottom: 56px; + right: 15px; + bottom: 36px; } .sn-map-control-layout .zoom-level-summary { diff --git a/apps/sn/docs/작업내용/FE-MAP-우측도구배치/001-fe-FE-MAP-우측도구배치-구현기록.md b/apps/sn/docs/작업내용/FE-MAP-우측도구배치/001-fe-FE-MAP-우측도구배치-구현기록.md new file mode 100644 index 000000000..fe6dc5008 --- /dev/null +++ b/apps/sn/docs/작업내용/FE-MAP-우측도구배치/001-fe-FE-MAP-우측도구배치-구현기록.md @@ -0,0 +1,62 @@ +# FE-MAP 우측 도구 배치 개선 구현 기록 + +## 작업 목적 + +- 지도 우측의 분석도구 펼침·숨김 버튼을 분석도구 제목 영역 안으로 이동한다. +- 분석도구, 지도 선택 버튼, 지도 도구 모음, 줌 컨트롤의 우측 기준선을 통일한다. +- 우측 도구를 위아래로 재배치해 도구 사이의 겹침을 제거한다. + +## 원본 요구사항 추적 근거 + +- `D:\workspace\IIPBS\docs\기준문서\화면설계서.pptx` + - 슬라이드 12: `SFR-011-003`, 화면 ID `SN_MN010105`, 관로분석·GIS 편집·GIS 관리·통수위험 등 분석도구 구성 + - 슬라이드 14, 16: 지도 우측 분석도구 배치 패턴 + - 슬라이드 32: `SFR-012-003`, `SFR-012-004`, 화면 ID `SN_MN010301`, GIS 편집 + - 슬라이드 33: `SFR-012-002`, 화면 ID `SN_MN010302`, GIS 관리 +- `D:\workspace\IIPBS\docs\기준문서\요구사항정의서.xlsx` + - 시트 `3. (기능)요구사항정의 및 추적표`, 행 89~92: `SFR-011-003`~`SFR-011-006` + - 같은 시트 행 97~99: `SFR-012-002`~`SFR-012-004` + +이번 변경은 원본에 정의된 분석 기능이나 동작 계약을 변경하지 않고, 해당 도구의 화면 배치와 접기·펼치기 UI만 개선한다. + +## 수정 대상 + +- `app/(map-layout)/map/components/analysisMenu/AnalysisPopupMenu.tsx` +- `app/(map-layout)/map/page.tsx` + +## 변경 내용 + +- 분석도구 토글을 외부 돌출 버튼에서 제목 우측의 내부 버튼으로 변경했다. +- 토글에 `aria-label`, `aria-expanded`를 적용하고 접힘 상태에서도 제목 바는 유지하도록 했다. +- 분석도구를 지도 영역 우측 15px 기준으로 고정하고 다른 도구의 우측 기준선도 15px로 통일했다. +- 분석도구 항목 높이와 간격을 소폭 조정하고, 하단 지도 도구들의 `bottom` 위치를 재배치했다. + +## 영향 범위 + +- 프론트엔드 `sn` 지도 화면의 우측 도구 배치에만 영향이 있다. +- API, 상태관리 계약, 백엔드, DB 스키마 영향은 없다. + +## 테스트 및 검증 + +- 변경 내용 검사: `git diff --check` 통과 +- 개발 서버의 Turbopack 컴파일 및 실제 화면 반영 확인 +- 실제 브라우저 검증: `http://localhost:3002/map`, 1920×912 뷰포트 + - 분석도구 우측 좌표: 1905px + - 지도 선택 버튼·지도 도구 모음·줌 컨트롤 우측 좌표: 모두 1905px + - 분석도구→지도 선택 버튼 간격: 6px + - 지도 선택 버튼→지도 도구 모음 간격: 4px + - 지도 도구 모음→줌 컨트롤 간격: 4px + - 숨김 시 `aria-expanded=false`, 분석 메뉴 항목 0개, 제목 바 유지 확인 + - 보이기 시 `aria-expanded=true`, 분석 메뉴 항목 9개 확인 +- 검증 화면: `D:\workspace\IIPBS\docs\작업내용\FE-MAP-우측도구배치\검증\20260811-분석도구-우측도구-정렬.png` + +## 롤백 방법 + +- 위 두 소스 파일에서 본 작업의 분석도구 헤더/토글 구조와 우측 도구 위치값 변경을 되돌린다. +- 구현 기록과 검증 이미지를 제거한다. + +## 남은 리스크 + +- 사용자 실행 중인 Next 개발 서버 보호를 위해 별도 프로덕션 빌드는 수행하지 않았다. +- ESLint는 기존 `apps/sn/eslint.config.mjs`의 배열 전개 오류로, TypeScript 전체 검사는 기존 `tsconfig.json`의 `ignoreDeprecations` 설정 오류로 각각 대상 코드 검사 전에 중단됐다. +- 사용자 제보 화면과 동일한 1920×912 크기의 실제 브라우저에서는 정렬·간격·토글 동작을 확인했다.