- SuperportDetailDialog 위젯과 showSuperportDetailDialog 헬퍼를 추가하고 metadata/섹션 패턴을 표준화 - 결재/재고/마스터 각 상세 다이얼로그를 dialogs 디렉터리에 신설하고 기존 페이지를 신규 팝업으로 전환 - SuperportTable 행 선택과 우편번호 검색 다이얼로그 onRowTap 보정을 통해 헤더 오프셋 버그를 제거 - 상세 다이얼로그 및 트랜잭션/상세 뷰 전용 위젯 테스트와 tester_extensions 유틸을 추가하여 회귀를 방지 - detail_dialog_unification_plan.md로 작업 배경과 필드 통합 계획을 문서화
15 KiB
15 KiB
상세 팝업 정보 영역 통합 계획
1. 배경
- 현재 모든 상세 팝업(마스터·결재·재고 등)은
SuperportDetailDialog상단 summary/metadata(정보1)와 탭 섹션(정보2)에서 동일한 엔티티 데이터를 중복 노출한다. - 사용자는 정보가 하나의 블록에서 완결되길 기대하지만, 구현상 개요(summary)와
_OverviewSection사이에 필드가 분산되어 정보1/정보2가 따로 보이게 된다. - 같은 API 데이터를 두 영역에 반복 표기하면서도 정보 간 일관성이 떨어져 UX 혼란이 발생한다.
2. 대상 팝업
| 분류 | 파일 |
|---|---|
| 결재 템플릿 | lib/features/approvals/template/presentation/dialogs/approval_template_detail_dialog.dart |
| 결재 단계 | lib/features/approvals/step/presentation/dialogs/approval_step_detail_dialog.dart |
| 벤더 | lib/features/masters/vendor/presentation/dialogs/vendor_detail_dialog.dart |
| 그룹 | lib/features/masters/group/presentation/dialogs/group_detail_dialog.dart |
| 그룹 메뉴 권한 | lib/features/masters/group_permission/presentation/dialogs/group_permission_detail_dialog.dart |
| 고객사 | lib/features/masters/customer/presentation/dialogs/customer_detail_dialog.dart |
| 메뉴 | lib/features/masters/menu/presentation/dialogs/menu_detail_dialog.dart |
| 제품 | lib/features/masters/product/presentation/dialogs/product_detail_dialog.dart |
| 사용자 | lib/features/masters/user/presentation/dialogs/user_detail_dialog.dart |
| 창고 | lib/features/masters/warehouse/presentation/dialogs/warehouse_detail_dialog.dart |
※
SuperportDetailDialog자체(lib/widgets/components/superport_detail_dialog.dart)를 공통으로 수정해야 하므로 목록에 포함.
3. 목표 UX
- 정보1(상단 summary+metadata)에서 모든 읽기 전용 필드를 완결성 있게 노출한다.
- 정보2(탭 영역)는 액션 중심(수정/삭제/히스토리 등)으로 단순화한다.
- 동일 필드는 단 한 곳(정보1)에만 표시되도록 하여 중복을 제거한다.
4. 단계별 플랜
4.1 구조 파악 & 정리
- 대상 다이얼로그마다 현재 summary/metadata/overview에 배치된 필드를 표로 정리한다.
- 중복 필드, 정보1에 반드시 남겨야 할 핵심 필드(이름, 코드, 상태, 타임스탬프 등)를 분류한다.
- 추가 데이터 소스 유무 확인(현행은 단일 엔티티 전달 → 별도 API 불필요).
4.1.1 필드 배치 매핑
| 팝업 | Summary 필드 | Metadata 필드 | Overview/기타 섹션 필드 | 중복 & 정보1 핵심 정리 |
|---|---|---|---|---|
| 결재 템플릿 | 템플릿명 설명 |
ID 코드 생성일시 변경일시 비고 |
템플릿명 코드 설명 사용 여부 생성일시 변경일시 비고 |
중복: 이름/코드/설명/타임스탬프/비고. 핵심: summary=템플릿명·설명 유지, metadata=ID/코드/생성·변경/비고, 사용 여부는 summaryBadges에 집중. |
| 결재 단계 | 단계 순번 승인자 이름+사번 비고 |
결재 ID 트랜잭션번호 템플릿명 승인자 사번 배정일시 결정일시 |
단계 순서 승인자 이름 승인자 사번 상태 배정/결정일시 비고 |
중복: 승인자 사번·배정/결정 시각·비고. 핵심: summary=단계 제목+승인자, metadata=결재/템플릿 식별자+승인자 사번+상태+배정/결정/비고로 통합. |
| 벤더 | 벤더명 벤더코드 |
ID 생성일시 변경일시 비고 |
벤더코드 벤더명 사용 여부 삭제 여부 비고 생성/변경일시 |
중복: 코드·이름·비고·타임스탬프. 핵심: summary=벤더명·코드, metadata=ID/코드/생성·변경/비고와 사용·삭제 상태(배지 또는 metadata)만 유지. |
| 그룹 | 그룹명 설명 |
ID 생성일시 변경일시 비고 |
그룹명 설명 기본 여부 사용 여부 삭제 여부 비고 생성/변경일시 |
중복: 그룹명·설명·비고·타임스탬프. 핵심: summary=그룹명·설명, metadata=ID/상태/타임스탬프/비고, 기본 여부는 metadata로 이동. |
| 그룹 권한 | 그룹명 → 메뉴명 | ID 메뉴 경로 비고 생성일시 변경일시 |
그룹 메뉴 경로 CRUD 권한 4종 사용 여부 삭제 여부 비고 생성/변경일시 |
중복: 경로·비고·타임스탬프. 핵심: summary=그룹/메뉴 페어, metadata=ID/경로/CRUD 권한/상태/비고/타임스탬프, 삭제 시 배지. |
| 고객사 | 고객사명 고객코드 |
ID 담당자 연락처 이메일 생성일시 수정일시 |
고객코드 유형(파트너/일반) 사용/삭제 여부 담당자 연락처 이메일 우편번호 주소 비고 생성/수정일시 |
중복: 담당자·연락처·이메일·타임스탬프. 핵심: summary=이름·코드, metadata=ID/유형/담당·연락·이메일/주소/상태/타임스탬프/비고. |
| 메뉴 | 메뉴명 경로 |
ID 메뉴코드 표시순서 비고 생성일시 변경일시 |
메뉴코드 메뉴명 상위메뉴 경로 표시순서 사용 여부 삭제 여부 비고 생성/변경일시 |
중복: 코드·경로·표시순서·비고·타임스탬프. 핵심: summary=메뉴명+경로, metadata=ID/코드/상위/표시순서/상태/타임스탬프/비고. |
| 제품 | 제품명 제품코드 |
ID 제조사 단위 생성일시 변경일시 비고 |
기본 정보: 제품코드·제품명·사용/삭제 여부·비고·생성/변경일시 관계 섹션: 제조사·단위 히스토리 섹션: 안내 문구 |
중복: 제조사/단위, 비고, 타임스탬프. 핵심: summary=이름·코드, metadata=ID/제조사/단위/상태/타임스탬프/비고, 관계 섹션은 액션/링크 중심으로 축소. |
| 사용자 | 직원명 사번 |
ID 그룹 이메일 연락처 비고 비밀번호 변경일시 생성/수정일시 |
개요: 사번·이메일·연락처·그룹·사용/삭제 여부·비고·생성/수정일시 보안 섹션: 비밀번호 변경일시·강제 변경 여부 |
중복: 이메일·연락처·그룹·비고·타임스탬프·비밀번호 변경일시. 핵심: summary=직원명·사번, metadata=ID/그룹/연락처/이메일/비고/비밀번호 정보/상태/타임스탬프. |
| 창고 | 창고명 창고코드 |
ID 우편번호 기본주소 상세주소 생성일시 변경일시 비고 |
기본 정보: 창고코드·창고명·사용/삭제 여부·비고·생성/변경일시 주소 섹션: 우편번호·주소·상세주소 |
중복: 주소 3종·타임스탬프·비고. 핵심: summary=이름·코드, metadata=ID/주소/상태/타임스탬프/비고, 별도 주소 섹션은 지도/편집 가이드를 위한 설명만 남김. |
- 모든 상세 다이얼로그가 단일 엔티티를 인자로 전달받고 있으며, 별도의 추가 API 호출이나 비동기 데이터 로딩 없이 summary/metadata/overview를 구성한다. 따라서 정보1에 필드를 통합할 때도 데이터 소스 확장이 필요 없다.
- 공통 컴포넌트
SuperportDetailDialog는 summary·metadata·섹션을 세로로 쌓는 단일 레이아웃으로, 현재 1열_MetadataTable만 지원한다. 고객/창고처럼 필드가 10개 이상인 경우 스크롤이 길어지므로 2열화 또는 그룹 헤더 도입 필요성이 확인됐다.
4.2 공통 레이아웃 개편안 확정
SuperportDetailDialog에서 summary/metadata 블록이 “정보1”로 인지되도록 레이아웃/간격/구분선을 다듬는다.- metadata를 2열 테이블 또는 Grid로 확장해 더 많은 필드를 수용할 수 있도록 옵션 검토.
- 탭 섹션에는 개요를 제외하고, 폼·위험 액션·히스토리 등 행위 중심 요소만 남기는 가이드 작성.
4.2.1 닫기 인터랙션 정리
- 상세보기 계열 팝업은 기본적으로 세 가지 닫기 방식을 제공한다.
- 팝업 우상단의 X 버튼
- 팝업 바깥 영역 클릭(barrier dismissible)
- 팝업 우하단 액션 영역의 “닫기” 버튼
- 3번 “닫기” 버튼은 X 버튼과 동일한 동작을 반복해서 정보 과밀감을 유발하므로 UI에서 제거한다. 필요 시 개별 화면에서만 액션 버튼을 추가하도록 하고, 공통 다이얼로그에서는 닫기 버튼을 렌더링하지 않는다.
4.2.2 정보1 레이아웃 스펙
SuperportDetailDialog상단 영역을infoPanel(summary + metadata)로 묶어ShadCard스타일로 렌더링한다. 좌우/상하 여백을 통일해 summary/metadata가 하나의 덩어리(정보1)로 인지되도록 했다.- summary 영역은 기존
summary슬롯을 그대로 사용하며, 대표 타이틀/보조 텍스트 → 배지 순의 수직 스택을 유지한다. summary/metadata 사이 여백은 카드 내부에서만 관리해 섹션과 시각적으로 분리된다. - metadata는
_MetadataGrid로 교체해 2열 레이아웃을 기본값(metadataColumns = 2)으로 제공한다. 가로폭이 520px 미만이거나 열 수가 항목 수보다 많으면 자동으로 1열로 접어 UX를 보장한다. - metadata 항목은 라벨/아이콘/값이 세로 정렬된 카드 타일로 렌더링되며, 값 영역은
Widget그대로 머지되어 텍스트·뱃지·아이콘 등 자유로운 구성을 유지한다. infoPanelPadding파라미터를 추가해 summary+metadata 블록과 탭 섹션 사이 간격을 한 번에 조절할 수 있도록 했고,metadataColumns파라미터로 팝업 별 열 수 튜닝도 가능하다.
4.2.3 탭 구성 가이드
- 탭 영역은 “행위 중심 정보2”로 재정의한다. 읽기 전용 필드는 summary/metadata에 모두 흡수하고, 탭에는 폼, 수정/위험 액션, 히스토리, 관계 관리 등 상호작용성 있는 콘텐츠만 남긴다.
SuperportDetailDialogSection에 overview 전용 빌더를 남겨두지 않고, 각 다이얼로그는_OverviewSection파일을 제거하면서 해당 필드를metadata리스트로 옮긴다.- 탭이 한 개만 남는 경우 자동으로 단일 패널 모드로 전환되므로, 최소 “폼/위험/히스토리” 중 필요한 섹션만 남겨도 된다. 이때
initialSectionId는 남은 섹션 ID 중 하나로 업데이트한다.
4.3 다이얼로그별 코드 수정
- 각 다이얼로그에서
_OverviewSection(읽기 전용)을 제거하고 해당 필드를 metadata 배열로 이동. - summary에는 대표 타이틀/보조 텍스트만 남기고 상태 배지는
summaryBadges로 유지. - 탭 목록에서 제거된 섹션을 반영하여 ID 상수·초기 선택 로직을 정리.
- 필요 시 metadata 행 구성을 위한 헬퍼(예:
_KeyValueRow)를 공통 유틸로 승격하거나 삭제.
4.3 진행 현황
- 결재 템플릿 팝업:
_TemplateOverviewSection제거, metadata에 상태/코드/타임스탬프/비고를 통합하고 초기 탭을steps로 변경했다._KeyValueRow유틸은 더 이상 사용하지 않아 삭제 완료. - 결재 단계 팝업:
_ApprovalStepOverviewSection제거, 단계 순서·승인자·상태·배정/결정일시·비고를 metadata로 이동하고 탭은 수정/삭제(복구)만 남겼다. 권한에 따라 섹션이 없을 수 있으므로 info panel만으로도 정보가 완결된다. - 벤더 팝업:
_VendorOverviewSection과_KeyValueRow삭제, ID/코드/상태/삭제 상태/타임스탬프/비고를 metadata로 통합하고 summary에는 이름만 남겼다. 초기 탭은 생성/수정으로 변경되어 정보1+액션 분리가 완료됐다. - 그룹 팝업:
_GroupOverviewSection제거, 기본 여부/사용·삭제 여부/타임스탬프/비고를 metadata로 이동했으며 summary는 이름·설명만 유지한다. 탭은 등록/수정과 삭제/복구만 남겨 행위 중심 구조를 맞췄다. - 그룹 권한 팝업:
_GroupPermissionOverviewSection을 삭제하고 그룹/메뉴/경로/CRUD 권한/상태/삭제 여부/노트/타임스탬프를 metadata에 넣었다. summary에는그룹 → 메뉴만 남기고 탭은 수정, 삭제/복구(또는 등록)만 유지한다. - 고객사 팝업:
_CustomerOverviewSection제거, 고객 코드/유형/연락처/주소/상태/삭제 여부/타임스탬프/비고를 metadata로 통합하고 summary는 이름만 남겼다. 탭은 등록/수정+삭제/복구만 유지해 정보1과 액션을 분리했다. - 제품 팝업:
_ProductOverviewSection제거, 제품 코드/상태/삭제 여부/제조사/단위/비고/타임스탬프를 metadata로 이동하고 summary에는 제품명만 남겼다. 탭은 연결 관계·히스토리(행위 가이드)와 등록/수정·삭제/복구만 남도록 조정했다. - 창고 팝업:
_WarehouseOverviewSection/_WarehouseAddressSection삭제, ID/창고코드/상태/삭제 여부/주소/비고/타임스탬프를 metadata로 결합했고 탭은 등록·수정과 삭제/복구만 남겼다. 상세 모드 초기 탭을edit으로 지정해 정보1과 행위 영역이 명확히 구분된다. - 재고 입출고/대여 팝업: 재고 상세 공통 다이얼로그를
SuperportDetailDialog로 교체하고 입고/출고/대여 레코드의 상태·창고·금액/수량·반납 예정일을 metadata로 옮겼다. 탭은 라인 품목(고객/관계 포함)만 남겨 info1과 행위 영역이 분리되었다. - 나머지 결재/마스터 팝업: 동일한 패턴으로 순차 대응 예정.
4.4 검증 & 테스트
- 기존 위젯 테스트 업데이트: overview 탭 삭제, metadata 렌더링 검증 등.
- 신규 테스트 케이스 추가: summary+metadata에 필드가 모두 나타나는지, 탭이 최소 한 개만 남았을 때 동작하는지 확인.
flutter analyze,flutter test전 프로젝트 실행.- 스타일 변경 시 주요 화면 캡처를 남겨 리뷰 참고자료로 사용.
5. 예상 산출물
- 수정된 상세 다이얼로그 10여 개 및 공통 컴포넌트 1개.
- 테스트 업데이트(다이얼로그 위젯 테스트 최소 1개 이상).
- 필요 시 설계 문서(본 문서 갱신 포함) 및 회고 노트.
6. 리스크 및 대응
| 리스크 | 대응 |
|---|---|
| metadata 영역에 필드가 많아져 가독성 저하 | 2열 레이아웃, 섹션 헤더, collapse 등 UI 개선 옵션 검토 |
| 탭 제거로 인한 라우팅/초기 섹션 ID 로직 오류 | initialSectionId 사용 여부 재확인 및 단위 테스트 작성 |
| 테스트 스냅샷/Golden 미존재 시 회귀 미포착 | 주요 다이얼로그에 대한 Widget 테스트 보강 |
7. 이후 액션
- 4.1의 필드 매핑 표를 작성해 본 문서를 업데이트.
- 공통 레이아웃 확정 후 시놉시스/디자인 확인.
- 다이얼로그-by-다이얼로그로 리팩토링 진행, 각 단계 완료 시 테스트/리포트 공유.