# Labeling Workflow UI Documentation

## Overview

`@things-factory/labeling` 패키지는 레이블링 워크플로우를 시각적으로 생성, 편집, 관리할 수 있는 범용 UI 컴포넌트를 제공합니다.

## Components

### 1. Workflow List Page (`workflow-list.ts`)

워크플로우 목록을 카드 형태로 표시하고 CRUD 작업을 수행하는 페이지입니다.

#### Features

- **Grid Layout**: 반응형 그리드로 워크플로우 카드 표시
- **Status Indicators**: 색상별 상태 표시
  - Green (Active): 활성 워크플로우
  - Gray (Draft): 초안 상태
  - Orange (Paused): 일시정지
  - Blue (Completed): 완료
  - Red (Failed): 실패
- **Filtering**: 상태 및 프로젝트 ID로 필터링
- **Actions**:
  - Create: 새 워크플로우 생성
  - Edit: 워크플로우 편집
  - Execute: 워크플로우 실행
  - Pause/Resume: 실행 제어
  - Delete: 워크플로우 삭제

#### Usage

```typescript
import '@things-factory/labeling/dist-client/pages/workflow-list'

// HTML에서 사용
<workflow-list-page></workflow-list-page>
```

#### GraphQL Queries Used

```graphql
# 워크플로우 목록 조회
query GetWorkflows($projectId: Int) {
  labelingWorkflows(projectId: $projectId) {
    items {
      id
      name
      description
      projectId
      status
      triggerType
      steps { name type }
      createdAt
      lastExecutedAt
    }
  }
}

# 워크플로우 실행
mutation ExecuteWorkflow($workflowId: String!) {
  executeLabelingWorkflow(input: { workflowId: $workflowId }) {
    executionId
    status
    summary
  }
}

# 워크플로우 일시정지
mutation PauseWorkflow($workflowId: String!) {
  pauseLabelingWorkflow(workflowId: $workflowId) {
    id
    status
  }
}

# 워크플로우 재개
mutation ResumeWorkflow($workflowId: String!) {
  resumeLabelingWorkflow(workflowId: $workflowId) {
    id
    status
  }
}

# 워크플로우 삭제
mutation DeleteWorkflow($workflowId: String!) {
  deleteLabelingWorkflow(workflowId: $workflowId)
}
```

### 2. Workflow Builder Page (`workflow-builder.ts`)

워크플로우를 생성하거나 편집하는 인터랙티브 빌더 페이지입니다.

#### Features

**Layout**:
- **Sidebar (Left)**: 워크플로우 기본 정보 및 스텝 목록
- **Main Area (Right)**: 선택된 스텝의 상세 설정

**Workflow Settings (Sidebar)**:
- Name: 워크플로우 이름 (필수)
- Description: 설명
- Project ID: Label Studio 프로젝트 ID (필수)
- Trigger Type: Manual/Scheduled/Event-based
- Auto Start: 생성 후 자동 시작 여부

**Step Management**:
- Add Step: 새 스텝 추가
- Reorder: 스텝 순서 변경 (↑↓ 버튼)
- Delete: 스텝 삭제 (× 버튼)
- Select: 스텝 클릭으로 편집

**Step Editor (Main Area)**:
- Step Name: 스텝 이름
- Step Type: 스텝 유형 선택
  - `import_data`: 데이터 가져오기
  - `generate_predictions`: AI 예측 생성
  - `wait_for_annotations`: 수동 레이블링 대기
  - `sync_annotations`: 레이블 동기화
  - `validate_quality`: 품질 검증
  - `export_results`: 결과 내보내기
  - `notification`: 알림 전송
- Configuration: JSON 형식의 스텝 설정
- Continue on Error: 에러 발생 시 계속 진행 여부

#### Usage

**Creating New Workflow**:
```typescript
import '@things-factory/labeling/dist-client/pages/workflow-builder'

// 새 워크플로우 생성
<workflow-builder-page></workflow-builder-page>
```

**Editing Existing Workflow**:
```typescript
// 기존 워크플로우 편집
<workflow-builder-page workflowId="workflow-uuid"></workflow-builder-page>
```

#### GraphQL Mutations Used

