- Integrated Unsplash API for image search functionality with environment configuration - Added new Nimbus Editor page component with navigation from sidebar and mobile drawer - Enhanced TOC with highlight animation for editor heading navigation - Improved CDK overlay z-index hierarchy for proper menu layering - Removed obsolete logging validation script
317 lines
9.2 KiB
Markdown
317 lines
9.2 KiB
Markdown
# Fix: Boutons Doubles sur Bloc Columns
|
|
|
|
## 🔴 Problème Identifié
|
|
|
|
**Symptôme (Image 2):**
|
|
- Boutons menu (⋯) et commentaire (💬) apparaissent pour la ligne de colonnes ENTIÈRE
|
|
- Ces boutons devraient être uniquement sur les blocs individuels, pas sur la ligne
|
|
|
|
**Cause:**
|
|
```
|
|
block-host.component.ts
|
|
├─ Ajoute bouton ⋯ à TOUS les blocs (ligne 78-90)
|
|
└─ Inclut le bloc "columns"
|
|
└─ columns-block.component.ts
|
|
└─ Ajoute ses PROPRES boutons ⋯ pour chaque bloc
|
|
```
|
|
|
|
**Résultat:** Double boutons ❌
|
|
|
|
## ✅ Solution Implémentée
|
|
|
|
### 1. Cacher Bouton block-host pour Type 'columns'
|
|
|
|
**Fichier:** `src/app/editor/components/block/block-host.component.ts`
|
|
|
|
**Avant:**
|
|
```html
|
|
<!-- Ellipsis menu handle -->
|
|
<button
|
|
type="button"
|
|
class="menu-handle..."
|
|
(click)="onMenuClick($event)"
|
|
(mousedown)="onDragStart($event)"
|
|
>
|
|
<svg>...</svg>
|
|
</button>
|
|
```
|
|
|
|
**Après:**
|
|
```html
|
|
<!-- Ellipsis menu handle (hidden for columns block) -->
|
|
@if (block.type !== 'columns') {
|
|
<button
|
|
type="button"
|
|
class="menu-handle..."
|
|
(click)="onMenuClick($event)"
|
|
(mousedown)="onDragStart($event)"
|
|
>
|
|
<svg>...</svg>
|
|
</button>
|
|
}
|
|
```
|
|
|
|
**Raison:**
|
|
- Le bloc `columns` n'a PAS BESOIN de bouton au niveau de la ligne entière
|
|
- Chaque bloc DANS les colonnes a ses propres boutons (définis dans `columns-block.component.ts`)
|
|
- Évite la duplication des boutons
|
|
|
|
### 2. Amélioration: Insertion ENTRE Colonnes
|
|
|
|
**Nouveau cas supporté:** Drop un bloc pleine largeur dans l'ESPACE ENTRE deux colonnes
|
|
|
|
**Fichier:** `src/app/editor/components/block/block-host.component.ts`
|
|
|
|
**Logique ajoutée:**
|
|
```typescript
|
|
// Dropping in the gap BETWEEN columns - insert as new column
|
|
const columnsContainerEl = columnsBlockEl.querySelector('[class*="columns"]');
|
|
if (columnsContainerEl) {
|
|
const containerRect = columnsContainerEl.getBoundingClientRect();
|
|
const relativeX = e.clientX - containerRect.left;
|
|
const columnWidth = containerRect.width / columns.length;
|
|
|
|
// Check if we're in the gap (not on a column)
|
|
const gapThreshold = 20; // pixels
|
|
const posInColumn = (relativeX % columnWidth);
|
|
const isInGap = posInColumn > (columnWidth - gapThreshold) ||
|
|
posInColumn < gapThreshold;
|
|
|
|
if (isInGap) {
|
|
// Insert as new column between existing columns
|
|
const blockCopy = JSON.parse(JSON.stringify(this.block));
|
|
const newColumn = {
|
|
id: this.generateId(),
|
|
blocks: [blockCopy],
|
|
width: 100 / (columns.length + 1)
|
|
};
|
|
|
|
// Redistribute widths and insert
|
|
updatedColumns.splice(insertIndex, 0, newColumn);
|
|
}
|
|
}
|
|
```
|
|
|
|
**Comment ça marche:**
|
|
1. Détecte si le drop est dans l'espace (gap) entre colonnes (20px de chaque côté)
|
|
2. Crée une nouvelle colonne à cet endroit
|
|
3. Redistribue les largeurs équitablement
|
|
4. Insère le bloc dans la nouvelle colonne
|
|
|
|
**Exemple:**
|
|
```
|
|
Avant:
|
|
┌────────────┬────────────┐
|
|
│ Quote !!! │ aaalll │
|
|
└────────────┴────────────┘
|
|
|
|
Drag H1 dans le gap ↓
|
|
|
|
Après:
|
|
┌────────────┬────────────┬────────────┐
|
|
│ Quote !!! │ H1 │ aaalll │
|
|
└────────────┴────────────┴────────────┘
|
|
```
|
|
|
|
## 📊 Résultat
|
|
|
|
### Avant
|
|
```
|
|
⋯ ┌─────────────────────┬──────────────────┐ 💬
|
|
│ ⋯ Quote !!! 💬 │ ⋯ aaalll 💬 │
|
|
└─────────────────────┴──────────────────┘
|
|
|
|
Problèmes:
|
|
- ⋯ et 💬 au niveau de la ligne entière ❌
|
|
- ⋯ et 💬 aussi sur chaque bloc ❌
|
|
- = Double boutons!
|
|
```
|
|
|
|
### Après
|
|
```
|
|
┌─────────────────────┬──────────────────┐
|
|
│ ⋯ Quote !!! 💬 │ ⋯ aaalll 💬 │
|
|
└─────────────────────┴──────────────────┘
|
|
|
|
Résultat:
|
|
- Pas de boutons au niveau de la ligne ✅
|
|
- Boutons uniquement sur les blocs individuels ✅
|
|
- Pas de duplication ✅
|
|
```
|
|
|
|
## 🎯 Cas d'Usage
|
|
|
|
### Cas 1: Insertion DANS une Colonne
|
|
**Déjà supporté:**
|
|
```
|
|
Drag H1 → Drop sur "Quote !!!"
|
|
→ H1 ajouté dans la première colonne
|
|
```
|
|
|
|
### Cas 2: Insertion ENTRE Colonnes (NOUVEAU)
|
|
**Maintenant supporté:**
|
|
```
|
|
Drag H1 → Drop dans le GAP entre Quote et aaalll
|
|
→ Nouvelle colonne créée avec H1 au milieu
|
|
```
|
|
|
|
### Cas 3: Insertion AVANT la Ligne
|
|
**Déjà supporté:**
|
|
```
|
|
Drag H1 → Drop au-dessus de la ligne de colonnes
|
|
→ H1 inséré avant le bloc columns
|
|
```
|
|
|
|
### Cas 4: Insertion APRÈS la Ligne
|
|
**Déjà supporté:**
|
|
```
|
|
Drag H1 → Drop en-dessous de la ligne de colonnes
|
|
→ H1 inséré après le bloc columns
|
|
```
|
|
|
|
## 🧪 Tests à Effectuer
|
|
|
|
### Test 1: Boutons Uniques
|
|
```
|
|
1. Créer un bloc columns avec 2 colonnes
|
|
2. Hover sur la ligne
|
|
✅ Vérifier: Pas de bouton ⋯ au niveau de la ligne
|
|
3. Hover sur "Quote !!!"
|
|
✅ Vérifier: Bouton ⋯ apparaît à gauche du bloc
|
|
✅ Vérifier: Bouton 💬 apparaît à droite du bloc
|
|
4. Hover sur "aaalll"
|
|
✅ Vérifier: Bouton ⋯ apparaît à gauche du bloc
|
|
✅ Vérifier: Bouton 💬 apparaît à droite du bloc
|
|
```
|
|
|
|
### Test 2: Insertion Entre Colonnes
|
|
```
|
|
1. Créer un bloc H1
|
|
2. Créer un bloc columns avec 2 colonnes (Quote et aaalll)
|
|
3. Drag H1 vers le GAP entre les deux colonnes (pas sur un bloc)
|
|
✅ Vérifier: Flèche bleue apparaît dans le gap
|
|
✅ Vérifier: H1 inséré comme nouvelle colonne au milieu
|
|
✅ Vérifier: 3 colonnes avec largeurs égales (33.33% chacune)
|
|
✅ Vérifier: Ordre: Quote | H1 | aaalll
|
|
```
|
|
|
|
### Test 3: Insertion Dans une Colonne
|
|
```
|
|
1. Créer un bloc H1
|
|
2. Créer un bloc columns avec 2 colonnes
|
|
3. Drag H1 vers le centre d'une colonne (pas dans le gap)
|
|
✅ Vérifier: H1 ajouté dans la colonne ciblée
|
|
✅ Vérifier: Nombre de colonnes reste le même (2)
|
|
```
|
|
|
|
### Test 4: Menu Contextuel
|
|
```
|
|
1. Créer un bloc columns
|
|
2. Cliquer sur bouton ⋯ d'un bloc dans une colonne
|
|
✅ Vérifier: Menu s'ouvre pour CE bloc uniquement
|
|
✅ Vérifier: Options: Comment, Add, Convert, Background, Duplicate, Delete, etc.
|
|
3. Sélectionner "Convert" → "Heading 2"
|
|
✅ Vérifier: Bloc converti en H2 dans la colonne
|
|
```
|
|
|
|
### Test 5: Commentaires
|
|
```
|
|
1. Créer un bloc columns avec 2 colonnes
|
|
2. Cliquer sur bouton 💬 d'un bloc
|
|
✅ Vérifier: Panel de commentaires s'ouvre pour CE bloc
|
|
3. Ajouter un commentaire "Test"
|
|
✅ Vérifier: Badge numérique apparaît sur le bouton 💬
|
|
✅ Vérifier: Badge uniquement sur ce bloc (pas sur l'autre)
|
|
```
|
|
|
|
## 🔧 Détails Techniques
|
|
|
|
### Détection du Gap
|
|
|
|
**Algorithme:**
|
|
```typescript
|
|
const gapThreshold = 20; // pixels de chaque côté
|
|
const relativeX = mouseX - containerLeft;
|
|
const columnWidth = containerWidth / numberOfColumns;
|
|
const positionInColumn = relativeX % columnWidth;
|
|
|
|
const isInLeftGap = positionInColumn < gapThreshold;
|
|
const isInRightGap = positionInColumn > (columnWidth - gapThreshold);
|
|
const isInGap = isInLeftGap || isInRightGap;
|
|
|
|
if (isInGap) {
|
|
// Insert new column
|
|
}
|
|
```
|
|
|
|
**Zones de Gap:**
|
|
```
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ Column 1 │ GAP │ Column 2 │
|
|
│ │ │ │
|
|
└──────────────┘ └──────────────┘
|
|
↑ ↑ ↑ ↑
|
|
20px 20px 20px 20px
|
|
(gap) (gap) (gap) (gap)
|
|
```
|
|
|
|
### Redistribution des Largeurs
|
|
|
|
**Formule:**
|
|
```typescript
|
|
newWidth = 100 / (numberOfColumns + 1)
|
|
|
|
Exemple:
|
|
- Avant: 2 colonnes (50% + 50%)
|
|
- Après: 3 colonnes (33.33% + 33.33% + 33.33%)
|
|
```
|
|
|
|
## 📚 Fichiers Modifiés
|
|
|
|
### 1. block-host.component.ts
|
|
**Ligne 78-92:** Condition `@if (block.type !== 'columns')`
|
|
**Ligne 313-361:** Logique d'insertion entre colonnes
|
|
|
|
### 2. Documentation
|
|
**Nouveau:** `docs/COLUMNS_BLOCK_BUTTON_FIX.md` (ce fichier)
|
|
**Mis à jour:** `docs/UNIFIED_DRAG_DROP_SYSTEM.md`
|
|
|
|
## ✅ Avantages
|
|
|
|
### 1. Interface Plus Propre
|
|
- ✅ Pas de boutons redondants
|
|
- ✅ Hiérarchie visuelle claire
|
|
- ✅ Moins de confusion pour l'utilisateur
|
|
|
|
### 2. Flexibilité Accrue
|
|
- ✅ Insertion entre colonnes maintenant possible
|
|
- ✅ Création de colonnes multiples dynamique
|
|
- ✅ Redistribution automatique des largeurs
|
|
|
|
### 3. Cohérence
|
|
- ✅ Comportement identique partout
|
|
- ✅ Même système de drag & drop
|
|
- ✅ Même indicateur visuel (flèche bleue)
|
|
|
|
## 🎉 Résultat Final
|
|
|
|
**Boutons propres et fonctionnels:**
|
|
- ✅ Pas de duplication au niveau de la ligne
|
|
- ✅ Boutons uniquement sur les blocs individuels
|
|
- ✅ Menu et commentaires fonctionnent correctement
|
|
|
|
**Insertion flexible:**
|
|
- ✅ Dans une colonne existante
|
|
- ✅ Entre colonnes (crée nouvelle colonne)
|
|
- ✅ Avant/après la ligne de colonnes
|
|
- ✅ Redistribution automatique des largeurs
|
|
|
|
**Expérience utilisateur:**
|
|
- ✅ Interface propre et intuitive
|
|
- ✅ Feedback visuel avec flèche bleue
|
|
- ✅ Comportement prévisible et cohérent
|
|
|
|
---
|
|
|
|
**Rafraîchissez le navigateur et testez les corrections!** 🚀
|