doksam-ui
홈ProfilesTokensIconsComponentsPatternsTemplatesRules
Srope — 프로젝트 확장

파이프라인 UI 패턴

srope 프로젝트의 크롤러/분석 파이프라인 관리 화면에서 반복되는 UI 패턴을 doksam-ui 표준 컴포넌트와 시맨틱 토큰으로 재작성한 모음입니다. 실행 상태(Running/Success/Failed/Stopped)는 chart-1 · success · destructive · warning 토큰 조합으로 라이트/다크 모드를 모두 지원합니다.

#33

스텝 플로우

번호 + 화살표 + 상태 아이콘 + 진행률 바.

조간 리포트 파이프라인
시세수집
→
뉴스수집
→
NLP분석
→
리포트생성
→
PDF렌더

Step 3/5: NLP분석

function StepIcon({ status }: { status: StepStatus }) {
  if (status === "done") return <CheckCircleIcon weight="fill" className="text-success" />
  if (status === "running") return <SpinnerGapIcon className="animate-spin text-chart-1" />
  if (status === "error") return <XCircleIcon weight="fill" className="text-destructive" />
  return <CircleIcon className="text-muted-foreground" />
}

<Progress value={progress} />
  • 상태 아이콘: done=success, running=chart-1(회전), error=destructive, idle=muted-foreground.
  • 진행률은 components/ui/progress 를 그대로 사용한다.
#34

실행 상태 배지

Running/Success/Failed/Stopped 4종 — 시맨틱 토큰으로 다크모드 자동 대응.

RunningSuccessFailedStopped
const STATUSES = [
  { status: "Running", className: "border-chart-1/30 bg-chart-1/10 text-chart-1" },
  { status: "Success", className: "border-success/30 bg-success/10 text-success" },
  { status: "Failed", className: "border-destructive/30 bg-destructive/10 text-destructive" },
  { status: "Stopped", className: "border-warning/30 bg-warning/10 text-warning" },
]
  • 라이트/다크 각각 다른 bg-{color}-100/900 하드코딩 대신 {token}/10 opacity 조합 하나로 양쪽을 모두 만족시킨다.
  • Running 은 SpinnerGapIcon 에 animate-spin 을 적용해 진행 중임을 표시한다.
#35

툴팁 액션 버튼

모든 아이콘 전용 버튼에 Tooltip 필수 — 접근성 라벨 겸용.

아이콘 버튼 (h-7 w-7)

테이블 행 액션 (h-6 w-6)

삼성전자 005930

텍스트 + 아이콘 버튼

<Tooltip>
  <TooltipTrigger asChild>
    <Button variant="ghost" size="icon" className="h-7 w-7" aria-label="수정">
      <PencilSimpleIcon size={14} />
    </Button>
  </TooltipTrigger>
  <TooltipContent>수정</TooltipContent>
</Tooltip>
  • 아이콘 전용 버튼은 크기와 무관하게 항상 aria-label 을 채운다(Tooltip 텍스트와 동일 값).
  • TooltipProvider 는 섹션(또는 페이지) 최상위에서 한 번만 감싼다 — delayDuration 기본값 0.
#36

스텝 카드 그리드

카테고리 배지 + 카테고리별 스텝 카드, 상태별 아이콘/에러 메시지.

크롤러(4)분석(3)렌더링(2)
시세 수집

네이버 API로 종목 현재가 수집

2.3s · 1,282건

뉴스 수집

네이버 뉴스 API 크롤링

5.1s · 45건

유튜브 수집

유튜브 채널 최신 영상 수집

API timeout

NLP 분석

뉴스 감성분석 + 키워드 추출

function statusIcon(status: StepStatus) {
  if (status === "done") return <CheckCircleIcon weight="fill" className="text-success" />
  if (status === "running") return <SpinnerGapIcon className="animate-spin text-chart-1" />
  if (status === "error") return <XCircleIcon weight="fill" className="text-destructive" />
  return null
}
  • 에러 상태는 elapsed/count 대신 errorMessage 를 text-destructive 로 노출한다.
  • 카테고리 배지는 첫 번째만 default, 나머지는 secondary — 활성 카테고리 강조 관례를 유지한다.
