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 c58fe8e076
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)
// =========================================================================
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) {
const btnCheck = document.getElementById('btn-check-update');
const btnRun = document.getElementById('btn-run-update');
@@ -5651,6 +5659,25 @@ async function checkSystemUpdate(notify = false) {
const pingDot = document.getElementById('update-ping');
const verTag = document.getElementById('system-version-tag');
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) {
btnCheck.disabled = true;
@@ -5661,9 +5688,35 @@ async function checkSystemUpdate(notify = false) {
const res = await fetch('/api.php?action=check_update');
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) {
const now = new Date();
lastChecked.textContent = `Dernière vérification : ${now.toLocaleTimeString()}`;
const lastTs = parseInt(localStorage.getItem(STORAGE_KEY_TIME) || Date.now().toString(), 10);
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) {
@@ -5674,6 +5727,14 @@ async function checkSystemUpdate(notify = false) {
}
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) {
statusText.className = 'text-amber-400 font-bold';
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('');
if (changelogContainer) changelogContainer.classList.remove('hidden');
}
if (notify) {
showToast(`Nouvelle version NexusPBX v${data.latest_version} disponible !`, 'info');
}
} else {
// Pas de mise à jour disponible : masquer le badge dans l'en-tête
if (headerUpdateBadge) {
headerUpdateBadge.style.display = 'none';
}
if (statusText) {
statusText.className = 'text-emerald-400 font-bold';
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 (pingDot) pingDot.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 -->
<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"
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>
+1
View File
@@ -151,3 +151,4 @@ if [ -f "$APP_DIR/version.json" ]; then
'
fi
echo ""
+6 -7
View File
@@ -1,14 +1,13 @@
{
"version": "1.3.0",
"version": "1.3.1",
"codename": "Helios",
"release_date": "2026-11-04",
"min_php_version": "8.2",
"changelog": [
"Gestion avancée des passerelles analogiques / FXO (Grandstream HT813, Cisco SPA, ATA)",
"Message vocal d'indisponibilité / congestion configurable sur les routes sortantes",
"Système de mise à jour automatique en 1-clic et commande CLI nexus-update",
"Compatibilité étendue téléphones IP (Yealink, Fanvil, Grandstream, Snom, Cisco)",
"Préfixe de ligne CID entrant pour identifier la provenance des appels",
"Génération automatique des tonalités et dial options Asterisk optimisées"
"Badge de notification automatique de mise à jour dans l'en-tête (à côté du test AMI)",
"Vérification intelligente en tâche de fond toutes les 24h sans solliciter le serveur",
"Accès direct 1-clic aux détails et à l'installation des mises à jour",
"Gestion avancée des passerelles analogiques / FXO (Grandstream HT813, Cisco SPA)",
"Message vocal d'indisponibilité / congestion configurable sur les routes sortantes"
]
}