```graphql
# 워크플로우 생성
mutation CreateWorkflow($input: CreateWorkflowRequest!) {
  createLabelingWorkflow(input: $input) {
    id
    name
  }
}

# 워크플로우 업데이트
mutation UpdateWorkflow($workflowId: String!, $input: UpdateWorkflowRequest!) {
  updateLabelingWorkflow(workflowId: $workflowId, input: $input) {
    id
    name
  }
}

# 워크플로우 상세 조회 (편집 모드)
query GetWorkflow($workflowId: String!) {
  labelingWorkflow(workflowId: $workflowId) {
    id
    name
    description
    projectId
    triggerType
    triggerConfig
    steps {
      name
      type
      order
      config
      continueOnError
    }
    status
    autoStart
  }
}
```

## Route Configuration

```typescript
// packages/labeling/client/route.ts
export default function route(page: string) {
  switch (page) {
    case 'workflows':
      import('./pages/workflow-list')
      return page

    case 'workflow-builder':
      import('./pages/workflow-builder')
      return page
  }
}
```

### URL Patterns

- `/workflows` - 워크플로우 목록
- `/workflow-builder` - 새 워크플로우 생성
- `/workflow-builder/{workflowId}` - 기존 워크플로우 편집

## Menu Configuration

```typescript
// packages/labeling/client/menu.ts
import i18next from 'i18next'

export function getMenuTemplate(owner: boolean = false) {
  return [
    {
      name: 'LABELING WORKFLOWS',
      type: 'group'
    },
    {
      name: i18next.t('title.workflows'),
      icon: 'account_tree',
      path: 'workflows',
      description: 'Manage labeling workflows'
    },
    owner && {
      name: i18next.t('title.create workflow'),
      icon: 'add_circle',
      path: 'workflow-builder',
      description: 'Create new labeling workflow'
    }
  ].filter(Boolean)
}
```

## Step Type Configuration Examples

### Import Data Step

```json
{
  "sourceType": "dataset",
  "dataSetId": "my-dataset-uuid",
  "imageField": "image",
  "limit": 1000
}
```

### Generate Predictions Step

```json
{
  "modelId": "resnet50-v2",
  "confidenceThreshold": 0.7,
  "forceRegenerate": false
}
```

### Wait for Annotations Step

```json
{
  "minCompletionRate": 0.9,
  "autoProceed": false
}
```

### Sync Annotations Step

```json
{
  "completedOnly": true,
  "targetDataSet": "my-dataset-uuid"
}
```

### Validate Quality Step

```json
{
  "minQualityScore": 0.8,
  "validationRules": ["consistency", "completeness"]
}
```

### Export Results Step

```json
{
  "format": "coco",
  "destination": "s3://my-bucket/exports/"
}
```

### Notification Step

```json
{
  "channels": ["email", "slack"],
  "recipients": ["admin@example.com"],
  "message": "Workflow completed successfully"
}
```

## Styling and Theming

UI 컴포넌트는 Material Design 3 테마 변수를 사용합니다:

```css
/* Primary colors */
--md-sys-color-primary
--md-sys-color-on-primary
--md-sys-color-primary-container
--md-sys-color-on-primary-container

/* Surface colors */
--md-sys-color-surface
--md-sys-color-on-surface
--md-sys-color-surface-variant
--md-sys-color-on-surface-variant

/* Outline */
--md-sys-color-outline

/* Secondary */
--md-sys-color-secondary
--md-sys-color-on-secondary
```

테마를 커스터마이징하려면 CSS 변수를 오버라이드하세요:

```css
:root {
  --md-sys-color-primary: #6750a4;
  --md-sys-color-on-primary: #ffffff;
}
```

## Integration with Other Packages

### Option 1: Direct Usage

다른 패키지에서 직접 사용:

```typescript
import '@things-factory/labeling/dist-client/pages/workflow-list'
import '@things-factory/labeling/dist-client/pages/workflow-builder'
```

### Option 2: Re-export with Customization

다른 패키지에서 래퍼 컴포넌트 생성:

```typescript
// packages/operato-dataset/client/pages/dataset-workflow-builder.ts
import { html } from 'lit'
import { customElement } from 'lit/decorators.js'
import '@things-factory/labeling/dist-client/pages/workflow-builder'

@customElement('dataset-workflow-builder')
export class DatasetWorkflowBuilder extends LitElement {
  render() {
    return html`
      <workflow-builder-page
        .presetConfig=${{
          triggerType: 'event',
          steps: [
            // DataSet-specific preset steps
          ]
        }}
      ></workflow-builder-page>
    `
  }
}
```

### Option 3: Menu Integration

다른 패키지의 메뉴에 통합:

