231 lines
7.1 KiB
JavaScript
231 lines
7.1 KiB
JavaScript
/* Feedback de chargement pour FullCalendar et spinner sur le bouton Enregistrer du modal */
|
|
(function () {
|
|
function setDisabled(containerSelector, disabled) {
|
|
try {
|
|
var container = document.querySelector(containerSelector);
|
|
if (!container) return;
|
|
var els = container.querySelectorAll('button, input, select, textarea');
|
|
els.forEach(function (el) {
|
|
el.disabled = !!disabled;
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
|
|
function showIndicator(id, show) {
|
|
try {
|
|
var el = document.getElementById(id);
|
|
if (el) {
|
|
el.style.display = show ? 'block' : 'none';
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
|
|
function attachLoading(calendar, indicatorId, filtersSelector) {
|
|
try {
|
|
if (!calendar || typeof calendar.setOption !== 'function') return;
|
|
calendar.setOption('loading', function (isLoading) {
|
|
showIndicator(indicatorId, isLoading);
|
|
// Ne pas désactiver les filtres pendant le chargement, uniquement overlay sur le calendrier
|
|
try {
|
|
var calEl = document.getElementById('agenda-calendar') || (calendar.el || null);
|
|
if (calEl && window.CRVI_OVERLAY) {
|
|
if (isLoading) {
|
|
window.CRVI_OVERLAY.show(calEl);
|
|
} else {
|
|
window.CRVI_OVERLAY.hide(calEl);
|
|
}
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
|
|
// Gestionnaire de chargement global, pour couvrir les appels AJAX génériques (création, update, delete, etc.)
|
|
// Usage: window.CRVI_LOADING.start(); ... finally window.CRVI_LOADING.end();
|
|
(function initGlobalLoading() {
|
|
var counter = 0;
|
|
var defaultIndicatorId = 'loading-indicator';
|
|
// Ne pas désactiver automatiquement les zones de filtres
|
|
var defaultDisableSelectors = [];
|
|
|
|
function updateUi() {
|
|
var isLoading = counter > 0;
|
|
try {
|
|
showIndicator(defaultIndicatorId, isLoading);
|
|
// Désactiver quelques containers communs si présents
|
|
defaultDisableSelectors.forEach(function (sel) {
|
|
setDisabled(sel, isLoading);
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
|
|
if (!window.CRVI_LOADING) {
|
|
window.CRVI_LOADING = {
|
|
start: function () {
|
|
counter++;
|
|
updateUi();
|
|
},
|
|
end: function () {
|
|
if (counter > 0) counter--;
|
|
updateUi();
|
|
},
|
|
// Permet d'ajuster la cible si besoin ailleurs
|
|
configure: function (opts) {
|
|
if (opts && typeof opts.indicatorId === 'string') {
|
|
defaultIndicatorId = opts.indicatorId;
|
|
}
|
|
if (opts && Array.isArray(opts.disableSelectors)) {
|
|
defaultDisableSelectors = opts.disableSelectors.slice();
|
|
}
|
|
updateUi();
|
|
},
|
|
// Pour diagnostics
|
|
_getCount: function () {
|
|
return counter;
|
|
}
|
|
};
|
|
}
|
|
})();
|
|
|
|
// Overlay ciblé par élément: window.CRVI_OVERLAY.show(elementOrSelector), .hide(...)
|
|
(function initElementOverlay() {
|
|
function getTarget(elOrSelector) {
|
|
if (!elOrSelector) return null;
|
|
if (typeof elOrSelector === 'string') return document.querySelector(elOrSelector);
|
|
return elOrSelector.nodeType === 1 ? elOrSelector : null;
|
|
}
|
|
|
|
function ensurePositioned(target) {
|
|
var style = window.getComputedStyle(target);
|
|
if (style.position === 'static' || !style.position) {
|
|
target.style.position = 'relative';
|
|
}
|
|
}
|
|
|
|
function createOverlay(target) {
|
|
var overlay = document.createElement('div');
|
|
overlay.className = 'crvi-overlay';
|
|
overlay.style.position = 'absolute';
|
|
overlay.style.top = '0';
|
|
overlay.style.left = '0';
|
|
overlay.style.right = '0';
|
|
overlay.style.bottom = '0';
|
|
overlay.style.background = 'rgba(255,255,255,0.6)';
|
|
overlay.style.display = 'flex';
|
|
overlay.style.alignItems = 'center';
|
|
overlay.style.justifyContent = 'center';
|
|
overlay.style.zIndex = '20';
|
|
|
|
var spinner = document.createElement('div');
|
|
spinner.className = 'spinner-border text-primary';
|
|
spinner.setAttribute('role', 'status');
|
|
spinner.setAttribute('aria-hidden', 'true');
|
|
|
|
overlay.appendChild(spinner);
|
|
return overlay;
|
|
}
|
|
|
|
function getCount(target) {
|
|
var c = parseInt(target.getAttribute('data-overlay-count') || '0', 10);
|
|
return isNaN(c) ? 0 : c;
|
|
}
|
|
|
|
function setCount(target, c) {
|
|
target.setAttribute('data-overlay-count', String(c));
|
|
}
|
|
|
|
function show(elOrSelector) {
|
|
var target = getTarget(elOrSelector);
|
|
if (!target) return;
|
|
ensurePositioned(target);
|
|
var count = getCount(target);
|
|
setCount(target, count + 1);
|
|
if (count > 0 && target.querySelector(':scope > .crvi-overlay')) {
|
|
return;
|
|
}
|
|
var overlay = createOverlay(target);
|
|
target.appendChild(overlay);
|
|
}
|
|
|
|
function hide(elOrSelector) {
|
|
var target = getTarget(elOrSelector);
|
|
if (!target) return;
|
|
var count = getCount(target);
|
|
count = Math.max(0, count - 1);
|
|
setCount(target, count);
|
|
if (count === 0) {
|
|
var overlay = target.querySelector(':scope > .crvi-overlay');
|
|
if (overlay) {
|
|
overlay.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!window.CRVI_OVERLAY) {
|
|
window.CRVI_OVERLAY = { show: show, hide: hide };
|
|
}
|
|
})();
|
|
|
|
function tryAttach() {
|
|
if (window.currentCalendar) {
|
|
attachLoading(window.currentCalendar, 'loading-indicator', '.filters');
|
|
}
|
|
if (window.currentColleaguesCalendar) {
|
|
attachLoading(
|
|
window.currentColleaguesCalendar,
|
|
'loading-indicator-colleagues',
|
|
'.filters-colleagues'
|
|
);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Essayer d'attacher au démarrage puis quelques tentatives (calendriers init asynchrones)
|
|
tryAttach();
|
|
var iv = setInterval(tryAttach, 500);
|
|
setTimeout(function () {
|
|
clearInterval(iv);
|
|
}, 10000);
|
|
|
|
// Spinner + désactivation sur le bouton Enregistrer du modal
|
|
document.addEventListener(
|
|
'click',
|
|
function (e) {
|
|
var btn = e.target && (e.target.closest ? e.target.closest('#saveEvent') : null);
|
|
if (!btn) return;
|
|
if (btn.dataset.loading === '1') return;
|
|
|
|
btn.dataset.loading = '1';
|
|
btn.disabled = true;
|
|
if (!btn.dataset.originalHtml) {
|
|
btn.dataset.originalHtml = btn.innerHTML;
|
|
}
|
|
btn.innerHTML =
|
|
'<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>Enregistrer';
|
|
|
|
var onDone = function () {
|
|
btn.disabled = false;
|
|
btn.dataset.loading = '0';
|
|
if (btn.dataset.originalHtml) {
|
|
btn.innerHTML = btn.dataset.originalHtml;
|
|
}
|
|
};
|
|
|
|
// Réactiver à la fermeture du modal ou après un timeout de secours
|
|
var modal = document.getElementById('eventModal');
|
|
if (modal) {
|
|
var handler = function () {
|
|
modal.removeEventListener('hidden.bs.modal', handler);
|
|
onDone();
|
|
};
|
|
modal.addEventListener('hidden.bs.modal', handler);
|
|
}
|
|
setTimeout(onDone, 8000);
|
|
},
|
|
true
|
|
);
|
|
});
|
|
})();
|
|
|
|
|