관로 이동 도구 on/off 유지 및 입력정보 조회 오류 방어
This commit is contained in:
@@ -83,6 +83,9 @@ const toEditableText = (value: unknown) => {
|
||||
return text === "-" ? "" : text;
|
||||
};
|
||||
|
||||
const isInvalidPipeLookupKey = (value: string) =>
|
||||
!value || value === "-" || /^NEW-/i.test(value) || /^(null|undefined)$/i.test(value);
|
||||
|
||||
const toDateInputValue = (value: unknown) => {
|
||||
const text = toEditableText(value).replaceAll(".", "").replaceAll("-", "");
|
||||
if (!/^\d{8}$/.test(text)) return "";
|
||||
@@ -181,8 +184,7 @@ export default function GisEditPipeSessionPopup({
|
||||
const result = await getData("v1/fcltppl/mngInsts");
|
||||
if (!isMounted) return;
|
||||
setMngInstOptions(Array.isArray(result) ? result : []);
|
||||
} catch (error) {
|
||||
console.error("관리기관 목록 조회 실패:", error);
|
||||
} catch {
|
||||
if (isMounted) setMngInstOptions([]);
|
||||
}
|
||||
};
|
||||
@@ -237,8 +239,7 @@ export default function GisEditPipeSessionPopup({
|
||||
|
||||
const fcltMngNo = String(change.featureRef?.fcltMngNo ?? "").trim();
|
||||
const mngInstCd = String(change.featureRef?.mngInstCd ?? "").trim();
|
||||
if (!fcltMngNo || !mngInstCd) return;
|
||||
if (/^NEW-/i.test(fcltMngNo) || /^NEW-/i.test(mngInstCd)) return;
|
||||
if (isInvalidPipeLookupKey(fcltMngNo) || isInvalidPipeLookupKey(mngInstCd)) return;
|
||||
|
||||
let isMounted = true;
|
||||
const fetchPipeInputInfo = async () => {
|
||||
@@ -253,8 +254,8 @@ export default function GisEditPipeSessionPopup({
|
||||
...pickFields(result, PIPE_VISIBLE_INPUT_FIELD_IDS),
|
||||
...pickFields(change.basicInfo ?? {}, PIPE_VISIBLE_INPUT_FIELD_IDS),
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("GIS 편집 관로 입력정보 조회 실패:", error);
|
||||
} catch {
|
||||
// Optional pipe input details should not block the edit session.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1088,7 +1088,7 @@ export const useGisEdit = (treeData: any[]) => {
|
||||
changeId: string,
|
||||
afterGeometry: Record<string, unknown> | null,
|
||||
summary: string,
|
||||
options?: { keepVertexEditActive?: boolean },
|
||||
options?: { keepVertexEditActive?: boolean; keepMoveToolActive?: boolean },
|
||||
) => {
|
||||
setLastSavedPayload(null);
|
||||
setChanges((previous) =>
|
||||
@@ -1106,6 +1106,10 @@ export const useGisEdit = (treeData: any[]) => {
|
||||
if (options?.keepVertexEditActive) {
|
||||
setActiveTool("VERTEX_EDIT");
|
||||
setPendingInteraction({ changeId, editType: "VERTEX_EDIT" });
|
||||
} else if (options?.keepMoveToolActive) {
|
||||
// MOVE는 버튼 재클릭 전까지 도구를 유지하고, 다음 지도 클릭에서 새 대상을 선택하게 한다.
|
||||
setActiveTool("MOVE");
|
||||
setPendingInteraction(null);
|
||||
} else {
|
||||
setActiveTool(null);
|
||||
setPendingInteraction(null);
|
||||
|
||||
@@ -6045,6 +6045,7 @@ const Map = () => {
|
||||
gisEdit.pendingInteraction!.changeId,
|
||||
writeGeometryObject(),
|
||||
`${layerName} ${objectId} 객체 위치를 지도에서 이동했습니다.`,
|
||||
{ keepMoveToolActive: true },
|
||||
);
|
||||
targetFeature.changed?.();
|
||||
source.changed?.();
|
||||
|
||||
@@ -93,6 +93,22 @@
|
||||
- `MOVE`, `VERTEX_EDIT` 중 비하수관로 클릭 시 선택/줌 이동 없이 차단되고 상태문구만 바뀌는지
|
||||
- `MOVE`, `VERTEX_EDIT`에서 하수관로 선택 즉시 편집 상세정보창이 열리는지
|
||||
|
||||
### 3.10 2026-06-26 MOVE 도구 on/off 유지보수 검증 계획
|
||||
|
||||
- 구현 후 아래 순서로 검증한다.
|
||||
1. `GIS편집`을 켜고 `이동` 버튼을 한 번 클릭한다.
|
||||
2. 하수관로 A를 선택하고 drag 이동을 완료한다.
|
||||
3. 이동 완료 후 툴바의 `이동` 버튼 active 상태가 유지되는지 확인한다.
|
||||
4. `이동` 버튼을 다시 누르지 않은 상태에서 하수관로 B를 선택해 이동 interaction이 다시 준비되는지 확인한다.
|
||||
5. 하수관로 B 이동 완료 후에도 `이동` active 상태가 유지되는지 확인한다.
|
||||
6. `이동` 버튼을 다시 클릭하면 active 상태가 꺼지고, 이후 지도 클릭이 이동 변경분을 만들지 않는지 확인한다.
|
||||
- 회귀 확인
|
||||
- `추가`, `꼭지점편집`, `삭제` 버튼은 기존처럼 하나만 active여야 한다.
|
||||
- `스냅핑` on/off는 `이동` active 유지와 별개로 유지되어야 한다.
|
||||
- `닫기`, `저장`, `세션 초기화`, `마지막 변경 취소` 후 이동 도구와 interaction이 남지 않아야 한다.
|
||||
- 검증 분류
|
||||
- 툴바 active 상태와 상태 메시지는 자동 관측 가능하다.
|
||||
- 실제 canvas drag와 관로별 연속 이동 체감은 수동 브라우저 검증을 기본으로 한다.
|
||||
## 4. 현재 검증 범위
|
||||
|
||||
### 4.1 진행 중
|
||||
|
||||
@@ -508,6 +508,26 @@
|
||||
- 관로 중간을 잡고 `MOVE`했을 때도 가장 가까운 관로 꼭지점을 기준으로 결과가 일관적인지
|
||||
- 이동 중 관로 상세 팝업이 열려도 `fetchPipeInputInfo` 500이 재발하지 않는지
|
||||
|
||||
### 2.17 2026-06-26 MOVE 도구 on/off 요구사항 분석 결과
|
||||
|
||||
- 문서/코드 대조 결과
|
||||
- 툴바는 이미 같은 `이동` 버튼을 다시 누르면 `deactivateTool()`로 꺼지는 구조다.
|
||||
- 현재 “한 번 이동하면 이동이 꺼지는” 동작은 사용자가 버튼을 다시 눌러서가 아니라 `MOVE` `translateend` 이후 `updateChangeGeometry()` 기본 경로가 `activeTool`을 `null`로 비우기 때문에 발생한다.
|
||||
- `VERTEX_EDIT`는 `keepVertexEditActive` 옵션으로 연속 편집을 유지하는 특수 경로가 있으나, `MOVE`는 같은 유지 옵션이 없다.
|
||||
- 이번 라운드 결과
|
||||
- `useGisEdit.updateChangeGeometry()`에 `keepMoveToolActive` 옵션을 추가했다.
|
||||
- `MOVE` `translateend` 호출에서 `{ keepMoveToolActive: true }`를 넘겨 이동 완료 후에도 `activeTool="MOVE"`가 유지되도록 했다.
|
||||
- `pendingInteraction`은 이동 완료 후 비워 다음 관로 클릭이 새 이동 대상으로 처리되게 했다.
|
||||
- 정적 검증
|
||||
- 실행 명령: `node apps/sn/node_modules/typescript/bin/tsc -p apps/sn/tsconfig.json --noEmit --pretty false --ignoreDeprecations 5.0`
|
||||
- 결과: 실패. 저장소 기존 오류(`components/common/index.ts`, `floodHistoryTypes.ts`, `page.tsx` 기존 null 가능성, html route, chart props implicit any`)에서 중단됐다.
|
||||
- 이번 변경 파일인 `useGisEdit.ts` 관련 신규 오류는 출력되지 않았다.
|
||||
- 후속 검증 필요
|
||||
- 관로 A 이동 후 이동 버튼 active 유지 여부
|
||||
- 관로 B 연속 이동 가능 여부
|
||||
- 이동 버튼 재클릭 off 여부
|
||||
- `추가`/`꼭지점편집`/`삭제`/`스냅핑`/`닫기`/`저장` 회귀 여부
|
||||
|
||||
## 3. 현재 검증 상태
|
||||
|
||||
### 3.1 통과
|
||||
@@ -597,3 +617,17 @@
|
||||
- `008-qa-SFR-012-003-하수관로편집-실제지도조작검증결과.md`
|
||||
- `010-qa-SFR-012-003-하수관로편집-MOVE실드래그검증결과.md`
|
||||
- `012-qa-SFR-012-003-하수관로편집-VERTEX_EDIT실조작검증결과.md`
|
||||
### 2.18 2026-06-26 관로 입력정보 조회 오류 방어 결과
|
||||
|
||||
- 확인된 오류
|
||||
- `GisEditPipeSessionPopup.useEffect.fetchPipeInputInfo`에서 `GET /api/v1/fcltppl/{fcltMngNo}/{mngInstCd}` 실패 응답이 `buildRequestError()`를 거쳐 `Error: ERROR`로 콘솔 출력됐다.
|
||||
- 조치 결과
|
||||
- 프론트는 잘못된 상세 식별값 조회를 차단하고, 선택적 조회 실패를 콘솔 오류로 출력하지 않도록 수정했다.
|
||||
- 백엔드는 관로 상세 보조속성/관리기관명 조회 실패를 빈 보조정보로 fallback하여 상세 API가 가능한 한 200 응답을 유지하도록 보강했다.
|
||||
- 정적 검증
|
||||
- FE TypeScript 명령은 기존 저장소 오류로 실패했다. 이번 수정 파일인 `GisEditPipeSessionPopup.tsx` 관련 신규 오류는 출력되지 않았다.
|
||||
- BE `./gradlew.bat compileJava`는 통과했다.
|
||||
- FE/BE `git diff --check`는 CRLF 경고만 출력했고 whitespace 오류는 없었다.
|
||||
- 남은 수동 검증
|
||||
- 브라우저에서 MOVE 후 상세 팝업 진입 시 Console Error 오버레이가 뜨지 않는지 확인이 필요하다.
|
||||
- Network 탭에서 `fcltppl` 조회가 실패해도 팝업 입력 흐름이 유지되는지 확인이 필요하다.
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
- `COMMON_DOCS_ROOT/작업지시/SFR-012-003-하수관로편집/하수관망도편집_화면설계서_v1_1.png`
|
||||
|
||||
## 1-2. 최근 진행 갱신
|
||||
- 2026-06-26
|
||||
- `MOVE` 도구가 관로 1회 이동 후 자동 해제되는 현상을 요구사항 분석 범위로 확인했다.
|
||||
- 현재 원인은 `useGisEdit.updateChangeGeometry()` 기본 경로가 geometry 갱신 뒤 `activeTool`과 `pendingInteraction`을 모두 비우는 구조이고, `page.tsx`의 `MOVE translateend`가 이 함수를 옵션 없이 호출하는 데 있다.
|
||||
- 구현은 `MOVE` 완료 후 `activeTool="MOVE"`를 유지하고 `pendingInteraction`만 비워 다음 관로 클릭을 새 이동 대상으로 받는 방식으로 반영했다.
|
||||
- 정적 타입체크는 실행했으나 저장소 기존 오류에서 실패했고, 실제 브라우저 연속 이동 검증은 다음 수동 검증 범위로 남긴다.
|
||||
- 2026-06-08
|
||||
- `MOVE`와 `꼭지점편집` 사이에 `스냅핑` on/off 버튼을 추가하고, 편집 세션/상태 스냅샷에도 `ON/OFF`가 보이도록 연결했다.
|
||||
- 기존 임시 스냅 수집 방식으로는 원본 오수관에 안정적으로 붙지 않는다고 판단해, 1차 재구현 범위를 `ADD`, `VERTEX_EDIT`로 줄였다.
|
||||
@@ -236,3 +241,7 @@
|
||||
- BE 공유용 API 요청 문서가 별도 정리됨
|
||||
- 브라우저에서 정상/예외 시나리오를 확인할 수 있음
|
||||
- 결과 보고 시 작업 목적, 수정 대상 파일, 영향 범위, 검증 방법, 롤백, 리스크를 정리할 수 있음
|
||||
- 2026-06-26 관로 입력정보 조회 오류 방어
|
||||
- MOVE on/off 기능 테스트 중 기존 관로 상세 입력정보 조회 실패가 `Error: ERROR` 콘솔 오류로 노출되는 문제를 확인했다.
|
||||
- `GisEditPipeSessionPopup`은 선택적 입력정보 조회 실패를 편집 세션 중단/콘솔 오류로 처리하지 않고, 기존 WFS/세션 draft 값을 유지하도록 보강한다.
|
||||
- 백엔드 `PplService`는 MS 보조 상세속성/관리기관명 조회 실패를 전체 API 500으로 전파하지 않고 fallback하도록 보강한다.
|
||||
|
||||
@@ -241,6 +241,31 @@
|
||||
- 남긴 판단
|
||||
- `MOVE` 체감이 여전히 어색하면 다음 단계는 grip point를 지도 위에 직접 시각화해 사용자가 “지금 어떤 점을 잡고 이동 중인지”를 보이게 해야 한다.
|
||||
|
||||
### 4.19 2026-06-26 MOVE 도구 on/off 유지보수 분석
|
||||
|
||||
- 사용자 요구사항
|
||||
- `GIS편집`에서 `이동`을 한 번 누르면 여러 관로를 연속으로 이동할 수 있어야 한다.
|
||||
- `이동` 버튼을 다시 누르면 이동 모드가 꺼지는 on/off 방식이어야 한다.
|
||||
- 현재 코드 확인
|
||||
- `GisEditToolbar`는 `activeTool === "MOVE"`일 때 `이동` 버튼을 active 색상으로 표시한다.
|
||||
- `handleSelectGisEditTool()`은 같은 도구를 다시 누르면 `gisEdit.deactivateTool()`을 호출하므로 버튼 재클릭 off 구조는 이미 있다.
|
||||
- 문제는 `MOVE` `Translate`의 `translateend`가 끝날 때 `gisEdit.updateChangeGeometry(...)`를 호출하고, 해당 훅 함수가 기본적으로 `setActiveTool(null)`과 `setPendingInteraction(null)`을 실행하는 데 있다.
|
||||
- 따라서 한 번 이동이 끝나면 사용자가 버튼을 다시 누른 것이 아니어도 `activeTool`이 `null`로 바뀌어 이동 도구가 꺼진다.
|
||||
- 다음 구현 방향
|
||||
- `MOVE` 완료 후에는 `activeTool`을 `"MOVE"`로 유지한다.
|
||||
- 이동이 끝난 같은 preview feature에 interaction이 계속 묶이지 않도록 `pendingInteraction`은 비운다.
|
||||
- 다음 관로 또는 preview feature를 클릭하면 기존 `registerFeatureSelection()` 흐름이 새 `pendingInteraction`을 만들고 이동 interaction을 다시 붙이게 한다.
|
||||
- 기존 `VERTEX_EDIT`의 `keepVertexEditActive` 동작과 충돌하지 않도록 `MOVE` 전용 옵션 또는 범용 `keepActiveTool` 옵션으로 좁혀 구현한다.
|
||||
- 이번 라운드 반영
|
||||
- `useGisEdit.updateChangeGeometry()` 옵션에 `keepMoveToolActive`를 추가했다.
|
||||
- `MOVE` `translateend`에서 geometry를 세션에 반영한 뒤 `{ keepMoveToolActive: true }`를 넘겨 `이동` 도구 active 상태를 유지한다.
|
||||
- 같은 preview feature에 interaction이 계속 묶이지 않도록 `pendingInteraction`은 `null`로 비운다.
|
||||
- 버튼 재클릭 off는 기존 `handleSelectGisEditTool()`의 동일 도구 클릭 분기를 그대로 사용한다.
|
||||
- 검증
|
||||
- `node apps/sn/node_modules/typescript/bin/tsc -p apps/sn/tsconfig.json --noEmit --pretty false --ignoreDeprecations 5.0` 실행 결과, 저장소 기존 TypeScript 오류에서 실패했다.
|
||||
- 이번 변경 파일인 `useGisEdit.ts` 관련 신규 오류는 출력되지 않았고, `page.tsx`는 기존 `GisApp.Module.layer` null 가능성 오류가 남아 있다.
|
||||
- 실제 브라우저에서 관로 A/B 연속 이동과 버튼 재클릭 off 검증은 아직 필요하다.
|
||||
|
||||
## 5. 기능별 현재 상태
|
||||
|
||||
### 5.1 `ADD`
|
||||
@@ -325,3 +350,14 @@
|
||||
- 기대 효과
|
||||
- 관로 클릭 직후 팝업 기본정보가 즉시 표시된다.
|
||||
- `/api/v1/fcltppl/null/null` 같은 불필요 호출을 줄여 상세 체감 지연과 백엔드 부하를 함께 낮춘다.
|
||||
### 4.20 2026-06-26 관로 입력정보 조회 오류 방어
|
||||
|
||||
- 배경
|
||||
- MOVE on/off 동작 확인 중 `GisEditPipeSessionPopup`의 기존 관로 입력정보 조회에서 `Error: ERROR` 콘솔 오류가 발생했다.
|
||||
- 해당 조회는 편집 세션 보조 입력정보를 채우기 위한 선택적 조회이므로, 실패해도 관로 이동/세션 편집 자체를 막지 않아야 한다.
|
||||
- 반영 내용
|
||||
- `GisEditPipeSessionPopup`에 `isInvalidPipeLookupKey`를 추가해 빈 값, `-`, `NEW-*`, `null`, `undefined` 문자열이면 `GET /api/v1/fcltppl/{fcltMngNo}/{mngInstCd}` 호출을 건너뛰도록 했다.
|
||||
- 관리기관 목록과 관로 입력정보 조회 실패 catch에서 `console.error`를 제거해 Next 개발 콘솔 오버레이가 뜨지 않도록 했다.
|
||||
- 조회 실패 시 기존 WFS 속성/세션 draft 값을 유지하고 팝업 입력 흐름은 계속 진행한다.
|
||||
- 백엔드 연동 보강
|
||||
- `PplService.findByFcltMngNo(fcltMngNo, mngInstCd)`에서 MS 관로 상세 보조속성 조회와 관리기관명 조회를 안전 래퍼로 감싸, 보조 조회 실패가 `GET /api/v1/fcltppl/...` 전체 500으로 전파되지 않게 했다.
|
||||
|
||||
Reference in New Issue
Block a user