up agenda filter search param
This commit is contained in:
parent
b18c2c5aec
commit
542d1d08d8
1 changed files with 106 additions and 13 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue