# 📖 Field Renderer - Référence Complète des Types

Référence exhaustive de tous les types de champs supportés par le `FieldRendererComponent`.

---

## 📋 Table des Types

| # | Type | Catégorie | Description | Compatible Projects |
|---|------|-----------|-------------|---------------------|
| 1 | `text` | Texte | Champ texte simple | ✅ |
| 2 | `string` | Texte | Équivalent text (projects) | ✅ |
| 3 | `email` | Texte | Email avec validation | ❌ |
| 4 | `tel` | Texte | Téléphone | ❌ |
| 5 | `url` | Texte | URL avec validation | ❌ |
| 6 | `password` | Texte | Mot de passe masqué | ❌ |
| 7 | `textarea` | Texte | Zone de texte multiligne | ❌ |
| 8 | `number` | Numérique | Nombre (entier/décimal) | ❌ |
| 9 | `integer` | Numérique | Nombre entier | ✅ |
| 10 | `double` | Numérique | Nombre décimal | ✅ |
| 11 | `currency` | Numérique | Montant avec € | ✅ |
| 12 | `date` | Temporel | Sélecteur de date | ✅ |
| 13 | `datetime` | Temporel | Date + heure | ✅ |
| 14 | `select` | Sélection | Liste déroulante | ❌ |
| 15 | `multiselect` | Sélection | Multi-sélection | ❌ |
| 16 | `picklist` | Sélection | Liste (projects) | ✅ |
| 17 | `radio` | Sélection | Boutons radio | ❌ |
| 18 | `checkbox` | Booléen | Case à cocher | ❌ |
| 19 | `boolean` | Booléen | Équivalent checkbox | ✅ |
| 20 | `file` | Spécial | Upload fichier | ❌ |
| 21 | `reference` | Spécial | Autocomplétion serveur | ✅ |

---

## 📝 Détails par Type

### 1. TEXT - Champ Texte Simple

**Usage** : Nom, prénom, adresse, etc.

```typescript
{
  controlName: 'firstName',
  controlType: 'text',
  placeholder: 'Prénom',
  valueType: 'text', // optionnel
  validators: {
    required: true,
    minlength: 2,
    maxlength: 50
  }
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Prénom</mat-label>
  <input matInput type="text" formControlName="firstName" />
</mat-form-field>
```

**Validations supportées** : required, minlength, maxlength

---

### 2. STRING - Texte (Projects.Component)

**Usage** : Identique à `text` mais au format projects.component

```typescript
{
  name: 'companyName',
  type: 'string',
  displayName: 'Nom de l\'entreprise',
  mandatory: 1
}
```

**Différence avec `text`** : Utilise `name` au lieu de `controlName`, `type` au lieu de `controlType`, `mandatory` au lieu de `validators.required`

---

### 3. EMAIL - Email avec Validation

**Usage** : Adresse email

```typescript
{
  controlName: 'email',
  controlType: 'email',
  placeholder: 'Adresse email',
  validators: { required: true }
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Adresse email</mat-label>
  <input matInput type="email" formControlName="email" />
  <mat-icon matSuffix>email</mat-icon>
</mat-form-field>
```

**Validation automatique** : Format email (xxx@yyy.zzz)

---

### 4. TEL - Téléphone

**Usage** : Numéro de téléphone

```typescript
{
  controlName: 'phone',
  controlType: 'tel',
  placeholder: 'Téléphone'
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Téléphone</mat-label>
  <input matInput type="tel" formControlName="phone" />
  <mat-icon matSuffix>phone</mat-icon>
</mat-form-field>
```

---

### 5. URL - URL avec Validation

**Usage** : Site web, lien

```typescript
{
  controlName: 'website',
  controlType: 'url',
  placeholder: 'Site web'
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Site web</mat-label>
  <input matInput type="url" formControlName="website" />
  <mat-icon matSuffix>link</mat-icon>
</mat-form-field>
```

