# Label Studio UI 커스터마이징 가이드

Things-Factory iframe에서 Label Studio UI를 커스터마이징하는 방법입니다.

> **기본 동작**: Things-Factory에서는 **항상 컨텐츠 전용 모드**로 Label Studio를 표시합니다.
> 헤더와 사이드바는 기본적으로 숨겨지며, 라벨링 영역만 표시됩니다.

---

## 🎨 UI 요소 제어

Label Studio는 `interfaces` 쿼리 파라미터를 통해 표시할 UI 요소를 제어할 수 있습니다.

### interfaces 파라미터

URL에 `?interfaces=panel,controls,annotations:menu` 형식으로 추가하면 해당 UI 요소만 표시됩니다.

---

## 📋 사용 가능한 Interface 옵션

### 기본 컨트롤

| Interface  | 설명                                | 권장    |
| ---------- | ----------------------------------- | ------- |
| `panel`    | 네비게이션 패널 (undo, redo, reset) | ✅ 필수 |
| `controls` | 제출/업데이트/스킵 버튼             | ✅ 필수 |
| `update`   | 업데이트 버튼                       | ⚠️ 선택 |
| `submit`   | 제출 버튼                           | ⚠️ 선택 |
| `skip`     | 스킵 버튼                           | ⚠️ 선택 |

### 상단바 요소

| Interface     | 설명               | 권장                 |
| ------------- | ------------------ | -------------------- |
| `topbar`      | 상단 메뉴바 전체   | ❌ iframe에서 불필요 |
| `infobar`     | 정보 표시줄        | ⚠️ 선택              |
| `instruction` | 작업 지시사항 버튼 | ⚠️ 선택              |

### 사이드바 요소

| Interface              | 설명                    | 권장                 |
| ---------------------- | ----------------------- | -------------------- |
| `side-column`          | 좌측/우측 사이드바      | ❌ iframe에서 불필요 |
| `annotations:tabs`     | Annotation 탭           | ⚠️ 선택              |
| `annotations:menu`     | Annotation 메뉴         | ✅ 권장              |
| `annotations:current`  | 현재 annotation 정보    | ⚠️ 선택              |
| `annotations:add-new`  | 새 annotation 추가 버튼 | ⚠️ 선택              |
| `annotations:delete`   | Annotation 삭제 버튼    | ⚠️ 선택              |
| `annotations:view-all` | 모든 annotation 보기    | ⚠️ 선택              |
| `annotations:history`  | Annotation 히스토리     | ⚠️ 선택              |

### Prediction 관련

| Interface          | 설명            | 권장    |
| ------------------ | --------------- | ------- |
| `predictions:tabs` | Prediction 탭   | ⚠️ 선택 |
| `predictions:menu` | Prediction 메뉴 | ⚠️ 선택 |
| `auto-annotation`  | 자동 annotation | ⚠️ 선택 |

---

## 🎯 추천 설정

### 1. 최소 인터페이스 (iframe 임베딩 권장)

컨텐츠에 집중하고 Things-Factory 내에서 사용하기에 최적:

```javascript
const interfaces = [
  'panel', // 네비게이션 (undo, redo, reset)
  'controls', // 제출/업데이트/스킵
  'annotations:menu' // Annotation 메뉴
]

// URL 예시:
// https://label-studio.com/projects/1/data?token=xxx&interfaces=panel,controls,annotations:menu
```

**결과**: 헤더, 사이드바 없이 **순수 라벨링 영역만** 표시

### 2. 표준 인터페이스

일반적인 라벨링 작업에 적합:

```javascript
const interfaces = [
  'panel',
  'controls',
  'infobar',
  'instruction',
  'annotations:menu',
  'annotations:add-new',
  'annotations:delete',
  'predictions:menu'
]
```

**결과**: 라벨링에 필요한 기본 기능 모두 포함

### 3. 전체 인터페이스

Label Studio의 모든 기능 사용:

