amélioration capacité traductions

This commit is contained in:
theShlavuk 2026-01-21 23:24:07 +01:00
parent a815a21d1b
commit 760e4d4f78
4 changed files with 232 additions and 2 deletions

View File

@ -93,6 +93,11 @@ class CRVI_Event_Controller {
'callback' => [self::class, 'get_statuts'], 'callback' => [self::class, 'get_statuts'],
'permission_callback' => '__return_true', 'permission_callback' => '__return_true',
]); ]);
\register_rest_route('crvi/v1', '/filters/traductions-capacites', [
'methods' => 'GET',
'callback' => [self::class, 'get_traductions_capacites'],
'permission_callback' => '__return_true',
]);
// --- Historique bénéficiaire --- // --- Historique bénéficiaire ---
\register_rest_route('crvi/v1', '/beneficiaires/(?P<id>\\d+)/historique', [ \register_rest_route('crvi/v1', '/beneficiaires/(?P<id>\\d+)/historique', [
@ -1920,6 +1925,26 @@ class CRVI_Event_Controller {
return Api_Helper::json_success($statuts); return Api_Helper::json_success($statuts);
} }
/**
* Récupère les capacités de traduction avec une plage de dates
* GET /crvi/v1/filters/traductions-capacites?date_debut=2025-01-01&date_fin=2025-01-31
*/
public static function get_traductions_capacites($request) {
$params = $request->get_params();
$date_debut = $params['date_debut'] ?? null;
$date_fin = $params['date_fin'] ?? null;
// Vérifier que la classe du modèle existe
if (!class_exists('\ESI_CRVI_AGENDA\models\CRVI_TraductionLangue_Model')) {
return Api_Helper::json_error('Modèle de traduction non disponible', 500);
}
// Utiliser la méthode du modèle qui gère le cache avec la plage de dates
$capacites = \ESI_CRVI_AGENDA\models\CRVI_TraductionLangue_Model::getAllLanguesCapacitesForACF($date_debut, $date_fin, true);
return Api_Helper::json_success($capacites);
}
/** /**
* Vérifie si l'utilisateur peut modifier un événement * Vérifie si l'utilisateur peut modifier un événement
* @param \WP_REST_Request $request * @param \WP_REST_Request $request

View File

@ -1172,6 +1172,25 @@ class CRVI_Event_Model extends Main_Model {
$where = []; $where = [];
$values = []; $values = [];
// Traitement spécial pour le filtre langue (inclure les permanences avec langues_disponibles)
$langue_filter_value = null;
$langue_slug = null;
if (!empty($params['langue']) || (isset($params['langue']) && $params['langue'] === '0')) {
$langue_filter_value = $params['langue'];
// Essayer d'obtenir le slug de la langue à partir de l'ID
$langue_term = get_term((int)$langue_filter_value, 'langue');
if ($langue_term && !is_wp_error($langue_term)) {
$langue_slug = $langue_term->slug;
} else {
// Si ce n'est pas un ID, essayer comme slug directement
$langue_term = get_term_by('slug', $langue_filter_value, 'langue');
if ($langue_term && !is_wp_error($langue_term)) {
$langue_slug = $langue_term->slug;
}
}
}
// Traitement des filtres // Traitement des filtres
foreach ($map as $api => $col) { foreach ($map as $api => $col) {
if (!empty($params[$api]) || (isset($params[$api]) && $params[$api] === '0')) { if (!empty($params[$api]) || (isset($params[$api]) && $params[$api] === '0')) {
@ -1185,6 +1204,19 @@ class CRVI_Event_Model extends Main_Model {
// Support du filtre assign (0 ou 1) // Support du filtre assign (0 ou 1)
$where[] = "$col = %d"; $where[] = "$col = %d";
$values[] = (int)$params[$api]; $values[] = (int)$params[$api];
} elseif ($api === 'langue') {
// Filtre langue spécial : inclure les rendez-vous avec cette langue
// ET les permanences avec cette langue dans langues_disponibles
if ($langue_slug) {
// Inclure les événements avec langue = ID OU les permanences avec langues_disponibles contenant le slug
$where[] = "($col = %s OR (type = 'permanence' AND langues_disponibles LIKE %s))";
$values[] = $langue_filter_value;
$values[] = '%' . $wpdb->esc_like($langue_slug) . '%';
} else {
// Fallback : comportement normal si on ne trouve pas le slug
$where[] = "$col = %s";
$values[] = $langue_filter_value;
}
} else { } else {
$where[] = "$col = %s"; $where[] = "$col = %s";
$values[] = $params[$api]; $values[] = $params[$api];
@ -1471,6 +1503,25 @@ class CRVI_Event_Model extends Main_Model {
$where = []; $where = [];
$values = []; $values = [];
// Traitement spécial pour le filtre langue (inclure les permanences avec langues_disponibles)
$langue_filter_value = null;
$langue_slug = null;
if (!empty($params['langue']) || (isset($params['langue']) && $params['langue'] === '0')) {
$langue_filter_value = $params['langue'];
// Essayer d'obtenir le slug de la langue à partir de l'ID
$langue_term = get_term((int)$langue_filter_value, 'langue');
if ($langue_term && !is_wp_error($langue_term)) {
$langue_slug = $langue_term->slug;
} else {
// Si ce n'est pas un ID, essayer comme slug directement
$langue_term = get_term_by('slug', $langue_filter_value, 'langue');
if ($langue_term && !is_wp_error($langue_term)) {
$langue_slug = $langue_term->slug;
}
}
}
// Traitement des filtres // Traitement des filtres
foreach ($map as $api => $col) { foreach ($map as $api => $col) {
if (!empty($params[$api]) || (isset($params[$api]) && $params[$api] === '0')) { if (!empty($params[$api]) || (isset($params[$api]) && $params[$api] === '0')) {
@ -1483,6 +1534,19 @@ class CRVI_Event_Model extends Main_Model {
} elseif ($api === 'assign') { } elseif ($api === 'assign') {
$where[] = "$col = %d"; $where[] = "$col = %d";
$values[] = (int)$params[$api]; $values[] = (int)$params[$api];
} elseif ($api === 'langue') {
// Filtre langue spécial : inclure les rendez-vous avec cette langue
// ET les permanences avec cette langue dans langues_disponibles
if ($langue_slug) {
// Inclure les événements avec langue = ID OU les permanences avec langues_disponibles contenant le slug
$where[] = "($col = %s OR (type = 'permanence' AND langues_disponibles LIKE %s))";
$values[] = $langue_filter_value;
$values[] = '%' . $wpdb->esc_like($langue_slug) . '%';
} else {
// Fallback : comportement normal si on ne trouve pas le slug
$where[] = "$col = %s";
$values[] = $langue_filter_value;
}
} else { } else {
$where[] = "$col = %s"; $where[] = "$col = %s";
$values[] = $params[$api]; $values[] = $params[$api];

View File

@ -98,3 +98,12 @@ export async function getFilters(type, params = {}) {
} }
return apiFetch(`filters/${type}`); return apiFetch(`filters/${type}`);
} }
export async function getTraductionsCapacites(date_debut, date_fin) {
const params = {};
if (date_debut) params.date_debut = date_debut;
if (date_fin) params.date_fin = date_fin;
const query = new URLSearchParams(params).toString();
const endpoint = `filters/traductions-capacites${query ? '?' + query : ''}`;
return apiFetch(endpoint);
}

View File

@ -3,12 +3,17 @@
* Filtres par département et capacités de traduction * Filtres par département et capacités de traduction
*/ */
import { getTraductionsCapacites } from './agenda-api.js';
class AgendaVisualFilters { class AgendaVisualFilters {
constructor() { constructor() {
this.departements = window.crviACFData?.departements || {}; this.departements = window.crviACFData?.departements || {};
this.traductions = window.crviACFData?.traductions_capacites || {}; this.traductions = window.crviACFData?.traductions_capacites || {};
this.selectedDepartement = null; this.selectedDepartement = null;
this.selectedTraduction = null; this.selectedTraduction = null;
this.currentDateDebut = null;
this.currentDateFin = null;
this.calendarInstance = null;
this.departementsContainer = document.getElementById('departements-filter-buttons'); this.departementsContainer = document.getElementById('departements-filter-buttons');
this.traductionsContainer = document.getElementById('traductions-filter-buttons'); this.traductionsContainer = document.getElementById('traductions-filter-buttons');
@ -22,6 +27,41 @@ class AgendaVisualFilters {
this.renderDepartementsButtons(); this.renderDepartementsButtons();
this.renderTraductionsButtons(); this.renderTraductionsButtons();
this.setupEventListeners(); this.setupEventListeners();
// Initialiser les dates depuis le calendrier si disponible
this.initializeDatesFromCalendar();
}
/**
* Initialise les dates depuis le calendrier au chargement
*/
initializeDatesFromCalendar() {
// Attendre que le calendrier soit disponible
const checkCalendar = () => {
if (window.currentCalendar) {
try {
const view = window.currentCalendar.view;
if (view && view.activeStart && view.activeEnd) {
const startStr = view.activeStart.toISOString().split('T')[0];
const endStr = view.activeEnd.toISOString().split('T')[0];
this.currentDateDebut = startStr;
this.currentDateFin = endStr;
console.log('📅 Dates initiales du calendrier:', { start: startStr, end: endStr });
// Recharger les capacités pour cette période initiale
this.reloadTraductionsCapacites(startStr, endStr);
}
} catch (error) {
console.warn('⚠️ Impossible de récupérer les dates initiales du calendrier:', error);
}
} else {
// Réessayer après un court délai
setTimeout(checkCalendar, 200);
}
};
// Attendre un peu plus longtemps pour que le calendrier soit complètement initialisé
setTimeout(checkCalendar, 500);
} }
/** /**
@ -220,9 +260,16 @@ class AgendaVisualFilters {
if (filters.traduction) { if (filters.traduction) {
const langueSelect = document.getElementById('langue_filtre'); const langueSelect = document.getElementById('langue_filtre');
if (langueSelect) { if (langueSelect) {
// La valeur doit correspondre au slug de la langue // Récupérer l'ID de la langue depuis les données de traduction
const traductionData = this.traductions[filters.traduction];
if (traductionData && traductionData.id) {
// Utiliser l'ID de la langue pour le filtre
langueSelect.value = traductionData.id;
} else {
// Fallback : utiliser le slug si l'ID n'est pas disponible
langueSelect.value = filters.traduction; langueSelect.value = filters.traduction;
} }
}
} else { } else {
const langueSelect = document.getElementById('langue_filtre'); const langueSelect = document.getElementById('langue_filtre');
if (langueSelect) { if (langueSelect) {
@ -265,6 +312,91 @@ class AgendaVisualFilters {
this.renderTraductionsButtons(); this.renderTraductionsButtons();
}); });
} }
// Écouter les changements de vue/dates de FullCalendar
this.setupCalendarListeners();
}
/**
* Configure les écouteurs pour les changements de vue/dates du calendrier
*/
setupCalendarListeners() {
// Attendre que le calendrier soit disponible
const checkCalendar = () => {
if (window.currentCalendar) {
this.calendarInstance = window.currentCalendar;
// Écouter l'événement datesSet de FullCalendar (déclenché lors des changements de dates/vue)
this.calendarInstance.on('datesSet', (arg) => {
this.handleCalendarDatesChange(arg);
});
console.log('✅ Écouteur datesSet configuré pour les filtres visuels');
} else {
// Réessayer après un court délai
setTimeout(checkCalendar, 100);
}
};
checkCalendar();
}
/**
* Gère les changements de dates/vue du calendrier
*/
async handleCalendarDatesChange(arg) {
const startStr = arg.startStr.split('T')[0];
const endStr = arg.endStr.split('T')[0];
// Vérifier si les dates ont vraiment changé
if (this.currentDateDebut === startStr && this.currentDateFin === endStr) {
return; // Pas de changement, ne rien faire
}
this.currentDateDebut = startStr;
this.currentDateFin = endStr;
console.log('📅 Changement de dates/vue détecté:', { start: startStr, end: endStr, view: arg.view.type });
// Recharger les capacités de traduction pour la nouvelle période
await this.reloadTraductionsCapacites(startStr, endStr);
}
/**
* Recharge les capacités de traduction pour une période donnée
*/
async reloadTraductionsCapacites(date_debut, date_fin) {
try {
console.log('🔄 Rechargement des capacités de traduction pour:', { date_debut, date_fin });
const capacites = await getTraductionsCapacites(date_debut, date_fin);
if (capacites && typeof capacites === 'object') {
this.traductions = capacites;
// Sauvegarder la sélection actuelle
const currentSelection = this.selectedTraduction;
// Re-rendre les boutons avec les nouvelles données
this.renderTraductionsButtons();
// Restaurer la sélection si elle existe toujours
if (currentSelection && this.traductions[currentSelection]) {
this.selectedTraduction = currentSelection;
const btnId = `trad-${currentSelection}`;
const activeBtn = document.getElementById(btnId);
if (activeBtn) {
activeBtn.classList.add('active');
}
}
console.log('✅ Capacités de traduction mises à jour');
} else {
console.warn('⚠️ Aucune donnée de capacité reçue');
}
} catch (error) {
console.error('❌ Erreur lors du rechargement des capacités:', error);
}
} }
/** /**