corections

This commit is contained in:
theShlavuk 2026-01-21 21:11:35 +01:00
parent 9f1cad89be
commit 80618e0b96
3 changed files with 198 additions and 4 deletions

View File

@ -845,6 +845,7 @@ class CRVI_Event_Model extends Main_Model {
'id_intervenant' => $existing_event->id_intervenant ?? null,
'id_traducteur' => $existing_event->id_traducteur ?? null,
'id_local' => $existing_event->id_local ?? null,
'langues_disponibles' => $existing_event->langues_disponibles ?? null,
], $data);
// 5. Valider les données fusionnées (aligné avec create_event)
@ -949,6 +950,38 @@ class CRVI_Event_Model extends Main_Model {
// 7. Calculer automatiquement le flag assign
$update_data['assign'] = self::calculate_assign_flag($update_data);
// 7.5. Traiter langues_disponibles UNIQUEMENT pour les permanences
// Ne pas traiter pour les autres types d'événements pour ne pas casser la mise à jour classique
if (($update_data['type'] ?? '') === 'permanence') {
$langues_disponibles_value = '';
// Si c'est un tableau (langues), le convertir en chaîne séparée par virgules
if (isset($data['langues']) && is_array($data['langues']) && !empty($data['langues'])) {
// Nettoyer et valider les slugs de langues
$langues_valides = [];
foreach ($data['langues'] as $langue_slug) {
$langue_slug = sanitize_text_field($langue_slug);
if (!empty($langue_slug)) {
$langues_valides[] = $langue_slug;
}
}
// Joindre les langues avec le séparateur virgule (,)
if (!empty($langues_valides)) {
$langues_disponibles_value = implode(',', $langues_valides);
}
}
// Si c'est déjà une chaîne (langues_disponibles) - pour mise à jour directe
elseif (isset($data['langues_disponibles'])) {
$langues_disponibles_value = sanitize_text_field($data['langues_disponibles']);
}
// Si aucune langue n'est envoyée, conserver la valeur existante (déjà dans $update_data via array_merge)
// Mettre à jour seulement si une valeur a été fournie
if (isset($data['langues']) || isset($data['langues_disponibles'])) {
$update_data['langues_disponibles'] = $langues_disponibles_value;
}
}
// 8. Ajouter les métadonnées de modification
$update_data['modifie_par'] = get_current_user_id();
$update_data['date_modification'] = current_time('mysql');
@ -959,7 +992,7 @@ class CRVI_Event_Model extends Main_Model {
'date_rdv', 'heure_rdv', 'date_fin', 'heure_fin', 'type', 'statut',
'motif_annulation', 'commentaire', 'id_departement', 'id_type_intervention',
'langue', 'id_beneficiaire', 'id_intervenant', 'id_traducteur', 'id_local',
'assign', 'modifie_par', 'date_modification'
'langues_disponibles', 'assign', 'modifie_par', 'date_modification'
];
$filtered_data = [];

View File

@ -31,7 +31,13 @@ export function initializeAdminPermanences() {
}
// Initialiser Select2 pour le champ langues
// Utiliser un petit délai pour s'assurer que le DOM est complètement prêt
setTimeout(() => {
initializeSelect2();
}, 100);
// Réinitialiser Select2 quand l'onglet devient visible (problème avec éléments cachés)
setupSelect2TabListener();
// Écouter les changements pour mettre à jour l'aperçu
setupPreviewListeners();
@ -46,13 +52,109 @@ export function initializeAdminPermanences() {
initializeCsvImport();
}
// Variable de garde pour éviter les initialisations multiples simultanées
let isInitializingSelect2 = false;
let select2Initialized = false; // Garde globale pour éviter toute réinitialisation
/**
* Initialise Select2 pour le champ de sélection des langues
*/
function initializeSelect2() {
console.log('🔍 initializeSelect2() appelée - Stack:', new Error().stack);
// Éviter les appels multiples simultanés
if (isInitializingSelect2) {
console.log('⏳ Initialisation Select2 déjà en cours, attente...');
return;
}
// Si Select2 est déjà initialisé et fonctionne, ne pas réinitialiser
const languesSelect = document.getElementById('langues-permanences');
if (languesSelect && typeof jQuery !== 'undefined' && jQuery.fn.select2) {
jQuery(languesSelect).select2({
if (languesSelect && select2Initialized) {
const $select = jQuery(languesSelect);
if ($select.data('select2') && $select.hasClass('select2-hidden-accessible')) {
console.log('✅ Select2 déjà initialisé (flag=true), pas de réinitialisation');
return;
}
}
if (!languesSelect) {
console.warn('Select langues-permanences non trouvé');
return;
}
// Vérifier que jQuery et Select2 sont disponibles
if (typeof jQuery === 'undefined' || !jQuery.fn.select2) {
console.warn('jQuery ou Select2 non disponible, réessai dans 100ms...');
setTimeout(initializeSelect2, 100);
return;
}
const $select = jQuery(languesSelect);
// DESTRUCTION AGRESSIVE : Détruire tout Select2 au début, sans pitié !
try {
// Détruire l'instance Select2 si elle existe
if ($select.data('select2')) {
$select.select2('destroy');
}
// Supprimer TOUS les conteneurs Select2 dans le parent
const parentContainer = languesSelect.closest('.card-body') || languesSelect.parentElement;
if (parentContainer) {
// Supprimer tous les conteneurs Select2
const select2Containers = parentContainer.querySelectorAll('span.select2-container');
select2Containers.forEach(container => container.remove());
}
// Nettoyer tous les attributs Select2 du select
$select.removeClass('select2-hidden-accessible');
$select.removeAttr('data-select2-id');
$select.removeAttr('aria-hidden');
$select.removeAttr('tabindex');
console.log('💥 Select2 complètement détruit (méchamment)');
} catch (e) {
console.warn('Erreur lors de la destruction agressive:', e);
}
// Marquer qu'on est en train d'initialiser
isInitializingSelect2 = true;
select2Initialized = false; // Réinitialiser le flag
// Vérifier que le select a des options
const options = languesSelect.querySelectorAll('option');
if (options.length === 0) {
console.warn('Le select langues-permanences n\'a pas d\'options');
isInitializingSelect2 = false;
return;
}
// Initialiser Select2
try {
// Vérifier que les options sont valides
const validOptions = Array.from(options).filter(opt => {
return opt.value && opt.value.trim() !== '' && opt.textContent && opt.textContent.trim() !== '';
});
console.log('📋 Options valides trouvées:', validOptions.length, 'sur', options.length);
if (validOptions.length === 0) {
console.error('Aucune option valide trouvée dans le select');
return;
}
// S'assurer que le select est visible avant l'initialisation
const isVisible = languesSelect.offsetParent !== null;
if (!isVisible) {
console.warn('Le select langues-permanences n\'est pas visible, réessai dans 200ms...');
setTimeout(initializeSelect2, 200);
return;
}
// Initialiser Select2 - laisser Select2 lire automatiquement depuis le select natif
// Ne pas passer data pour éviter les conflits avec le select natif
$select.select2({
placeholder: 'Sélectionnez une ou plusieurs langues',
allowClear: true,
width: '100%',
@ -62,7 +164,56 @@ function initializeSelect2() {
}
}
});
// Vérifier que Select2 a bien chargé les options
setTimeout(() => {
const select2Instance = $select.data('select2');
if (select2Instance) {
// Forcer Select2 à recharger les options depuis le select natif
$select.trigger('change.select2');
console.log('✅ Select2 initialisé pour langues-permanences avec', validOptions.length, 'options');
// Marquer comme initialisé
select2Initialized = true;
} else {
console.warn('⚠️ Select2 n\'a pas été correctement initialisé');
select2Initialized = false;
}
// Libérer la garde
isInitializingSelect2 = false;
}, 50);
} catch (e) {
console.error('Erreur lors de l\'initialisation de Select2:', e);
isInitializingSelect2 = false;
select2Initialized = false;
}
}
/**
* Configure un listener pour réinitialiser Select2 quand l'onglet devient visible
* (uniquement si Select2 n'est pas déjà correctement initialisé)
*/
function setupSelect2TabListener() {
const tabButtons = document.querySelectorAll('#permanences-tabs button[data-bs-toggle="tab"]');
tabButtons.forEach(button => {
button.addEventListener('shown.bs.tab', function(e) {
// Vérifier si l'onglet qui devient visible contient le select langues-permanences
const targetTabId = e.target.getAttribute('data-bs-target');
const targetTab = document.querySelector(targetTabId);
if (targetTab && targetTab.querySelector('#langues-permanences')) {
// Ne PAS réinitialiser si Select2 est déjà initialisé
// La garde globale select2Initialized empêche toute réinitialisation
if (!select2Initialized) {
console.log('🔄 Onglet changé, vérification Select2...');
setTimeout(() => {
initializeSelect2();
}, 100);
} else {
console.log('✅ Select2 déjà initialisé, pas de réinitialisation');
}
}
});
});
}
/**

View File

@ -438,6 +438,16 @@ export async function handleEventFormSubmit(mode, eventId = null, onSuccess = nu
const formData = new FormData(form);
let data = Object.fromEntries(formData.entries());
// Gérer les champs multiples (comme langues[]) UNIQUEMENT pour les permanences
// Ne pas traiter pour les autres types d'événements pour ne pas casser la mise à jour classique
if (data.type === 'permanence') {
const langues = formData.getAll('langues[]');
if (langues && langues.length > 0) {
// Filtrer les valeurs vides et convertir en tableau de slugs
data.langues = langues.filter(value => value !== '' && value !== null);
}
}
// Validation côté client
const errors = validateForm(data, mode);
if (Object.keys(errors).length > 0) {