**Validation automatique** : Format URL (http://...)

---

### 6. PASSWORD - Mot de Passe

**Usage** : Mot de passe masqué

```typescript
{
  controlName: 'password',
  controlType: 'password',
  placeholder: 'Mot de passe',
  validators: { required: true, minlength: 8 }
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Mot de passe</mat-label>
  <input matInput type="password" formControlName="password" />
  <mat-icon matSuffix>lock</mat-icon>
</mat-form-field>
```

---

### 7. TEXTAREA - Zone de Texte

**Usage** : Commentaire, description longue

```typescript
{
  controlName: 'description',
  controlType: 'textarea',
  placeholder: 'Description',
  validators: { required: true }
}
```

**Rendu HTML** :
```html
<mat-form-field>
  <mat-label>Description</mat-label>
  <textarea matInput rows="4" formControlName="description"></textarea>
</mat-form-field>
```

---

### 8-11. TYPES NUMÉRIQUES

#### NUMBER

```typescript
{
  controlName: 'quantity',
  controlType: 'number',
  placeholder: 'Quantité',
  validators: { required: true }
}
```

#### INTEGER (Projects)

```typescript
{
  name: 'employees',
  type: 'integer',
  displayName: 'Nombre d\'employés',
  mandatory: 0
}
```

#### DOUBLE (Projects)

```typescript
{
  name: 'rating',
  type: 'double',
  displayName: 'Note',
  mandatory: 0
}
```

**Rendu** : `<input type="number" step="0.01" />`

#### CURRENCY (Projects)

```typescript
{
  name: 'price',
  type: 'currency',
  displayName: 'Prix',
  mandatory: 1
}
```

**Rendu** :
```html
<mat-form-field>
  <input matInput type="number" step="0.01" />
  <span matSuffix>€</span>
</mat-form-field>
```

---

### 12-13. TYPES TEMPORELS

#### DATE

```typescript
{
  controlName: 'birthdate',
  controlType: 'date',
  placeholder: 'Date de naissance'
}
```

**Rendu** : `<input type="date" />`
**Format** : yyyy-MM-dd

#### DATETIME

```typescript
{
  controlName: 'appointmentDate',
  controlType: 'datetime',
  placeholder: 'Date et heure du rendez-vous'
}
```

**Rendu** : `<input type="datetime-local" />`
**Format** : yyyy-MM-ddTHH:mm

---

### 14-17. TYPES SÉLECTION

#### SELECT - Liste Simple

```typescript
{
  controlName: 'country',
  controlType: 'select',
  placeholder: 'Pays',
  options: [
    { value: 'FR', optionName: 'France' },
    { value: 'BE', optionName: 'Belgique' },
    { value: 'CH', optionName: 'Suisse' }
  ],
  validators: { required: true }
}
```

#### MULTISELECT - Multi-sélection

```typescript
{
  controlName: 'interests',
  controlType: 'multiselect',
  placeholder: 'Centres d\'intérêt',
  options: [
    { value: 'sports', optionName: 'Sports' },
    { value: 'music', optionName: 'Musique' },
    { value: 'tech', optionName: 'Technologie' }
  ]
}
```

**Rendu** : `<mat-select multiple>`

#### PICKLIST (Projects)

```typescript
{
  name: 'status',
  type: 'picklist',
  displayName: 'Statut',
  mandatory: 1,
  options: [
    { value: 'Active' },
    { value: 'Inactive' },
    { value: 'Pending' }
  ]
}
```

**Différence** : Options ont seulement `value` (pas `optionName`)

#### RADIO - Boutons Radio

```typescript
{
  controlName: 'gender',
  controlType: 'radio',
  placeholder: 'Genre',
  options: [
    { value: 'M', optionName: 'Homme' },
    { value: 'F', optionName: 'Femme' },
    { value: 'O', optionName: 'Autre' }
  ]
}
```

---

### 18-19. TYPES BOOLÉENS

#### CHECKBOX

```typescript
{
  controlName: 'acceptTerms',
  controlType: 'checkbox',
  placeholder: 'J\'accepte les conditions',
  validators: { required: true }
}
```

**Rendu** :
```html
<mat-checkbox formControlName="acceptTerms">
  J'accepte les conditions
</mat-checkbox>
```

#### BOOLEAN (Projects)

```typescript
{
  name: 'isActive',
  type: 'boolean',
  displayName: 'Actif',
  mandatory: 0
}
```

---

### 20. FILE - Upload Fichier

**Configuration** :

```typescript
{
  controlName: 'document',
  controlType: 'file',
  placeholder: 'Document',
  acceptedTypes: 'image/*,.pdf', // optionnel
  validators: { required: true }
}
```

**Usage dans le template** :

```html
<app-field-renderer
  [field]="fileField"
  [form]="form"
  [acceptedFileTypes]="'image/*,.pdf'"
  [maxFileSize]="5242880"
  (fileSelected)="onFileUpload($event.file, $event.fieldName)">
</app-field-renderer>
```

**Gestion de l'upload** :

```typescript
onFileUpload(file: File, fieldName: string) {
  // Validation
  if (file.size > 5 * 1024 * 1024) {
    alert('Fichier trop volumineux (5MB max)');
    return;
  }

  // Upload
  const formData = new FormData();
  formData.append('file', file);
  this.http.post('/api/upload', formData).subscribe();
}
```

**Types de fichiers acceptés** :
- Images : `image/*` ou `image/png,image/jpeg`
- Documents : `.pdf,.doc,.docx`
- Tout : `*`

---

### 21. REFERENCE - Autocomplétion Serveur

**Configuration** :

```typescript
{
  name: 'account',
  type: 'reference',
  displayName: 'Compte',
  module: 'accounts', // Module de recherche
  mandatory: 1
}
```

**Usage complet** :

```html
<app-field-renderer
  [field]="referenceField"
  [form]="form"
  [submitted]="submitted"
  [autocompleteData]="searchResults"
  [isLoadingAutocomplete]="isSearching"
  [displayFn]="displayAccount"
  (autocompleteInput)="onSearch($event.value, $event.module)"
  (autocompleteSelected)="onAccountSelected($event.event, $event.fieldName)"
  (autocompleteFocused)="onFocus($event)"
  (autocompleteCleared)="onClear()">
</app-field-renderer>
```

**Component** :

```typescript
searchResults: any[] = [];
isSearching = false;

onSearch(query: string, module: string) {
  if (query.length < 3) return;

  this.isSearching = true;
  this.dataService.search(module, query).subscribe({
    next: (results) => {
      this.searchResults = results.map(r => ({
        id: r.id,
        name: r.name
      }));
      this.isSearching = false;
    },
    error: () => this.isSearching = false
  });
}

onAccountSelected(event: any, fieldName: string) {
  const account = event.option.value;
  this.form.get(fieldName)?.setValue(account.id);
}

displayAccount(item: any): string {
  return item?.name || '';
}
```

---

## 🔄 Tableau de Conversion

### Harmonized ↔ Projects

| Harmonized Format | Projects Format |
|-------------------|-----------------|
| `controlName` | `name` |
| `controlType` | `type` |
| `placeholder` | `displayName` |
| `validators.required: true` | `mandatory: 1` |
| `currentValue` | `value` |
| `text` | `string` |
| `select` | `picklist` |
| `checkbox` | `boolean` |

---

## 🎨 Personnalisation des Types

### Ajouter un Nouveau Type

Pour ajouter un nouveau type (ex: `color`), modifier :

**1. HTML** ([field-renderer.component.html](./field-renderer.component.html))

```html
<ng-template [ngSwitchCase]="'color'">
  <mat-form-field>
    <mat-label>{{ getLabel() }}</mat-label>
    <input
      matInput
      type="color"
      [formControlName]="getControlName()"
      [required]="isRequired()"
    />
  </mat-form-field>
</ng-template>
```

**2. Documentation** (ce fichier)

Ajouter la référence du type dans la table et la description détaillée.

---

## 📌 Notes Importantes

### Compatibilité

- **Tous les types** fonctionnent avec `harmonized-create-view`
- **10 types** sont optimisés pour `projects.component` (voir colonne "Compatible Projects")

### Performance

- Le composant utilise `OnPush` change detection (futur)
- Chaque type est lazy-loaded via `ngSwitch`
- Pas de duplication de code grâce aux méthodes helper

### Validation

- Validation côté formulaire via `Validators`
- Validation côté template via `[required]`, `[minlength]`, etc.
- **Toujours valider côté serveur également !**

---

## 🔗 Liens Utiles

- [Guide de Démarrage Rapide](./QUICK-START.md)
- [Documentation Complète](./README.md)
- [Exemples Pratiques](./EXAMPLES.md)
- [Code Source](./field-renderer.component.ts)

---

**Dernière mise à jour** : Octobre 2025
