feat(ota): add header update notification badge & 24h background check (v1.3.1)

This commit is contained in:
sorcier committed 2026-11-04 01:36:28 +01:00
1 parent 5d60e66518
commit e2af2c34c9
4 files changed
+82 -24

No files matched your search

+68 -17
View File
@@ -5641,6 +5641,14 @@ function copyYealinkUrl(inputId, btn) {
// ========================================================================= // =========================================================================
// GESTIONNAIRE DE MISES À JOUR DU SYSTÈME NEXUSPBX (OTA) // GESTIONNAIRE DE MISES À JOUR DU SYSTÈME NEXUSPBX (OTA)
// ========================================================================= // =========================================================================
function openUpdatePanel() {
switchTab('system');
setTimeout(() => {
const el = document.getElementById('update-status-box');
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
}, 150);
}
async function checkSystemUpdate(notify = false) { async function checkSystemUpdate(notify = false) {
const btnCheck = document.getElementById('btn-check-update'); const btnCheck = document.getElementById('btn-check-update');
const btnRun = document.getElementById('btn-run-update'); const btnRun = document.getElementById('btn-run-update');
@@ -5651,6 +5659,25 @@ async function checkSystemUpdate(notify = false) {
const pingDot = document.getElementById('update-ping'); const pingDot = document.getElementById('update-ping');
const verTag = document.getElementById('system-version-tag'); const verTag = document.getElementById('system-version-tag');
const appBadge = document.getElementById('app-version-badge'); const appBadge = document.getElementById('app-version-badge');
const headerUpdateBadge = document.getElementById('header-update-badge');
const headerUpdateText = document.getElementById('header-update-text');
const STORAGE_KEY_TIME = 'nexus_update_last_check_ts';
const STORAGE_KEY_DATA = 'nexus_update_cached_data';
const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000;
// Si pas de clic explicite (notify === false), vérifier si un check a déjà été fait il y a moins de 24h
if (!notify) {
const lastTs = parseInt(localStorage.getItem(STORAGE_KEY_TIME) || '0', 10);
const cachedRaw = localStorage.getItem(STORAGE_KEY_DATA);
if (lastTs && (Date.now() - lastTs < TWENTY_FOUR_HOURS) && cachedRaw) {
try {
const cached = JSON.parse(cachedRaw);
applyUpdateUI(cached);
return;
} catch (_) {}
}
}
if (btnCheck) { if (btnCheck) {
btnCheck.disabled = true; btnCheck.disabled = true;
@@ -5661,9 +5688,35 @@ async function checkSystemUpdate(notify = false) {
const res = await fetch('/api.php?action=check_update'); const res = await fetch('/api.php?action=check_update');
const data = await res.json(); const data = await res.json();
// Enregistrement du timestamp de vérification et des données en cache local (24h)
localStorage.setItem(STORAGE_KEY_TIME, Date.now().toString());
localStorage.setItem(STORAGE_KEY_DATA, JSON.stringify(data));
applyUpdateUI(data);
if (notify) {
if (data.has_update) {
showToast(`Nouvelle version NexusPBX v${data.latest_version} disponible !`, 'info');
} else {
showToast("Votre système NexusPBX est parfaitement à jour !", 'success');
}
}
} catch (e) {
if (notify) {
showToast("Erreur lors de la vérification des mises à jour : " + e.message, 'error');
}
} finally {
if (btnCheck) {
btnCheck.disabled = false;
btnCheck.classList.remove('opacity-50');
}
}
function applyUpdateUI(data) {
if (lastChecked) { if (lastChecked) {
const now = new Date(); const lastTs = parseInt(localStorage.getItem(STORAGE_KEY_TIME) || Date.now().toString(), 10);
lastChecked.textContent = `Dernière vérification : ${now.toLocaleTimeString()}`; const d = new Date(lastTs);
lastChecked.textContent = `Dernière vérification : ${d.toLocaleDateString()} à ${d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})}`;
} }
if (verTag && data.current_version) { if (verTag && data.current_version) {
@@ -5674,6 +5727,14 @@ async function checkSystemUpdate(notify = false) {
} }
if (data.has_update) { if (data.has_update) {
// Affichage du badge dans l'en-tête à côté de Tester AMI
if (headerUpdateBadge) {
headerUpdateBadge.style.display = 'inline-flex';
if (headerUpdateText) {
headerUpdateText.textContent = `v${escapeHtml(data.latest_version)} dispo`;
}
}
if (statusText) { if (statusText) {
statusText.className = 'text-amber-400 font-bold'; statusText.className = 'text-amber-400 font-bold';
statusText.innerHTML = `🚀 Nouvelle version disponible : <span class="underline">v${escapeHtml(data.latest_version)}</span> !`; statusText.innerHTML = `🚀 Nouvelle version disponible : <span class="underline">v${escapeHtml(data.latest_version)}</span> !`;
@@ -5688,10 +5749,12 @@ async function checkSystemUpdate(notify = false) {
changelogList.innerHTML = data.changelog.map(item => `<li>${escapeHtml(item)}</li>`).join(''); changelogList.innerHTML = data.changelog.map(item => `<li>${escapeHtml(item)}</li>`).join('');
if (changelogContainer) changelogContainer.classList.remove('hidden'); if (changelogContainer) changelogContainer.classList.remove('hidden');
} }
if (notify) {
showToast(`Nouvelle version NexusPBX v${data.latest_version} disponible !`, 'info');
}
} else { } else {
// Pas de mise à jour disponible : masquer le badge dans l'en-tête
if (headerUpdateBadge) {
headerUpdateBadge.style.display = 'none';
}
if (statusText) { if (statusText) {
statusText.className = 'text-emerald-400 font-bold'; statusText.className = 'text-emerald-400 font-bold';
statusText.textContent = `Votre PBX est à jour avec la dernière version officielle (v${data.current_version}).`; statusText.textContent = `Votre PBX est à jour avec la dernière version officielle (v${data.current_version}).`;
@@ -5699,18 +5762,6 @@ async function checkSystemUpdate(notify = false) {
if (btnRun) btnRun.style.display = 'none'; if (btnRun) btnRun.style.display = 'none';
if (pingDot) pingDot.classList.add('hidden'); if (pingDot) pingDot.classList.add('hidden');
if (changelogContainer) changelogContainer.classList.add('hidden'); if (changelogContainer) changelogContainer.classList.add('hidden');
if (notify) {
showToast("Votre système NexusPBX est parfaitement à jour !", 'success');
}
}
} catch (e) {
if (notify) {
showToast("Erreur lors de la vérification des mises à jour : " + e.message, 'error');
}
} finally {
if (btnCheck) {
btnCheck.disabled = false;
btnCheck.classList.remove('opacity-50');
} }
} }
} }
+7
View File
@@ -478,6 +478,13 @@ $currentUser = Auth::getUsername();
<!-- Boutons d'action globaux --> <!-- Boutons d'action globaux -->
<div class="flex items-center gap-2.5"> <div class="flex items-center gap-2.5">
<!-- Badge Notification Mise à Jour Disponible -->
<button id="header-update-badge" type="button" onclick="openUpdatePanel()" style="display:none;"
class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-xl text-xs font-bold bg-amber-500/20 hover:bg-amber-500/30 text-amber-300 border border-amber-500/40 shadow-sm transition animate-pulse" title="Une mise à jour NexusPBX est disponible ! Cliquez pour voir les détails.">
<span>🚀</span>
<span id="header-update-text">Mise à jour dispo</span>
</button>
<button id="btn-test-ami" type="button" <button id="btn-test-ami" type="button"
class="inline-flex items-center gap-2 px-3.5 py-2 rounded-xl text-xs font-semibold bg-anthracite-750 hover:bg-anthracite-700 text-slate-100 border border-anthracite-600 transition"> class="inline-flex items-center gap-2 px-3.5 py-2 rounded-xl text-xs font-semibold bg-anthracite-750 hover:bg-anthracite-700 text-slate-100 border border-anthracite-600 transition">
<span id="ami-dot" class="w-2 h-2 rounded-full bg-emerald-400"></span> <span id="ami-dot" class="w-2 h-2 rounded-full bg-emerald-400"></span>
+1
View File
@@ -151,3 +151,4 @@ if [ -f "$APP_DIR/version.json" ]; then
' '
fi fi
echo "" echo ""
+6 -7
View File
@@ -1,14 +1,13 @@
{ {
"version": "1.3.0", "version": "1.3.1",
"codename": "Helios", "codename": "Helios",
"release_date": "2026-11-04", "release_date": "2026-11-04",
"min_php_version": "8.2", "min_php_version": "8.2",
"changelog": [ "changelog": [
"Gestion avancée des passerelles analogiques / FXO (Grandstream HT813, Cisco SPA, ATA)", "Badge de notification automatique de mise à jour dans l'en-tête (à côté du test AMI)",
"Message vocal d'indisponibilité / congestion configurable sur les routes sortantes", "Vérification intelligente en tâche de fond toutes les 24h sans solliciter le serveur",
"Système de mise à jour automatique en 1-clic et commande CLI nexus-update", "Accès direct 1-clic aux détails et à l'installation des mises à jour",
"Compatibilité étendue téléphones IP (Yealink, Fanvil, Grandstream, Snom, Cisco)", "Gestion avancée des passerelles analogiques / FXO (Grandstream HT813, Cisco SPA)",
"Préfixe de ligne CID entrant pour identifier la provenance des appels", "Message vocal d'indisponibilité / congestion configurable sur les routes sortantes"
"Génération automatique des tonalités et dial options Asterisk optimisées"
] ]
} }