10 KiB
Executable File
Fonctionnalité : Modifier un périphérique
🎯 Objectif
Implémenter le bouton "Modifier" dans la page de détail d'un périphérique pour permettre l'édition complète des informations.
✅ Implémentation
1. Interface HTML
Fichier : frontend/peripheral-detail.html
Modale d'édition (lignes 305-453)
<!-- Edit Peripheral Modal -->
<div id="modal-edit" class="modal">
<div class="modal-content modal-large">
<div class="modal-header">
<h2><i class="fas fa-edit"></i> Modifier le périphérique</h2>
<span class="close" onclick="closeEditModal()">×</span>
</div>
<div class="modal-body">
<form id="form-edit-peripheral" onsubmit="savePeripheral(event)">
<!-- Formulaire complet avec tous les champs -->
</form>
</div>
</div>
</div>
Sections du formulaire
-
Identification
- Nom (requis)
- Type principal (requis)
- Sous-type
- Marque
- Modèle
- Numéro de série
-
Achat
- Boutique
- Date d'achat
- Prix
- Devise
- Garantie (mois)
-
État et localisation
- État (Neuf, Bon, Usagé, Défectueux, Retiré)
- Note (système d'étoiles cliquables)
- Quantité totale
- Quantité disponible
-
Documentation technique
- Synthèse (Markdown)
- CLI / Données structurées (YAML)
- CLI / Rapport système (Markdown)
- Spécifications (Markdown)
- Notes (Markdown)
2. Style CSS
Fichier : frontend/css/peripherals.css (lignes 284-287)
.modal-content.modal-large {
max-width: 1400px;
width: 95%;
}
Caractéristiques :
- Modale plus large pour afficher tous les champs
- Responsive (95% de la largeur sur petit écran)
- Max 1400px sur grand écran
3. JavaScript - Fonctions
Fichier : frontend/js/peripheral-detail.js
toggleEditMode() (ligne 461-494)
Rôle : Ouvrir la modale et pré-remplir le formulaire avec les données actuelles
function toggleEditMode() {
if (!peripheral) {
showError('Aucun périphérique chargé');
return;
}
// Populate form with peripheral data
document.getElementById('edit-nom').value = peripheral.nom || '';
document.getElementById('edit-type_principal').value = peripheral.type_principal || '';
// ... tous les autres champs ...
// Show modal
document.getElementById('modal-edit').style.display = 'block';
}
Gère :
- Vérification que le périphérique est chargé
- Pré-remplissage de tous les champs du formulaire
- Gestion des valeurs nulles avec fallback
- Appel
setEditRating()pour les étoiles
closeEditModal() (ligne 496-498)
Rôle : Fermer la modale d'édition
function closeEditModal() {
document.getElementById('modal-edit').style.display = 'none';
}
setEditRating(rating) (ligne 500-513)
Rôle : Mettre à jour l'affichage des étoiles dans le formulaire d'édition
function setEditRating(rating) {
const stars = document.querySelectorAll('#edit-star-rating .fa-star');
const ratingInput = document.getElementById('edit-rating');
ratingInput.value = rating;
stars.forEach((star, index) => {
if (index < rating) {
star.classList.add('active');
} else {
star.classList.remove('active');
}
});
}
Fonctionnalités :
- Met à jour le champ hidden
edit-rating - Ajoute/retire la classe
activesur les étoiles - Permet sélection visuelle interactive
Event listener étoiles (ligne 516-525)
document.addEventListener('DOMContentLoaded', () => {
const editStars = document.querySelectorAll('#edit-star-rating .fa-star');
editStars.forEach(star => {
star.addEventListener('click', () => {
const rating = parseInt(star.getAttribute('data-rating'));
setEditRating(rating);
});
});
});
Rôle : Rendre les étoiles cliquables pour modifier la note
savePeripheral(event) (ligne 527-559)
Rôle : Sauvegarder les modifications via l'API
async function savePeripheral(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const data = {};
// Convert FormData to object
for (let [key, value] of formData.entries()) {
// Convert numeric fields
if (['prix', 'garantie_duree_mois', 'quantite_totale', 'quantite_disponible', 'rating'].includes(key)) {
data[key] = value ? parseFloat(value) : null;
} else {
data[key] = value || null;
}
}
try {
const response = await apiRequest(`/peripherals/${peripheralId}`, {
method: 'PUT',
body: JSON.stringify(data)
});
showSuccess('Périphérique mis à jour avec succès');
closeEditModal();
// Reload peripheral data
await loadPeripheral();
} catch (error) {
console.error('Error updating peripheral:', error);
showError('Erreur lors de la mise à jour du périphérique');
}
}
Processus :
- Empêche soumission formulaire par défaut
- Récupère les données du formulaire
- Convertit FormData en objet JavaScript
- Convertit champs numériques en nombres
- Envoie requête PUT à l'API
- Affiche message succès/erreur
- Ferme la modale
- Recharge les données pour rafraîchir l'affichage
4. API Backend
Endpoint : PUT /api/peripherals/{peripheral_id}
Fichier : backend/app/api/endpoints/peripherals.py (ligne 177-187)
@router.put("/{peripheral_id}", response_model=PeripheralDetail)
def update_peripheral(
peripheral_id: int,
peripheral_data: PeripheralUpdate,
db: Session = Depends(get_peripherals_db)
):
"""Update a peripheral"""
peripheral = PeripheralService.update_peripheral(db, peripheral_id, peripheral_data)
if not peripheral:
raise HTTPException(status_code=404, detail="Peripheral not found")
return peripheral
Schéma attendu : PeripheralUpdate (Pydantic)
Retour : PeripheralDetail (données complètes du périphérique)
🔄 Flux d'utilisation
1. User clique "Modifier" dans page détail
↓
2. toggleEditMode() appelé
│ ├─> Vérifie que peripheral est chargé
│ ├─> Pré-remplit tous les champs du formulaire
│ ├─> Configure les étoiles de notation
│ └─> Affiche la modale
↓
3. User modifie les champs souhaités
│ └─> Peut cliquer sur les étoiles pour changer la note
↓
4. User clique "Enregistrer"
↓
5. savePeripheral() appelé
│ ├─> Récupère données du formulaire
│ ├─> Convertit types numériques
│ ├─> PUT /api/peripherals/{id}
│ └─> Backend met à jour en BDD
↓
6. Success
│ ├─> Message "Périphérique mis à jour avec succès"
│ ├─> Ferme modale
│ └─> Recharge peripheral pour afficher nouvelles données
📊 Champs éditables
| Catégorie | Champ | Type | Requis |
|---|---|---|---|
| Identification | nom | text | ✅ |
| type_principal | text | ✅ | |
| sous_type | text | ||
| marque | text | ||
| modele | text | ||
| numero_serie | text | ||
| Achat | boutique | text | |
| date_achat | date | ||
| prix | number | ||
| devise | text(3) | ||
| garantie_duree_mois | number | ||
| État | etat | select | |
| rating | number(0-5) | ||
| quantite_totale | number | ||
| quantite_disponible | number | ||
| Documentation | synthese | textarea | |
| cli_yaml | textarea | ||
| cli_raw | textarea | ||
| specifications | textarea | ||
| notes | textarea |
Total : 22 champs éditables
🎨 Interface utilisateur
Bouton "Modifier"
Position : Dans le header de la carte "Informations générales"
<button class="btn btn-primary" onclick="toggleEditMode()" id="btn-edit">
<i class="fas fa-edit"></i> Modifier
</button>
Style :
- Bouton bleu primaire
- Icône crayon Font Awesome
- Positionné à droite du header
Modale d'édition
Dimensions :
- Largeur : 95% (mobile) → max 1400px (desktop)
- Layout : Grille responsive 3 colonnes
Sections :
- 3 colonnes pour les champs principaux
- Pleine largeur pour documentation technique
- Actions (Annuler / Enregistrer) en bas
Retour utilisateur
Messages :
- ✅ Succès : "Périphérique mis à jour avec succès" (vert)
- ❌ Erreur : "Erreur lors de la mise à jour du périphérique" (rouge)
- ⚠️ Validation : "Aucun périphérique chargé" (orange)
🧪 Tests
Test manuel
- Ouvrir page détail :
/peripheral-detail.html?id=3 - Cliquer "Modifier" : Modale s'ouvre avec données pré-remplies
- Modifier champs : Ex: changer nom, prix, note
- Cliquer étoiles : Note change visuellement
- Cliquer "Enregistrer" : Message succès + modale se ferme
- Vérifier affichage : Nouvelles valeurs affichées
Test API
# Mettre à jour un périphérique
curl -X PUT "http://10.0.0.50:8007/api/peripherals/3" \
-H "Content-Type: application/json" \
-H "X-API-Token: YOUR_TOKEN" \
-d '{
"nom": "Logitech MX Master 3 (Updated)",
"prix": 99.99,
"rating": 5
}'
Résultat attendu :
{
"id": 3,
"nom": "Logitech MX Master 3 (Updated)",
"prix": 99.99,
"rating": 5,
...
}
📝 Fichiers modifiés
Créés
- ✅
docs/FEATURE_EDIT_PERIPHERAL.md- Cette documentation
Modifiés
- ✅
frontend/peripheral-detail.html- Ajout modale d'édition - ✅
frontend/js/peripheral-detail.js- Fonctions édition complètes - ✅
frontend/css/peripherals.css- Style.modal-large
Backend (déjà existant)
- ✅
backend/app/api/endpoints/peripherals.py- Endpoint PUT - ✅
backend/app/services/peripheral_service.py- Service update - ✅
backend/app/schemas/peripheral.py- Schema PeripheralUpdate
🚀 Améliorations futures possibles
- Validation côté client (longueurs, formats)
- Champs device_id et location_id (dropdowns)
- Confirmation avant fermeture si modifications non sauvegardées
- Historique des modifications (audit trail)
- Mode "édition rapide" (inline editing)
- Raccourci clavier (Ctrl+E)
Date : 31 décembre 2025 Statut : ✅ Implémenté et fonctionnel Impact : Permet l'édition complète des périphériques depuis la page de détail