Skip to content

표준프로세스 화면 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
상세 식별정보·RACIPortalDescriptions(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로 연결
편집 DialogPortalDialog(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.133PortalMetricGrid, PortalTooltip, PortalConfirm, PortalMultiSelect 추가, PortalSelect에 showSearch·loading
0.6.134 ~ 0.6.137공용 트리 선택 하이라이트 정렬(대칭 패딩·세로 중앙), 죽은 트리 스타일 제거, PortalButton variant 타입 수정
0.6.138AssetAttachmentList에 onDownload·downloadingId·deletingId·testId 추가
0.6.139PortalSelect에 placeholder·searchText(라벨 외 검색) 추가, PortalCheckbox 추가
0.6.140PortalMetricGrid를 Ant Design Row·Col 반응형 배치로 교체(기본 2/3/4개, responsive prop) + 카드 높이·제목 클램프 CSS
0.6.141지표 카드를 컴팩트하게 조정(카드 본문 패딩 10/12px, 수치 20px) — 좁은 카드에서도 제목·수치 정렬 유지
0.6.142PortalMetricGrid에 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.146AssetAttachmentList의 다운로드·삭제를 아이콘 전용(툴팁 유지)으로 전환
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. 후속 갭 처리 ​

  1. PortalSelect에 placeholder prop이 없어 조직 선택 안내 문구를 표시하지 못함 → 0.6.139에서 placeholder 추가로 해결.
  2. RACI 검색이 이름 기준 → 0.6.139의 searchText로 이름·이메일·부서를 함께 검색한다.
  3. 역할자 배정이 네이티브 input[type=checkbox] → PortalCheckbox(Ant Design Checkbox)로 전환.
  4. 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 build 0
  • 전체 스위트에는 이번 작업 이전부터 존재하던 실패(워크플로우·디렉터리 일부)가 남아 있다.

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 삭제 후 개발 서버를 재시작하는 것이 안전하다.