fix(viewer+backend): cache sorties TTL 10min + /sorties/local + viewer non-bloquant

This commit is contained in:
Poulpe
2026-04-27 22:02:21 +00:00
parent b962997008
commit 31b5a221b8
3 changed files with 109 additions and 24 deletions

View File

@@ -1121,29 +1121,60 @@ async function loadSortieData(sortieId) {
}
}
async function loadSorties() {
try {
const resp = await fetch(`${API2}/sorties`);
if (!resp.ok) return;
const sorties = await resp.json();
const sel = document.getElementById('sortie-select');
sorties.forEach(s => {
const opt = document.createElement('option');
opt.value = s.id;
opt.textContent = s.id + (s.processed ? ' ✓' : '');
sel.appendChild(opt);
});
sel.addEventListener('change', () => {
const btn = document.getElementById('btn-sync');
btn.disabled = !sel.value;
if (sel.value) {
const opt = sel.options[sel.selectedIndex];
if (opt.textContent.includes('✓')) {
loadSortieData(sel.value);
}
function _wireSortieSelect() {
const sel = document.getElementById('sortie-select');
// Evite double-binding si appelé plusieurs fois
if (sel._wired) return;
sel._wired = true;
sel.addEventListener('change', () => {
const btn = document.getElementById('btn-sync');
btn.disabled = !sel.value;
if (sel.value) {
const opt = sel.options[sel.selectedIndex];
if (opt.textContent.includes('✓')) {
loadSortieData(sel.value);
}
}
});
}
function _populateSortieSelect(sorties) {
const sel = document.getElementById('sortie-select');
// Vider sauf première option placeholder
while (sel.options.length > 1) sel.remove(1);
if (!sorties || !sorties.length) {
sel.options[0].textContent = '— Aucune sortie —';
return;
}
sel.options[0].textContent = '— Sortie —';
sorties.forEach(s => {
const opt = document.createElement('option');
opt.value = s.id;
opt.textContent = s.id + (s.processed ? ' ✓' : '');
sel.appendChild(opt);
});
_wireSortieSelect();
}
function loadSorties() {
const sel = document.getElementById('sortie-select');
sel.options[0].textContent = 'Sorties: chargement…';
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
fetch(`${API2}/sorties`, { signal: controller.signal })
.then(resp => {
clearTimeout(timeoutId);
if (!resp.ok) throw new Error('HTTP ' + resp.status);
return resp.json();
})
.then(sorties => { _populateSortieSelect(sorties); })
.catch(e => {
clearTimeout(timeoutId);
sel.options[0].textContent = '— Pipeline indisponible —';
console.warn('loadSorties:', e.message);
});
} catch(e) { console.warn('pipeline-runner unavailable', e); }
}
document.getElementById('btn-sync').addEventListener('click', async () => {