fix: Amélioration de l'expérience utilisateur lors de la génération de QR codes

Cette mise à jour améliore la génération de QR codes pour les équipements et les containers en ajoutant un retour visuel à l'utilisateur et une gestion des erreurs plus robuste.

**Changements :**
- **Ajout d'un indicateur de chargement :** Un `CircularProgressIndicator` est désormais affiché pendant que les données des équipements ou des containers sélectionnés sont récupérées, informant l'utilisateur qu'une opération est en cours.
- **Gestion des erreurs :** Un bloc `try...catch` a été ajouté autour de la logique de génération dans les pages de gestion des équipements (`EquipmentManagementPage`) et des containers (`ContainerManagementPage`).
- **Affichage des erreurs :** En cas d'échec, le chargement est stoppé et une `SnackBar` rouge apparaît pour notifier l'utilisateur de l'erreur, améliorant ainsi la robustesse de la fonctionnalité.
This commit is contained in:
ElPoyo
2026-01-16 00:42:16 +01:00
parent 06f394b728
commit 1ea5cea6fc
2 changed files with 132 additions and 64 deletions

View File

@@ -473,49 +473,81 @@ class _ContainerManagementPageState extends State<ContainerManagementPage>
Future<void> _generateQRCodesForSelected() async {
if (!hasSelection) return;
// Récupérer les containers sélectionnés
final containerProvider = context.read<ContainerProvider>();
final List<ContainerModel> selectedContainers = [];
final Map<String, List<EquipmentModel>> containerEquipmentMap = {};
// Afficher un indicateur de chargement
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(color: AppColors.rouge),
),
);
for (final id in selectedIds) {
final container = await containerProvider.getContainerById(id);
if (container != null) {
selectedContainers.add(container);
// Charger les équipements pour ce container
final equipment = await containerProvider.getContainerEquipment(id);
containerEquipmentMap[id] = equipment;
try {
// Récupérer les containers sélectionnés
final containerProvider = context.read<ContainerProvider>();
final List<ContainerModel> selectedContainers = [];
final Map<String, List<EquipmentModel>> containerEquipmentMap = {};
for (final id in selectedIds) {
final container = await containerProvider.getContainerById(id);
if (container != null) {
selectedContainers.add(container);
// Charger les équipements pour ce container
final equipment = await containerProvider.getContainerEquipment(id);
containerEquipmentMap[id] = equipment;
}
}
}
if (selectedContainers.isEmpty) {
// Fermer l'indicateur de chargement
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Aucun container trouvé')),
Navigator.of(context).pop();
}
if (selectedContainers.isEmpty) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Aucun container trouvé')),
);
}
return;
}
// Afficher le dialogue de sélection de format avec le widget générique
if (mounted) {
showDialog(
context: context,
builder: (context) => QRCodeFormatSelectorDialog<ContainerModel>(
itemList: selectedContainers,
getId: (c) => c.id,
getTitle: (c) => c.name,
getDetails: (ContainerModel c) {
final equipment = containerEquipmentMap[c.id] ?? <EquipmentModel>[];
return [
'Contenu (${equipment.length}):',
...equipment.take(5).map((eq) => '- ${eq.id}'),
if (equipment.length > 5) '... +${equipment.length - 5}',
];
},
dialogTitle: 'Générer ${selectedContainers.length} QR Code(s)',
),
);
}
return;
}
} catch (e) {
// Fermer l'indicateur si une erreur survient
if (mounted) {
Navigator.of(context).pop();
}
// Afficher le dialogue de sélection de format avec le widget générique
if (mounted) {
showDialog(
context: context,
builder: (context) => QRCodeFormatSelectorDialog<ContainerModel>(
itemList: selectedContainers,
getId: (c) => c.id,
getTitle: (c) => c.name,
getDetails: (ContainerModel c) {
final equipment = containerEquipmentMap[c.id] ?? <EquipmentModel>[];
return [
'Contenu (${equipment.length}):',
...equipment.take(5).map((eq) => '- ${eq.id}'),
if (equipment.length > 5) '... +${equipment.length - 5}',
];
},
dialogTitle: 'Générer ${selectedContainers.length} QR Code(s)',
),
);
DebugLog.error('[ContainerManagementPage] Error generating QR codes', e);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Erreur lors de la génération : ${e.toString()}'),
backgroundColor: Colors.red,
),
);
}
}
}

View File

@@ -791,39 +791,75 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
void _generateQRCodesForSelected() async {
if (!hasSelection) return;
// Récupérer les équipements sélectionnés
final provider = context.read<EquipmentProvider>();
final List<EquipmentModel> selectedEquipment = [];
// Afficher un indicateur de chargement
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(color: AppColors.rouge),
),
);
// On doit récupérer les équipements depuis le stream
await for (final equipmentList in provider.equipmentStream.take(1)) {
for (final equipment in equipmentList) {
if (isItemSelected(equipment.id)) {
selectedEquipment.add(equipment);
try {
// Récupérer les équipements sélectionnés
final provider = context.read<EquipmentProvider>();
final List<EquipmentModel> selectedEquipment = [];
// On doit récupérer les équipements depuis le stream
await for (final equipmentList in provider.equipmentStream.take(1)) {
for (final equipment in equipmentList) {
if (isItemSelected(equipment.id)) {
selectedEquipment.add(equipment);
}
}
break;
}
// Fermer l'indicateur de chargement
if (mounted) {
Navigator.of(context).pop();
}
if (selectedEquipment.isEmpty) return;
if (selectedEquipment.length == 1) {
// Un seul équipement : afficher le dialogue simple
if (mounted) {
showDialog(
context: context,
builder: (context) => QRCodeDialog.forEquipment(selectedEquipment.first),
);
}
} else {
// Plusieurs équipements : afficher le sélecteur de format
if (mounted) {
showDialog(
context: context,
builder: (context) => QRCodeFormatSelectorDialog<EquipmentModel>(
itemList: selectedEquipment,
getId: (eq) => eq.id,
getTitle: (eq) => '${eq.brand ?? ''} ${eq.model ?? ''}'.trim(),
dialogTitle: 'Générer ${selectedEquipment.length} QR Code(s)',
),
);
}
}
break;
}
} catch (e) {
// Fermer l'indicateur si une erreur survient
if (mounted) {
Navigator.of(context).pop();
}
if (selectedEquipment.isEmpty) return;
DebugLog.error('[EquipmentManagementPage] Error generating QR codes', e);
if (selectedEquipment.length == 1) {
// Un seul équipement : afficher le dialogue simple
showDialog(
context: context,
builder: (context) => QRCodeDialog.forEquipment(selectedEquipment.first),
);
} else {
// Plusieurs équipements : afficher le sélecteur de format
showDialog(
context: context,
builder: (context) => QRCodeFormatSelectorDialog<EquipmentModel>(
itemList: selectedEquipment,
getId: (eq) => eq.id,
getTitle: (eq) => '${eq.brand ?? ''} ${eq.model ?? ''}'.trim(),
dialogTitle: 'Générer ${selectedEquipment.length} QR Code(s)',
),
);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Erreur lors de la génération : ${e.toString()}'),
backgroundColor: Colors.red,
),
);
}
}
}