```javascript
// interfaces 파라미터 없음 또는 빈 값
// URL 예시: https://label-studio.com/projects/1/data?token=xxx
```

**결과**: Label Studio 전체 UI (헤더, 사이드바 포함)

---

## 💻 구현 방법

### label-studio-wrapper.ts에서 설정

현재 구현 (`client/label-studio-wrapper.ts`):

```typescript
async buildIframeUrl() {
  let url = this.config.serverUrl

  // 프로토콜 확인
  if (!url.startsWith('http://') && !url.startsWith('https://')) {
    url = `https://${url}`
  }

  // 트레일링 슬래시 제거
  url = url.replace(/\/$/, '')

  const params = new URLSearchParams()

  // SSO 토큰 추가
  const token = await this.getAccessToken()
  if (token) {
    const param = this.config.ssoTokenParam || 'token'
    params.set(param, token)
  }

  // UI 요소 제어 (항상 최소 인터페이스)
  const interfaces = [
    'panel',           // 네비게이션 (undo, redo, reset)
    'controls',        // 제출, 업데이트, 스킵 버튼
    'annotations:menu' // Annotation 메뉴
  ]
  params.set('interfaces', interfaces.join(','))

  this.iframeUrl = `${url}?${params.toString()}`
}

async getAccessToken(): Promise<string | null> {
  try {
    // localStorage에서 JWT 토큰 가져오기
    const token = (window as any).auth?.token || localStorage.getItem('access-token')
    return token
  } catch (err) {
    console.error('Failed to get access token:', err)
    return null
  }
}
```

### Things-Factory 기본 설정

Things-Factory는 **항상 최소 인터페이스 모드**를 사용합니다:

```typescript
// 고정 설정
const interfaces = [
  'panel',           // 네비게이션
  'controls',        // 제출 버튼
  'annotations:menu' // Annotation 메뉴
]
```

사용자가 전체 Label Studio UI를 사용하려면 별도로 Label Studio에 직접 접속해야 합니다.

---

## 🔧 커스터마이징 예시

### 예시 1: 읽기 전용 모드

Annotation을 보기만 하고 수정 불가:

```javascript
const interfaces = ['panel', 'annotations:menu', 'annotations:view-all']
// controls 없음 = 제출/수정 불가
```

### 예시 2: 리뷰어 모드

기존 annotation을 검토하고 승인:

```javascript
const interfaces = ['panel', 'controls', 'annotations:tabs', 'annotations:menu', 'annotations:history']
```

### 예시 3: 어노테이터 모드

새로운 annotation 작성에 집중:

```javascript
const interfaces = ['panel', 'controls', 'instruction', 'annotations:menu', 'annotations:add-new']
```

---

## 🎨 CSS 커스터마이징 (고급)

Label Studio의 UI 요소를 CSS로 더 세밀하게 제어할 수 있습니다.

### iframe 내부 스타일 적용

⚠️ **주의**: Cross-origin iframe에서는 보안상 제약이 있습니다.

**방법 1**: Label Studio 테마 커스터마이징

Label Studio `settings.py`에서:

```python
# Label Studio settings.py
LABEL_STUDIO_CUSTOM_CSS = """
/* 상단바 숨기기 */
.dm-header {
  display: none !important;
}

/* 사이드바 숨기기 */
.dm-sidebar {
  display: none !important;
}

/* 컨텐츠 영역 전체 활용 */
.dm-content {
  margin: 0 !important;
  padding: 0 !important;
}
"""
```

**방법 2**: 프로젝트별 스타일 (설정 가능 시)

Label Studio UI에서 Project Settings → Appearance에서 CSS 추가

---

## 📊 특정 페이지 직접 접근

### 프로젝트 데이터 페이지

```
https://label-studio.com/projects/{project_id}/data?token=xxx&interfaces=panel,controls
```

### 특정 태스크 라벨링 페이지

```
https://label-studio.com/projects/{project_id}/data?task={task_id}&token=xxx&interfaces=panel,controls,annotations:menu
```

### 대시보드 (통계)

```
https://label-studio.com/projects/{project_id}?token=xxx&interfaces=topbar,infobar
```

---

## 🔄 커스텀 인터페이스 설정 (선택사항)

Things-Factory 설정 파일에서 인터페이스를 커스터마이징할 수 있습니다:

**config/label-studio.config.js**:
```javascript
module.exports = {
  labelStudio: {
    serverUrl: process.env.LABEL_STUDIO_URL || 'http://localhost:8080',
    apiToken: process.env.LABEL_STUDIO_API_TOKEN || '',
    // 표시할 UI 요소 커스터마이징
    interfaces: 'panel,controls,annotations:menu,annotations:add-new,predictions:menu'
  }
}
```

**사용 가능한 interfaces 옵션**:
- `panel`: 네비게이션 패널 (undo, redo, reset)
- `controls`: 제출/업데이트/스킵 버튼
- `annotations:menu`: Annotation 메뉴
- `annotations:add-new`: 새 annotation 추가 버튼
- `annotations:delete`: Annotation 삭제 버튼
- `predictions:menu`: Prediction 메뉴
- `infobar`: 정보 표시줄
- `instruction`: 작업 지시사항 버튼

**주의**: `topbar`, `side-column` 등의 옵션은 iframe 통합에서 권장하지 않습니다.

---

## ⚠️ 제한사항

### 1. Label Studio 버전 호환성

- `interfaces` 파라미터는 Label Studio 1.5.0+ 지원
- 일부 interface 옵션은 최신 버전에서만 작동

### 2. Cross-origin 제약

- iframe 내부 DOM에 직접 접근 불가 (same-origin policy)
- CSS 주입은 Label Studio 서버 측에서 설정 필요

### 3. URL 길이 제한

- 너무 많은 파라미터는 URL 길이 제한에 걸릴 수 있음
- 일반적으로 2048자 이내 권장

---

## 🧪 테스트 방법

### 1. 브라우저 개발자 도구에서 직접 테스트

```javascript
// 콘솔에서 실행
const baseUrl = 'https://label-studio.example.com/projects/1/data'
const token = 'your-jwt-token'
const interfaces = 'panel,controls,annotations:menu'

