corections
This commit is contained in:
parent
9f1cad89be
commit
80618e0b96
@ -845,6 +845,7 @@ class CRVI_Event_Model extends Main_Model {
|
|||||||
'id_intervenant' => $existing_event->id_intervenant ?? null,
|
'id_intervenant' => $existing_event->id_intervenant ?? null,
|
||||||
'id_traducteur' => $existing_event->id_traducteur ?? null,
|
'id_traducteur' => $existing_event->id_traducteur ?? null,
|
||||||
'id_local' => $existing_event->id_local ?? null,
|
'id_local' => $existing_event->id_local ?? null,
|
||||||
|
'langues_disponibles' => $existing_event->langues_disponibles ?? null,
|
||||||
], $data);
|
], $data);
|
||||||
|
|
||||||
// 5. Valider les données fusionnées (aligné avec create_event)
|
// 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
|
// 7. Calculer automatiquement le flag assign
|
||||||
$update_data['assign'] = self::calculate_assign_flag($update_data);
|
$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
|
// 8. Ajouter les métadonnées de modification
|
||||||
$update_data['modifie_par'] = get_current_user_id();
|
$update_data['modifie_par'] = get_current_user_id();
|
||||||
$update_data['date_modification'] = current_time('mysql');
|
$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',
|
'date_rdv', 'heure_rdv', 'date_fin', 'heure_fin', 'type', 'statut',
|
||||||
'motif_annulation', 'commentaire', 'id_departement', 'id_type_intervention',
|
'motif_annulation', 'commentaire', 'id_departement', 'id_type_intervention',
|
||||||
'langue', 'id_beneficiaire', 'id_intervenant', 'id_traducteur', 'id_local',
|
'langue', 'id_beneficiaire', 'id_intervenant', 'id_traducteur', 'id_local',
|
||||||
'assign', 'modifie_par', 'date_modification'
|
'langues_disponibles', 'assign', 'modifie_par', 'date_modification'
|
||||||
];
|
];
|
||||||
|
|
||||||
$filtered_data = [];
|
$filtered_data = [];
|
||||||
|
|||||||
@ -31,7 +31,13 @@ export function initializeAdminPermanences() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialiser Select2 pour le champ langues
|
// Initialiser Select2 pour le champ langues
|
||||||
initializeSelect2();
|
// 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
|
// Écouter les changements pour mettre à jour l'aperçu
|
||||||
setupPreviewListeners();
|
setupPreviewListeners();
|
||||||
@ -46,13 +52,109 @@ export function initializeAdminPermanences() {
|
|||||||
initializeCsvImport();
|
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
|
* Initialise Select2 pour le champ de sélection des langues
|
||||||
*/
|
*/
|
||||||
function initializeSelect2() {
|
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');
|
const languesSelect = document.getElementById('langues-permanences');
|
||||||
if (languesSelect && typeof jQuery !== 'undefined' && jQuery.fn.select2) {
|
if (languesSelect && select2Initialized) {
|
||||||
jQuery(languesSelect).select2({
|
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',
|
placeholder: 'Sélectionnez une ou plusieurs langues',
|
||||||
allowClear: true,
|
allowClear: true,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@ -62,9 +164,58 @@ 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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure la préselection des inputs jours[] et heures[]
|
* Configure la préselection des inputs jours[] et heures[]
|
||||||
* à partir des attributs data-days et data-time-slots de l'option sélectionnée
|
* à partir des attributs data-days et data-time-slots de l'option sélectionnée
|
||||||
|
|||||||
@ -438,6 +438,16 @@ export async function handleEventFormSubmit(mode, eventId = null, onSuccess = nu
|
|||||||
const formData = new FormData(form);
|
const formData = new FormData(form);
|
||||||
let data = Object.fromEntries(formData.entries());
|
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
|
// Validation côté client
|
||||||
const errors = validateForm(data, mode);
|
const errors = validateForm(data, mode);
|
||||||
if (Object.keys(errors).length > 0) {
|
if (Object.keys(errors).length > 0) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user