표준프로세스 화면 Ant Design 리팩토링 기록
작성 시각: 2026-09-12 범위: 사용자 표준프로세스 화면과 관리자 프로세스 관리 화면, 그리고 이를 지탱하는 공용 UI(portal-foundation) 적용
1. 목표와 결과
기능이 거의 같은 두 화면(관리자 "프로세스 관리", 사용자 "표준프로세스")을 단일 소스로 합치고, 화면 전체를 Ant Design 기반 공용 컴포넌트로 전환했다.
| 화면 요소 | 적용한 공용 컴포넌트 |
|---|---|
| 셸·사이드바·상단바 | PortalShell / PortalAdminShell (portal-foundation, Ant Design Layout·Menu) |
| 좌측 트리 | PortalTree(Ant Design Tree) + PortalTextField(검색) + PortalEmptyState |
| 상세 식별정보·RACI | PortalDescriptions(Ant Design Descriptions) |
| 상세 액션 툴바 | PortalButton(Ant Design Button) + PortalTooltip + PortalConfirm(Popconfirm) |
| 단계별 개수 카드 | PortalMetricGrid(Ant Design Card·Statistic + CSS Grid auto-fit) — **레벨명(레벨)**과 등록 갯수만 표시하고, 컨테이너 폭에 맞춰 한 줄로 꽉 차게 배치 |
| 변경 이력 | DataListShell(Ant Design Table·Empty·Spin) + PortalTabs |
| 상태바 | PortalToolbar |
| 첨부파일 | AssetAttachmentList(Ant Design List·Empty·Button) — 인증된 blob 다운로드는 onDownload로 연결 |
| 편집 Dialog | PortalDialog(Ant Design Modal) + PortalSelect/PortalTextField/PortalTextArea/PortalMultiSelect |
| 로딩·오류 안내 | PortalLoadingState(Spin) / PortalErrorState(Alert) |
| 지연 로딩 화면 | Suspense + PortalLoadingState |
2. 구조 변경
ProcessManagementPanel이variant: "admin" | "portal"를 받아 두 화면을 모두 담당한다.admin: 등록·수정·삭제·순서 이동·일괄 등록·편집 첨부 등 전체 편집 기능.portal: 같은 트리·상세·첨부·L4/L5 맵을 조회 전용으로 사용하고, 포털 전용 요소(단계 카드·상태바·변경 이력)만 추가로 렌더한다.
- 포털 전용이던 인라인 구현(
ProcessTreeNode, 중복 상세 마크업, dead handler)은 제거했다. Home.tsx는PortalShell과 검색 placeholder만 책임지고, 프로세스 화면은 공용 패널에 위임한다.
3. 제거한 레거시
- Radix UI 의존(프로세스 관리 화면):
ui/dialog,ui/select,ui/popover,ui/label,ui/input,ui/textarea. - 죽은 컴포넌트:
process/ProcessFormDialog,process/ProcessRaciUserPicker,HierarchyMap(+test),WorkflowEntityModelMockup,ManusDialog,Map,pages/ComponentShowcase,pages/NotFound. - 죽은 스타일:
index.css의process-stage-card*, 레거시auth-*,.portal-readonly편집 버튼 숨김(:has) 해킹,.manual-view(총 148줄). navy-theme.css는 감사 결과 거의 모든 선택자가 사용 중이어서 유지했다(다크 모드 회귀 방지).
4. 공용 패키지 변경(portal-foundation)
| 버전 | 내용 |
|---|---|
| 0.6.132 | 내부 상태 패널을 Ant Design Spin·Alert로 교체, PortalDescriptions 추가 |
| 0.6.133 | PortalMetricGrid, PortalTooltip, PortalConfirm, PortalMultiSelect 추가, PortalSelect에 showSearch·loading |
| 0.6.134 ~ 0.6.137 | 공용 트리 선택 하이라이트 정렬(대칭 패딩·세로 중앙), 죽은 트리 스타일 제거, PortalButton variant 타입 수정 |
| 0.6.138 | AssetAttachmentList에 onDownload·downloadingId·deletingId·testId 추가 |
| 0.6.139 | PortalSelect에 placeholder·searchText(라벨 외 검색) 추가, PortalCheckbox 추가 |
| 0.6.140 | PortalMetricGrid를 Ant Design Row·Col 반응형 배치로 교체(기본 2/3/4개, responsive prop) + 카드 높이·제목 클램프 CSS |
| 0.6.141 | 지표 카드를 컴팩트하게 조정(카드 본문 패딩 10/12px, 수치 20px) — 좁은 카드에서도 제목·수치 정렬 유지 |
| 0.6.142 | PortalMetricGrid에 minColumnWidth 유연 배치 추가(CSS Grid auto-fit) — 한 줄을 꽉 채우고 좁아지면 자동 줄바꿈 |
| 0.6.143 | 지표 카드 제목을 한 줄 고정(nowrap + 말줄임)하고 11px·좌우 패딩 10px·간격 10px로 조정해 "Function Group (L3)" 같은 긴 라벨도 한 줄에 표시 |
| 0.6.144 | 카드 좌우 패딩 8px·유연 배치 간격 8px로 축소 — 7개 카드가 한 줄이 되는 최소 컨테이너 폭을 약 1040px → 약 1000px로 낮춰 1280 해상도에서도 한 줄 유지 |
| 0.6.145 | 지표 그리드에 data-pf-metric-layout(fluid/fixed/responsive) 표식 추가, PORTAL_FOUNDATION_VERSION(빌드 시 실제 버전으로 치환) 추가 — 실행 중인 공용 UI 버전·레이아웃을 DOM에서 확인 |
| 0.6.146 | AssetAttachmentList의 다운로드·삭제를 아이콘 전용(툴팁 유지)으로 전환 |
| 0.6.147 | 레거시 .pf-button 박스 스타일을 :not(.ant-btn)으로 스코프하고 아이콘 전용 컴팩트 규칙 추가 |
| 0.6.150 | 팝업 레이어 규칙을 foundation이 소유 — PortalDialog가 시맨틱 슬롯(pf-dialog__container/header/title/content/close)로 제목 바(배경은 Ant Design component token Modal.headerBg = var(--pf-accent-soft) — 메뉴 상단바와 같은 accent 계열, 하단 구분선·20px 제목·12px 설명)와 본문 인셋(20/24px)을 정의한다. 제목·설명은 제목 바 안에 배치하고, 포털 앱의 팝업 CSS 오버라이드는 제거 |
| 0.6.152 | 첨부파일 목록(AssetAttachmentList)을 foundation 규칙으로 정리 — 빈 상태에서 antd Empty 아이콘(이미지 100px)을 제거하고 12px 담백한 텍스트로 표시해 노드 상세의 첨부 영역이 과도하게 길어지던 문제를 해결(상세내용 빈 상태와 같은 처리) |
5. 후속 갭 처리
→ 0.6.139에서PortalSelect에placeholderprop이 없어 조직 선택 안내 문구를 표시하지 못함placeholder추가로 해결.RACI 검색이 이름 기준→ 0.6.139의searchText로 이름·이메일·부서를 함께 검색한다.역할자 배정이 네이티브→input[type=checkbox]PortalCheckbox(Ant Design Checkbox)로 전환.ManualEditor(Tiptap)는 Ant Design 대응물이 없어 의도적으로 유지한다.
6. 검증
bash
pnpm check # tsc --noEmit
pnpm build # vite build + esbuild
pnpm test # vitest (Home·ProcessManagementPanel·AdminProcessTree 등)Home.test.tsx: 15/15 통과 (셸 계약 라벨 드리프트 9건 복구)ProcessManagementPanel.test.tsx+AdminProcessTree.test.tsx: 4/4 통과- 위 3개 파일 기준 19/19 통과,
pnpm check·pnpm build0 - 전체 스위트에는 이번 작업 이전부터 존재하던 실패(워크플로우·디렉터리 일부)가 남아 있다.
7. 남은 작업
- 1920×1080 라이트·다크 시각 검증(단계 카드·이력 표·첨부 목록·편집 폼은 Ant Design 렌더링으로 모양이 바뀐다).
- role checkboxes와 조직/RACI 검색 필드의 공용 컴포넌트 확장.
- 릴리스:
portal-foundation태그v0.6.138, 앱 태그v1.0.5.
8. 빈 화면 신고 대응 (v1.0.7)
신고된 "프로세스센터 빈 화면"은 화면 코드의 렌더 크래시가 아니다. 최상위 ErrorBoundary가 App을 감싸고 있어 렌더 오류라면 오류 화면이 표시되고, 아래 두 테스트가 실제 컴포넌트로 포털 화면 전체를 렌더해 통과한다.
client/src/components/process/ProcessNodeAttachments.test.tsx: 실제AssetAttachmentList로 첨부 목록·다운로드·삭제 경로 검증(2/2).client/src/pages/Home.integration.test.tsx: 단계 카드·상태바·트리·상세·변경 이력·첨부를 모킹 없이 렌더(1/1).ProcessNodeAttachments.tsx재작성 시 빠졌던React기본 import를 복원했다(이 리포지토리의 모든.tsx는React를 명시적으로 import하는 관례를 따른다).- 진단 결과 vendor
0.6.139(dist/index.js익스포트 전수 확인, blob 126,990바이트)·락파일·CSS 브레이스(112/112)·빌드 산출물은 모두 정상이었다.
빈 화면은 앱이 마운트되기 전 단계(모듈 로드/초기화) 실패이므로 아래를 함께 반영했다.
client/index.html의#root에 부팅 폴백을 넣어, 실패 시 빈 화면 대신 오류 메시지와 새로고침 안내를 표시한다. React는 첫 마운트에서 컨테이너 자식을 지우므로(테스트로 확인) 정상 부팅 시 폴백은 사라진다.- 오래된 Vite 개발 캐시(
node_modules/.vite)를 제거했다. vendor 교체 후에는node_modules/.vite삭제 후 개발 서버를 재시작하는 것이 안전하다.