#37

수집 이력 테이블

상태별 행 하이라이팅 + 체크박스 일괄선택 + 인라인 Tooltip 액션.

#상태대상날짜수집필터스킵소요액션
1success2026-04-08125302.3s
2running2026-04-0845101.2s
3failed2026-04-070000.5s
4success2026-04-07130523.1s
5stopped2026-04-0680201.8s
function rowHighlightClass(status: RunStatus) {
  if (status === "running") return "bg-chart-1/5"
  if (status === "failed") return "bg-destructive/5"
  return ""
}
// 수치 색상: inserted=text-success, filtered=text-chart-1, skipped=text-destructive
  • 행 배경은 상태 강조용으로만 옅게(opacity 5%) 사용하고 본문 텍스트 대비를 해치지 않는다.
  • sticky 헤더 + ScrollArea 로 긴 이력 목록도 헤더가 고정되도록 한다.
#38

스텝 결과 리스트

순번 + 스텝명 + 건수 + 소요시간, 하단 자동 합산.

1시세수집1,282건2.3s
2뉴스수집156건5.7s
3NLP분석156건12.1s
4시그널생성62건1.8s
5리포트생성1건3.4s
총 소요시간25.3s
const TOTAL_ELAPSED = RESULTS.reduce((sum, item) => sum + item.elapsed, 0)
// order, label, count, elapsed(초) 만으로 리스트 + 하단 합산 행을 렌더링
  • 총 소요시간은 items.reduce 로 자동 계산하고 별도 prop 으로 전달하지 않는다.
  • 각 행은 성공 아이콘 고정 — 실패/진행중 표시가 필요하면 #34 StatusBadge 패턴을 함께 사용한다.
#39

고급 데이터 테이블

필터 + 정렬 헤더 + 일괄 선택 + 페이징 — 목록 화면 표준 툴바.

3건 선택
카테고리수량상태등록일액션
뉴스 크롤러수집1,250활성04-01
감성 분석기분석890활성04-02
PDF 렌더러출력32비활성03-28
시세 수집기수집4,100활성04-05
1-4 / 128건
1 / 32
<Checkbox aria-label="전체 선택" />
<button className="flex items-center gap-0.5">
  이름 <SortAscendingIcon size={10} />
</button>
<Badge variant={row.status === "active" ? "default" : "secondary"}>
  {row.status === "active" ? "활성" : "비활성"}
</Badge>
  • 일괄 액션(삭제·내보내기)은 선택된 건수와 함께 툴바 좌측에, 필터·새로고침은 우측에 배치한다.
  • 페이징은 이전/다음 버튼 + 현재 페이지만 노출하는 간단한 형태를 기본으로 한다.
#40

에러 카드 + 실행 로그

실패/경고 알림 카드와 최근 실행 이력 리스트.

실행 실패

Step 3 (NLP분석)에서 오류 발생: API rate limit exceeded. 5분 후 재시도하세요.

경고

3건의 종목 데이터가 누락되었습니다. 부분 완료 상태입니다.

실행 이력
04-08 09:41Step 3/3: 조간 리포트scheduler
04-08 09:35Step 2/3: 뉴스 수집admintimeout
04-07 15:42Step 5/5: 석간 리포트scheduler
04-07 09:40Step 3/3: 조간 리포트scheduler
04-06 15:41Step 5/5: 석간 리포트scheduler
<Card className="border-destructive/50 bg-destructive/5">
  <XCircleIcon className="text-destructive" />
</Card>
<Card className="border-warning/50 bg-warning/5">
  <WarningCircleIcon className="text-warning" />
</Card>
  • 에러 카드는 border+bg 를 같은 토큰의 옅은 버전으로 맞춰(destructive/warning) 카드 자체가 상태를 말하게 한다.
  • 로그 리스트는 실패 항목에만 에러 사유를 truncate 로 짧게 덧붙인다.