feat(ota): add header update notification badge & 24h background check (v1.3.1)
This commit is contained in:
1 parent
5d60e66518
commit
e2af2c34c9
4 files changed
+82
-24
No files matched your search
+68
-17
@@ -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');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -151,3 +151,4 @@ if [ -f "$APP_DIR/version.json" ]; then
|
|||||||
'
|
'
|
||||||
fi
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
+6
-7
@@ -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"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user