feat: Filtres membres/secteurs dynamiques et liés (#42)
- Filtrage croisé via box user_sector (UserSectorModel) - Si secteur sélectionné → membres filtrés (uniquement ce secteur) - Si membre sélectionné → secteurs filtrés (uniquement ses secteurs) - Relation : UserSectorModel.opeUserId ↔ UserSectorModel.fkSector - Import UserSectorModel ajouté - Simplification dropdown secteurs (liste directe, plus de map) Comportement : 1. Aucun filtre → tous les membres et tous les secteurs 2. Secteur choisi → liste membres réduite 3. Membre choisi → liste secteurs réduite 4. Les deux choisis → affichage le plus restreint 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import 'package:geosector_app/core/constants/app_keys.dart';
|
|||||||
import 'package:geosector_app/core/services/current_user_service.dart';
|
import 'package:geosector_app/core/services/current_user_service.dart';
|
||||||
import 'package:geosector_app/core/theme/app_theme.dart';
|
import 'package:geosector_app/core/theme/app_theme.dart';
|
||||||
import 'package:geosector_app/core/data/models/passage_model.dart';
|
import 'package:geosector_app/core/data/models/passage_model.dart';
|
||||||
|
import 'package:geosector_app/core/data/models/user_sector_model.dart';
|
||||||
import 'package:geosector_app/presentation/widgets/passages/passages_list_widget.dart';
|
import 'package:geosector_app/presentation/widgets/passages/passages_list_widget.dart';
|
||||||
import 'package:geosector_app/presentation/widgets/passage_form_dialog.dart';
|
import 'package:geosector_app/presentation/widgets/passage_form_dialog.dart';
|
||||||
import 'package:geosector_app/presentation/widgets/app_scaffold.dart';
|
import 'package:geosector_app/presentation/widgets/app_scaffold.dart';
|
||||||
@@ -621,11 +622,22 @@ class _HistoryContentState extends State<HistoryContent> {
|
|||||||
Widget _buildMemberDropdown() {
|
Widget _buildMemberDropdown() {
|
||||||
// Récupérer tous les membres depuis la box Hive
|
// Récupérer tous les membres depuis la box Hive
|
||||||
final membresBox = membreRepository.getMembresBox();
|
final membresBox = membreRepository.getMembresBox();
|
||||||
final membres = membresBox.values.where((membre) {
|
var membres = membresBox.values.where((membre) {
|
||||||
// Ne garder que les membres ayant un opeUserId (membres actifs dans une opération)
|
// Ne garder que les membres ayant un opeUserId (membres actifs dans une opération)
|
||||||
return membre.opeUserId != null;
|
return membre.opeUserId != null;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
|
// Filtrage dynamique : si un secteur est sélectionné, ne montrer que les membres de ce secteur
|
||||||
|
if (_selectedSectorId != null) {
|
||||||
|
final userSectorsBox = Hive.box<UserSectorModel>(AppKeys.userSectorBoxName);
|
||||||
|
final memberIdsInSector = userSectorsBox.values
|
||||||
|
.where((us) => us.fkSector == _selectedSectorId)
|
||||||
|
.map((us) => us.opeUserId)
|
||||||
|
.toSet();
|
||||||
|
|
||||||
|
membres = membres.where((membre) => memberIdsInSector.contains(membre.opeUserId)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
// Trier par nom
|
// Trier par nom
|
||||||
membres.sort((a, b) {
|
membres.sort((a, b) {
|
||||||
final nameA = a.name ?? a.firstName ?? '';
|
final nameA = a.name ?? a.firstName ?? '';
|
||||||
@@ -688,27 +700,22 @@ class _HistoryContentState extends State<HistoryContent> {
|
|||||||
|
|
||||||
/// Construit le dropdown de sélection de secteur (admin uniquement)
|
/// Construit le dropdown de sélection de secteur (admin uniquement)
|
||||||
Widget _buildSectorDropdown() {
|
Widget _buildSectorDropdown() {
|
||||||
// Récupérer les secteurs uniques depuis les passages de l'opération courante
|
// Récupérer tous les secteurs depuis le repository
|
||||||
final sectorIds = <int>{};
|
var allSectors = sectorRepository.getAllSectors();
|
||||||
|
|
||||||
for (final passage in _originalPassages) {
|
// Filtrage dynamique : si un membre est sélectionné, ne montrer que ses secteurs
|
||||||
if (passage.fkSector != null && !sectorIds.contains(passage.fkSector)) {
|
if (_selectedMemberId != null) {
|
||||||
sectorIds.add(passage.fkSector!);
|
final userSectorsBox = Hive.box<UserSectorModel>(AppKeys.userSectorBoxName);
|
||||||
}
|
final sectorIdsForMember = userSectorsBox.values
|
||||||
}
|
.where((us) => us.opeUserId == _selectedMemberId)
|
||||||
|
.map((us) => us.fkSector)
|
||||||
|
.toSet();
|
||||||
|
|
||||||
// Récupérer les noms des secteurs depuis le repository
|
allSectors = allSectors.where((sector) => sectorIdsForMember.contains(sector.id)).toList();
|
||||||
final allSectors = sectorRepository.getAllSectors();
|
|
||||||
final sectorNames = <int, String>{};
|
|
||||||
for (final sector in allSectors) {
|
|
||||||
if (sectorIds.contains(sector.id)) {
|
|
||||||
sectorNames[sector.id] = sector.libelle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trier par nom
|
// Trier par nom
|
||||||
final sortedSectors = sectorIds.toList()
|
allSectors.sort((a, b) => a.libelle.compareTo(b.libelle));
|
||||||
..sort((a, b) => (sectorNames[a] ?? '').compareTo(sectorNames[b] ?? ''));
|
|
||||||
|
|
||||||
return DropdownButtonFormField<int?>(
|
return DropdownButtonFormField<int?>(
|
||||||
value: _selectedSectorId,
|
value: _selectedSectorId,
|
||||||
@@ -724,11 +731,11 @@ class _HistoryContentState extends State<HistoryContent> {
|
|||||||
value: null,
|
value: null,
|
||||||
child: Text('Tous'),
|
child: Text('Tous'),
|
||||||
),
|
),
|
||||||
...sortedSectors.map((sectorId) {
|
...allSectors.map((sector) {
|
||||||
return DropdownMenuItem<int?>(
|
return DropdownMenuItem<int?>(
|
||||||
value: sectorId,
|
value: sector.id,
|
||||||
child: Text(
|
child: Text(
|
||||||
sectorNames[sectorId] ?? 'Secteur #$sectorId',
|
sector.libelle,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user