```typescript
// packages/operato-dataset/client/menu.ts
import { getMenuTemplate as getLabelingMenu } from '@things-factory/labeling'

export function getMenuTemplate(owner: boolean, dataSets: any[]) {
  return [
    // ... other menu items
    ...getLabelingMenu(owner),
    // ... more menu items
  ]
}
```

## Best Practices

### 1. Validation

워크플로우 저장 전 검증:

```typescript
validateWorkflow(workflow: any): string[] {
  const errors: string[] = []

  if (!workflow.name) errors.push('Workflow name is required')
  if (!workflow.projectId) errors.push('Project ID is required')
  if (workflow.steps.length === 0) errors.push('At least one step is required')

  workflow.steps.forEach((step: any, index: number) => {
    if (!step.name) errors.push(`Step ${index + 1}: Name is required`)
    if (!step.type) errors.push(`Step ${index + 1}: Type is required`)

    try {
      JSON.parse(step.config)
    } catch (e) {
      errors.push(`Step ${index + 1}: Invalid JSON configuration`)
    }
  })

  return errors
}
```

### 2. Error Handling

사용자에게 명확한 에러 메시지 표시:

```typescript
async saveWorkflow() {
  try {
    const errors = this.validateWorkflow(this.workflow)
    if (errors.length > 0) {
      this.error = errors.join('\n')
      return
    }

    await client.mutate({ mutation, variables })
    alert('Workflow saved successfully!')
  } catch (error) {
    console.error('Failed to save workflow:', error)
    this.error = 'Failed to save workflow. Please check your inputs.'
  }
}
```

### 3. Loading States

긴 작업 중 로딩 상태 표시:

```typescript
async loadWorkflows() {
  this.loading = true
  try {
    const response = await client.query({ query })
    this.workflows = response.data.labelingWorkflows.items
  } finally {
    this.loading = false
  }
}
```

### 4. Navigation

페이지 간 이동:

```typescript
import { navigate } from '@operato/shell'

// 워크플로우 목록으로
navigate('workflows')

// 워크플로우 편집
navigate(`workflow-builder/${workflowId}`)

// 이전 페이지로
history.back()
```

## Accessibility

### Keyboard Navigation

- Tab: 폼 필드 간 이동
- Enter: 버튼 클릭, 폼 제출
- Escape: 다이얼로그 닫기
- Arrow keys: 스텝 목록 탐색

### Screen Readers

모든 인터랙티브 요소에 적절한 ARIA 레이블 제공:

```html
<button aria-label="Add new step">+ Add Step</button>
<input aria-label="Workflow name" placeholder="Enter workflow name" />
```

## Performance Optimization

### Lazy Loading

페이지 컴포넌트는 동적으로 임포트됩니다:

```typescript
// route.ts
case 'workflows':
  import('./pages/workflow-list')  // Lazy loaded
  return page
```

### Virtual Scrolling

많은 워크플로우를 표시할 때는 가상 스크롤링 고려:

```typescript
// 큰 리스트에 적용 (향후 개선 사항)
import { virtualScroll } from '@lit-labs/virtualizer'
```

## Troubleshooting

### Common Issues

**Issue 1: GraphQL Query Fails**
- **Solution**: GraphQL 서버 연결 확인, 쿼리 구문 검증

**Issue 2: Workflow Not Saving**
- **Solution**: JSON 설정 형식 확인, 필수 필드 입력 확인

**Issue 3: Step Configuration Error**
- **Solution**: config 필드가 유효한 JSON 문자열인지 확인

**Issue 4: Navigation Not Working**
- **Solution**: route.ts가 올바르게 설정되었는지, shell 패키지 임포트 확인

## Future Enhancements

### Planned Features

- [ ] Drag & Drop 스텝 재정렬
- [ ] 비주얼 워크플로우 다이어그램
- [ ] 스텝 템플릿 라이브러리
- [ ] 실시간 워크플로우 실행 모니터링
- [ ] 워크플로우 복제 기능
- [ ] 워크플로우 비교 도구
- [ ] 스텝별 설정 검증기
- [ ] 다국어 지원 확장
- [ ] 워크플로우 시뮬레이션 모드
- [ ] 조건부 분기 지원

## References

- [Lit Documentation](https://lit.dev/)
- [Material Design 3](https://m3.material.io/)
- [GraphQL Best Practices](https://graphql.org/learn/best-practices/)
- [Things-Factory Architecture](../../../docs/architecture.md)
