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 { Future<void> _generateQRCodesForSelected() async {
if (!hasSelection) return; if (!hasSelection) return;
// Récupérer les containers sélectionnés // Afficher un indicateur de chargement
final containerProvider = context.read<ContainerProvider>(); showDialog(
final List<ContainerModel> selectedContainers = []; context: context,
final Map<String, List<EquipmentModel>> containerEquipmentMap = {}; barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(color: AppColors.rouge),
),
);
for (final id in selectedIds) { try {
final container = await containerProvider.getContainerById(id); // Récupérer les containers sélectionnés
if (container != null) { final containerProvider = context.read<ContainerProvider>();
selectedContainers.add(container); final List<ContainerModel> selectedContainers = [];
// Charger les équipements pour ce container final Map<String, List<EquipmentModel>> containerEquipmentMap = {};
final equipment = await containerProvider.getContainerEquipment(id);
containerEquipmentMap[id] = equipment; 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) { if (mounted) {
ScaffoldMessenger.of(context).showSnackBar( Navigator.of(context).pop();
const SnackBar(content: Text('Aucun container trouvé')), }
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 DebugLog.error('[ContainerManagementPage] Error generating QR codes', e);
if (mounted) {
showDialog( if (mounted) {
context: context, ScaffoldMessenger.of(context).showSnackBar(
builder: (context) => QRCodeFormatSelectorDialog<ContainerModel>( SnackBar(
itemList: selectedContainers, content: Text('Erreur lors de la génération : ${e.toString()}'),
getId: (c) => c.id, backgroundColor: Colors.red,
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)',
),
);
} }
} }

View File

@@ -791,39 +791,75 @@ class _EquipmentManagementPageState extends State<EquipmentManagementPage>
void _generateQRCodesForSelected() async { void _generateQRCodesForSelected() async {
if (!hasSelection) return; if (!hasSelection) return;
// Récupérer les équipements sélectionnés // Afficher un indicateur de chargement
final provider = context.read<EquipmentProvider>(); showDialog(
final List<EquipmentModel> selectedEquipment = []; context: context,
barrierDismissible: false,
builder: (context) => const Center(
child: CircularProgressIndicator(color: AppColors.rouge),
),
);
// On doit récupérer les équipements depuis le stream try {
await for (final equipmentList in provider.equipmentStream.take(1)) { // Récupérer les équipements sélectionnés
for (final equipment in equipmentList) { final provider = context.read<EquipmentProvider>();
if (isItemSelected(equipment.id)) { final List<EquipmentModel> selectedEquipment = [];
selectedEquipment.add(equipment);
// 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) { if (mounted) {
// Un seul équipement : afficher le dialogue simple ScaffoldMessenger.of(context).showSnackBar(
showDialog( SnackBar(
context: context, content: Text('Erreur lors de la génération : ${e.toString()}'),
builder: (context) => QRCodeDialog.forEquipment(selectedEquipment.first), backgroundColor: Colors.red,
); ),
} 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)',
),
);
} }
} }