up agenda filter search param

This commit is contained in:
Tykayn 2025-11-03 00:48:04 +01:00 committed by tykayn
parent b18c2c5aec
commit 542d1d08d8

View file

@ -92,6 +92,22 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
const limitParam = map.get('limit');
const limit = limitParam ? Number(limitParam) : null;
const viewParam = (map.get('view') || '').trim();
const searchParam = (map.get('search') || '').trim();
// Gérer le paramètre search pour préremplir le champ de recherche
// Ignorer si c'est le même que celui déjà présent (pour éviter les boucles)
const decodedSearch = searchParam ? decodeURIComponent(searchParam) : '';
if (this.filterText !== decodedSearch) {
this.filterText = decodedSearch;
// Déclencher le filtre directement sans passer par le Subject pour éviter le debounce
if (decodedSearch) {
// Appliquer le filtre immédiatement
this.applyWhatFilter();
} else {
// Si le paramètre est vide ou absent, réinitialiser le filtre
this.applyWhatFilter();
}
}
// Définir le filtre what avant de charger les événements
if (what) {
@ -222,7 +238,9 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
}
convertToCalendarEvents() {
const source = this.filteredEvents.length ? this.filteredEvents : this.events;
// Toujours utiliser filteredEvents si un filtre est actif (texte ou what)
const hasActiveFilter = this.filterText.trim() || this.selectedWhatFilter;
const source = (hasActiveFilter || this.filteredEvents.length > 0) ? this.filteredEvents : this.events;
this.calendarEvents = source.map(event => {
const startDate = this.parseEventDate(event.properties.start || event.properties.when);
const endDate = event.properties.stop ? this.parseEventDate(event.properties.stop) : null;
@ -297,6 +315,58 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
this.availableWhatTypes = Array.from(set).sort();
}
/**
* Normalise un texte en enlevant les accents et en mettant en minuscule
* pour permettre une recherche insensible à la casse et aux accents
*/
private normalizeText(text: string): string {
if (!text) return '';
return text
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, ''); // Enlève les accents
}
/**
* Cherche récursivement dans toutes les propriétés d'un objet
* pour trouver si une valeur correspond au texte de recherche
*/
private searchInObject(obj: any, searchText: string): boolean {
if (!obj || searchText === '') return false;
const normalizedSearch = this.normalizeText(searchText);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
// Si c'est un objet ou un tableau, chercher récursivement
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
// Chercher dans chaque élément du tableau
if (value.some(item => this.searchInObject(item, searchText))) {
return true;
}
} else {
// Chercher récursivement dans l'objet
if (this.searchInObject(value, searchText)) {
return true;
}
}
} else {
// Convertir en string et chercher
const stringValue = String(value);
const normalizedValue = this.normalizeText(stringValue);
if (normalizedValue.includes(normalizedSearch)) {
return true;
}
}
}
}
return false;
}
applyWhatFilter() {
console.log('🔍 Application du filtre what:', this.selectedWhatFilter);
console.log('📊 Événements avant filtrage:', this.events.length);
@ -313,17 +383,12 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
// Appliquer le filtre texte si présent
if (this.filterText.trim()) {
const searchText = this.filterText.trim().toLowerCase();
const searchText = this.filterText.trim();
filtered = filtered.filter(e => {
const props = e?.properties || {};
return (
(props.label || '').toLowerCase().includes(searchText) ||
(props.name || '').toLowerCase().includes(searchText) ||
(props.description || '').toLowerCase().includes(searchText) ||
(props.what || '').toLowerCase().includes(searchText) ||
(props.where || '').toLowerCase().includes(searchText)
);
// Chercher dans tout l'objet événement (properties, geometry, etc.)
return this.searchInObject(e, searchText);
});
console.log('✅ Événements après filtrage texte:', filtered.length);
}
this.filteredEvents = filtered;
@ -340,8 +405,32 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
}
filterEventsByText(text: string) {
this.filterText = text;
const trimmedText = text ? text.trim() : '';
this.filterText = trimmedText;
this.applyWhatFilter();
// Mettre à jour l'URL avec le paramètre search (seulement si différent de l'URL actuelle)
const currentSearchParam = this.route.snapshot.queryParamMap.get('search') || '';
const decodedCurrentSearch = currentSearchParam ? decodeURIComponent(currentSearchParam) : '';
// Ne mettre à jour l'URL que si la valeur a changé
if (decodedCurrentSearch !== trimmedText) {
const currentParams = { ...this.route.snapshot.queryParams };
if (trimmedText) {
// Encoder le texte de recherche pour l'URL
currentParams['search'] = encodeURIComponent(trimmedText);
} else {
// Supprimer le paramètre search si le champ est vide
delete currentParams['search'];
}
this.router.navigate([], {
relativeTo: this.route,
queryParams: currentParams,
queryParamsHandling: 'merge',
replaceUrl: true // Utiliser replaceUrl pour éviter d'ajouter des entrées dans l'historique
});
}
}
onWhatFilterChange(value: string) {
@ -362,7 +451,9 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
buildGroupedEvents() {
const groups: Record<string, { date: Date; items: OedbEvent[] }> = {};
const source = this.filteredEvents.length ? this.filteredEvents : this.events;
// Toujours utiliser filteredEvents si un filtre est actif (texte ou what)
const hasActiveFilter = this.filterText.trim() || this.selectedWhatFilter;
const source = (hasActiveFilter || this.filteredEvents.length > 0) ? this.filteredEvents : this.events;
for (const ev of source) {
const d = this.getEventStartDate(ev);
const key = this.toDateKey(d);
@ -423,7 +514,9 @@ export class Agenda implements OnInit, OnDestroy, AfterViewInit {
const selectedDateKey = this.toDateKey(this.selectedDate);
const groups: Record<string, { date: Date; items: OedbEvent[] }> = {};
const source = this.filteredEvents.length ? this.filteredEvents : this.events;
// Toujours utiliser filteredEvents si un filtre est actif (texte ou what)
const hasActiveFilter = this.filterText.trim() || this.selectedWhatFilter;
const source = (hasActiveFilter || this.filteredEvents.length > 0) ? this.filteredEvents : this.events;
for (const ev of source) {
const d = this.getEventStartDate(ev);