feat: Ajout de la gestion des utilisateurs et optimisation du chargement des données
Cette mise à jour introduit la gestion complète des utilisateurs (création, mise à jour, suppression) via des Cloud Functions et optimise de manière significative le chargement des données dans toute l'application.
**Features :**
- **Gestion des utilisateurs (Backend & Frontend) :**
- Ajout des Cloud Functions `getUser`, `updateUser` et `deleteUser` pour gérer les utilisateurs de manière sécurisée, en respectant les permissions des rôles.
- L'authentification passe désormais par `onCall` pour plus de sécurité.
- **Optimisation du chargement des données :**
- Introduction de nouvelles Cloud Functions `getEquipmentsByIds` et `getContainersByIds` pour récupérer uniquement les documents nécessaires, réduisant ainsi la charge sur le client et Firestore.
- Les fournisseurs (`EquipmentProvider`, `ContainerProvider`) ont été refactorisés pour utiliser un chargement à la demande (`ensureLoaded`) et mettre en cache les données récupérées.
- Les écrans de détails et de préparation d'événements n'utilisent plus de `Stream` globaux, mais chargent les équipements et boites spécifiques via ces nouvelles fonctions, améliorant considérablement les performances.
**Refactorisation et Améliorations :**
- **Backend (Cloud Functions) :**
- Le service de vérification de disponibilité (`checkEquipmentAvailability`) est désormais une Cloud Function, déplaçant la logique métier côté serveur.
- La récupération des données (utilisateurs, événements, alertes) a été centralisée derrière des Cloud Functions, remplaçant les appels directs à Firestore depuis le client.
- Amélioration de la sérialisation des données (timestamps, références) dans les réponses des fonctions.
- **Frontend (Flutter) :**
- `LocalUserProvider` charge désormais les informations de l'utilisateur connecté via la fonction `getCurrentUser`, incluant son rôle et ses permissions en un seul appel.
- `AlertProvider` utilise des fonctions pour charger et manipuler les alertes, abandonnant le `Stream` Firestore.
- `EventAvailabilityService` utilise maintenant la Cloud Function `checkEquipmentAvailability` au lieu d'une logique client complexe.
- Correction de la gestion des références de rôles (`roles/ADMIN`) et des `DocumentReference` pour les utilisateurs dans l'ensemble de l'application.
- Le service d'export ICS (`IcsExportService`) a été simplifié, partant du principe que les données nécessaires (utilisateurs, options) sont déjà chargées dans l'application.
This commit is contained in:
@@ -15,6 +15,11 @@ class EquipmentProvider extends ChangeNotifier {
|
||||
String? _selectedModel;
|
||||
String _searchQuery = '';
|
||||
bool _isLoading = false;
|
||||
bool _isInitialized = false; // Flag pour savoir si les équipements ont été chargés
|
||||
|
||||
// Constructeur - Ne charge PAS automatiquement
|
||||
// Les équipements seront chargés à la demande (page de gestion ou via getEquipmentsByIds)
|
||||
EquipmentProvider();
|
||||
|
||||
// Getters
|
||||
List<EquipmentModel> get equipment => _filteredEquipment;
|
||||
@@ -25,8 +30,19 @@ class EquipmentProvider extends ChangeNotifier {
|
||||
String? get selectedModel => _selectedModel;
|
||||
String get searchQuery => _searchQuery;
|
||||
bool get isLoading => _isLoading;
|
||||
bool get isInitialized => _isInitialized;
|
||||
|
||||
/// Charger tous les équipements via l'API
|
||||
/// S'assure que les équipements sont chargés (charge si nécessaire)
|
||||
Future<void> ensureLoaded() async {
|
||||
if (_isInitialized || _isLoading) {
|
||||
print('[EquipmentProvider] Equipment already loaded or loading, skipping...');
|
||||
return;
|
||||
}
|
||||
print('[EquipmentProvider] Equipment not loaded, loading now...');
|
||||
await loadEquipments();
|
||||
}
|
||||
|
||||
/// Charger tous les équipements via l'API (utilisé par la page de gestion)
|
||||
Future<void> loadEquipments() async {
|
||||
print('[EquipmentProvider] Starting to load equipments...');
|
||||
_isLoading = true;
|
||||
@@ -45,6 +61,8 @@ class EquipmentProvider extends ChangeNotifier {
|
||||
// Extraire les modèles et marques uniques
|
||||
_extractUniqueValues();
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
_isLoading = false;
|
||||
notifyListeners();
|
||||
print('[EquipmentProvider] Equipment loading complete');
|
||||
@@ -56,6 +74,70 @@ class EquipmentProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge plusieurs équipements par leurs IDs (optimisé pour les détails d'événement)
|
||||
Future<List<EquipmentModel>> getEquipmentsByIds(List<String> equipmentIds) async {
|
||||
if (equipmentIds.isEmpty) return [];
|
||||
|
||||
print('[EquipmentProvider] Loading ${equipmentIds.length} equipments by IDs...');
|
||||
|
||||
try {
|
||||
// Vérifier d'abord le cache local
|
||||
final cachedEquipments = <EquipmentModel>[];
|
||||
final missingIds = <String>[];
|
||||
|
||||
for (final id in equipmentIds) {
|
||||
final cached = _equipment.firstWhere(
|
||||
(eq) => eq.id == id,
|
||||
orElse: () => EquipmentModel(
|
||||
id: '',
|
||||
name: '',
|
||||
category: EquipmentCategory.other,
|
||||
status: EquipmentStatus.available,
|
||||
parentBoxIds: [],
|
||||
maintenanceIds: [],
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
),
|
||||
);
|
||||
|
||||
if (cached.id.isNotEmpty) {
|
||||
cachedEquipments.add(cached);
|
||||
} else {
|
||||
missingIds.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
print('[EquipmentProvider] Found ${cachedEquipments.length} in cache, ${missingIds.length} missing');
|
||||
|
||||
// Si tous sont en cache, retourner directement
|
||||
if (missingIds.isEmpty) {
|
||||
return cachedEquipments;
|
||||
}
|
||||
|
||||
// Charger les manquants depuis l'API
|
||||
final equipmentsData = await _dataService.getEquipmentsByIds(missingIds);
|
||||
|
||||
final loadedEquipments = equipmentsData.map((data) {
|
||||
return EquipmentModel.fromMap(data, data['id'] as String);
|
||||
}).toList();
|
||||
|
||||
// Ajouter au cache
|
||||
for (final eq in loadedEquipments) {
|
||||
if (!_equipment.any((e) => e.id == eq.id)) {
|
||||
_equipment.add(eq);
|
||||
}
|
||||
}
|
||||
|
||||
print('[EquipmentProvider] Loaded ${loadedEquipments.length} equipments from API');
|
||||
|
||||
// Retourner tous les équipements (cache + chargés)
|
||||
return [...cachedEquipments, ...loadedEquipments];
|
||||
} catch (e) {
|
||||
print('[EquipmentProvider] Error loading equipments by IDs: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Extraire modèles et marques uniques
|
||||
void _extractUniqueValues() {
|
||||
final modelSet = <String>{};
|
||||
|
||||
Reference in New Issue
Block a user