// Module de gestion des boutons de la modale // Contient les gestionnaires d'événements pour tous les boutons de la modale import { deleteEvent, changeEventStatus } from './agenda-api.js'; import { notifyError, notifySuccess } from './agenda-notifications.js'; /** * Helper pour gérer l'overlay de chargement * @param {Function} asyncAction - Action asynchrone à exécuter * @returns {Promise} */ async function withLoadingOverlay(asyncAction) { const overlayTarget = document.querySelector('#eventModal .modal-content') || document.getElementById('eventModal'); try { if (window.CRVI_OVERLAY && overlayTarget) { window.CRVI_OVERLAY.show(overlayTarget); } await asyncAction(); } finally { if (window.CRVI_OVERLAY && overlayTarget) { window.CRVI_OVERLAY.hide(overlayTarget); } } } /** * Helper pour rafraîchir les calendriers */ function refreshCalendars() { if (window.currentCalendar) { window.currentCalendar.refetchEvents(); } if (window.currentColleaguesCalendar) { window.currentColleaguesCalendar.refetchEvents(); } } /** * Helper pour fermer le modal * @param {Function} onClosed - Callback après fermeture */ function closeModal(onClosed = null) { const modal = document.getElementById('eventModal'); if (modal) { const bsModal = bootstrap.Modal.getInstance(modal); if (bsModal) { if (onClosed) { modal.addEventListener('hidden.bs.modal', onClosed, { once: true }); } bsModal.hide(); } } } /** * Vérifie les permissions utilisateur * @param {string} permission - Type de permission ('can_edit', 'can_delete', 'can_create') * @returns {boolean} */ function checkPermission(permission) { const hasPermission = window.crviPermissions && window.crviPermissions[permission]; if (!hasPermission) { console.warn(`Utilisateur non autorisé: ${permission}`); } return hasPermission; } /** * Initialise le bouton de fermeture * @param {string} buttonId - ID du bouton */ export function initializeCloseButton(buttonId) { const button = document.getElementById(buttonId); if (button) { button.onclick = () => closeModal(); } } /** * Initialise le bouton de suppression * @param {Function} getCurrentEventData - Fonction pour obtenir les données de l'événement * @param {Function} onDeleted - Callback après suppression */ export function initializeDeleteButton(getCurrentEventData, onDeleted = null) { const deleteBtn = document.getElementById('deleteEvent'); if (!deleteBtn) return; deleteBtn.onclick = async function() { if (!checkPermission('can_delete')) return; if (!confirm('Êtes-vous sûr de vouloir supprimer cet événement ?')) { return; } const currentEventData = getCurrentEventData(); const eventId = currentEventData ? currentEventData.id : null; if (!eventId) { notifyError('ID d\'événement manquant'); return; } await withLoadingOverlay(async () => { try { await deleteEvent(eventId); refreshCalendars(); closeModal(onDeleted); } catch (error) { console.error('Erreur lors de la suppression:', error); notifyError('Erreur lors de la suppression de l\'événement'); } }); }; } /** * Initialise le bouton de validation de présence * @param {Function} getCurrentEventData - Fonction pour obtenir les données de l'événement * @param {Function} openCheckPresenceModal - Fonction pour ouvrir la modal de validation de présence de groupe * @param {Function} onStatusChanged - Callback après changement de statut */ export function initializeMarkPresentButton(getCurrentEventData, openCheckPresenceModal, onStatusChanged = null) { const markPresentBtn = document.getElementById('markPresentBtn'); if (!markPresentBtn) return; markPresentBtn.onclick = async function() { if (!checkPermission('can_edit')) return; const currentEventData = getCurrentEventData(); const eventId = currentEventData ? currentEventData.id : null; if (!eventId) { notifyError('ID d\'événement manquant'); return; } // Vérifier le type d'événement const eventType = currentEventData?.type || currentEventData?.extendedProps?.type || ''; const isGroupe = eventType === 'groupe'; if (isGroupe) { // Pour les événements de groupe, ouvrir la modal de validation des présences openCheckPresenceModal(currentEventData); } else { // Pour les événements individuels if (!confirm('Confirmer la présence à cet événement ?')) { return; } await withLoadingOverlay(async () => { try { await changeEventStatus(eventId, 'present'); notifySuccess('Présence validée'); refreshCalendars(); closeModal(onStatusChanged); } catch (error) { console.error('Erreur lors du changement de statut:', error); notifyError('Erreur lors de la validation de présence'); } }); } }; } /** * Initialise le bouton pour marquer comme absent * @param {Function} getCurrentEventData - Fonction pour obtenir les données de l'événement * @param {Function} onStatusChanged - Callback après changement de statut */ export function initializeMarkAbsentButton(getCurrentEventData, onStatusChanged = null) { const markAbsentBtn = document.getElementById('markAbsentBtn'); if (!markAbsentBtn) return; markAbsentBtn.onclick = async function() { if (!checkPermission('can_edit')) return; const currentEventData = getCurrentEventData(); const eventId = currentEventData ? currentEventData.id : null; if (!eventId) { notifyError('ID d\'événement manquant'); return; } if (!confirm('Marquer cet événement comme absent ?')) { return; } await withLoadingOverlay(async () => { try { await changeEventStatus(eventId, 'absence'); notifySuccess('Événement marqué comme absent'); refreshCalendars(); closeModal(onStatusChanged); } catch (error) { console.error('Erreur lors du changement de statut:', error); notifyError('Erreur lors du changement de statut'); } }); }; } /** * Initialise le bouton d'annulation de rendez-vous * @param {Function} getCurrentEventData - Fonction pour obtenir les données de l'événement * @param {Function} onCancelled - Callback après annulation */ export function initializeCancelAppointmentButton(getCurrentEventData, onCancelled = null) { const cancelAppointmentBtn = document.getElementById('cancelAppointmentBtn'); if (!cancelAppointmentBtn) return; cancelAppointmentBtn.onclick = async function() { if (!checkPermission('can_edit')) return; const currentEventData = getCurrentEventData(); const eventId = currentEventData ? currentEventData.id : null; if (!eventId) { notifyError('ID d\'événement manquant'); return; } const motif = prompt('Motif de l\'annulation (optionnel):'); if (motif === null) { return; // L'utilisateur a cliqué sur Annuler } await withLoadingOverlay(async () => { try { await changeEventStatus(eventId, 'annule', motif); notifySuccess('Rendez-vous annulé'); refreshCalendars(); closeModal(onCancelled); } catch (error) { console.error('Erreur lors de l\'annulation:', error); notifyError('Erreur lors de l\'annulation du rendez-vous'); } }); }; } /** * Initialise tous les boutons de la modale * @param {Object} options - Options de configuration * @param {Function} options.getCurrentEventData - Fonction pour obtenir les données de l'événement * @param {Function} options.openCheckPresenceModal - Fonction pour ouvrir la modal de validation de présence * @param {Function} options.onDeleted - Callback après suppression * @param {Function} options.onStatusChanged - Callback après changement de statut */ export function initializeModalButtons(options = {}) { const { getCurrentEventData, openCheckPresenceModal, onDeleted, onStatusChanged } = options; // Boutons de fermeture initializeCloseButton('closeModalBtn'); initializeCloseButton('closeViewBtn'); // Boutons d'action if (getCurrentEventData) { initializeDeleteButton(getCurrentEventData, onDeleted); initializeMarkPresentButton(getCurrentEventData, openCheckPresenceModal, onStatusChanged); initializeMarkAbsentButton(getCurrentEventData, onStatusChanged); initializeCancelAppointmentButton(getCurrentEventData, onStatusChanged); } }