window.open(`${baseUrl}?token=${token}&interfaces=${interfaces}`)
```

### 2. iframe src 확인

Things-Factory에서 iframe 로드 후:

```javascript
// 브라우저 콘솔
document.querySelector('iframe').src
```

**예상 출력**:

```
https://label-studio.example.com/projects/1/data?token=eyJhbGc...&interfaces=panel,controls,annotations:menu
```

### 3. 다양한 조합 테스트

```bash
# 최소 인터페이스
?interfaces=panel,controls

# 표준 인터페이스
?interfaces=panel,controls,annotations:menu,annotations:add-new

# 전체 인터페이스
(interfaces 파라미터 없음)
```

---

## 📚 참고 자료

- [Label Studio Frontend Documentation](https://labelstud.io/guide/frontend.html)
- [Label Studio Frontend Library Reference](https://labelstud.io/guide/frontend_reference)
- [Label Studio Frontend GitHub](https://github.com/HumanSignal/label-studio-frontend)

---

## 💡 권장 설정 요약

**Things-Factory iframe 임베딩 권장 설정**:

```typescript
// label-studio-wrapper.ts
const interfaces = [
  'panel', // ✅ 네비게이션 필수
  'controls', // ✅ 제출 버튼 필수
  'annotations:menu' // ✅ Annotation 메뉴 필수
]
```

**결과**:

- ✅ 헤더 숨김
- ✅ 사이드바 숨김
- ✅ 순수 라벨링 컨텐츠만 표시
- ✅ Things-Factory UI와 자연스럽게 통합

---

**문서 버전**: 1.0
**작성일**: 2025-10-02
**Label Studio 호환**: 1.5.0+
