Files
pipeline/docs/ycshin-node/CTI[계획]-카테고리-깊이구분.md
T
syc0123 65026f14e4 docs: Add documentation for category dropdown depth separation
- Introduced new documents detailing the implementation of visual separation for three-level category dropdowns.
- Updated the `flattenTree` function in both `V2Select.tsx` and `UnifiedSelect.tsx` to use Non-Breaking Space (`\u00A0`) for indentation, ensuring proper visual hierarchy.
- Included a checklist to track the implementation progress and verification of the changes.
- Documented the rationale behind the changes, including the issues with HTML whitespace collapsing and the decisions made to enhance user experience.

These updates aim to improve the clarity and usability of the category selection interface in the application.
2026-03-11 15:53:01 +09:00

3.7 KiB

[계획서] 카테고리 드롭다운 - 3단계 깊이 구분 표시

관련 문서: 맥락노트 | 체크리스트

상태: 완료 (2026-03-11)

개요

카테고리 타입(source="category") 드롭다운에서 3단계 계층(대분류 > 중분류 > 소분류)의 들여쓰기가 시각적으로 구분되지 않는 문제를 수정합니다.


변경 전 동작

  • category_values 테이블은 parent_value_id, depth 컬럼으로 3단계 계층 구조를 지원
  • 백엔드 buildHierarchy()가 트리 구조를 정상적으로 반환
  • 프론트엔드 flattenTree()가 트리를 평탄화하면서 일반 ASCII 공백(" ") 으로 들여쓰기 생성
  • HTML이 연속 공백을 하나로 축소(collapse)하여 depth 1과 depth 2가 동일하게 렌더링됨

변경 전 코드 (flattenTree)

const prefix = depth > 0 ? "  ".repeat(depth) + "└ " : "";

변경 전 렌더링 결과

신예철
└ 신2
└ 신22    ← depth 2인데 depth 1과 구분 불가
└ 신3
└ 신4

변경 후 동작

일반 공백을 Non-Breaking Space(\u00A0)로 교체

  • \u00A0는 HTML에서 축소되지 않으므로 depth별 들여쓰기가 정확히 유지됨
  • depth당 3칸(\u00A0\u00A0\u00A0)으로 시각적 계층 구분을 명확히 함
  • 백엔드 변경 없음 (트리 구조는 이미 정상)

변경 후 코드 (flattenTree)

const prefix = depth > 0 ? "\u00A0\u00A0\u00A0".repeat(depth) + "└ " : "";

시각적 예시

depth prefix 드롭다운 표시
0 (대분류) "" 신예철
1 (중분류) "\u00A0\u00A0\u00A0└ " ···└ 신2
2 (소분류) "\u00A0\u00A0\u00A0\u00A0\u00A0\u00A0└ " ······└ 신22

변경 전후 비교

변경 전:                    변경 후:
신예철                      신예철
└ 신2                          └ 신2
└ 신22  ← 구분 불가                └ 신22  ← 명확히 구분
└ 신3                          └ 신3
└ 신4                          └ 신4

아키텍처

flowchart TD
    A[category_values 테이블] -->|parent_value_id, depth| B[백엔드 buildHierarchy]
    B -->|트리 JSON 응답| C[프론트엔드 API 호출]
    C --> D[flattenTree 함수]
    D -->|"depth별 \u00A0 prefix 생성"| E[SelectOption 배열]
    E --> F{렌더링 모드}
    F -->|비검색| G[SelectItem - label 표시]
    F -->|검색| H[CommandItem - displayLabel 표시]

    style D fill:#f96,stroke:#333,color:#000

변경 지점: flattenTree 함수 내 prefix 생성 로직 (주황색 표시)


변경 대상 파일

파일 경로 변경 내용 변경 규모
frontend/components/v2/V2Select.tsx (904행) flattenTree prefix를 \u00A0 기반으로 변경 1줄
frontend/components/unified/UnifiedSelect.tsx (632행) 동일한 flattenTree prefix 변경 1줄

영향받는 기존 로직

V2Select.tsx의 resolvedValue(979행)에서 prefix를 제거하는 정규식:

const cleanLabel = o.label.replace(/^[\s└]+/, "").trim();
  • JavaScript \s\u00A0를 포함하므로 기존 정규식이 정상 동작함
  • 추가 수정 불필요

설계 원칙

  • 백엔드 변경 없이 프론트엔드 표시 로직만 수정
  • flattenTree 공통 함수 수정이므로 카테고리 타입 드롭다운 전체에 자동 적용
  • DB 저장값(valueCode)에는 영향 없음 — label만 변경
  • 기존 prefix strip 정규식(/^[\s└]+/)과 호환 유지
  • V2SelectUnifiedSelect 두 곳의 동일 패턴을 일관되게 수정