fix: couleurs icônes, boutons carrés, sidebar collapsée, langue, SW scope, LXC arrêté

Icônes :
- Sidebar navItems : couleur distincte par section (iconStyle via data-binding)
- Sidebar footer user : couleur primary
- Navbar : logout → danger, soleil → amber, lune → blue
- Panel widgets : œil visible → success, caché → muted

Boutons :
- `.neu-btn--sm:has(> i:only-child)` → carré 2rem×2rem automatiquement
  (theme, logout, mode édition) sans modifier le HTML

Sidebar :
- --sidebar-width-collapsed : 64px → 52px
- Sidebar réduite : icônes centrées (justify-content center)

Langue :
- Setter vide sur `lang` dans navbar() pour corriger x-model avec getter
  (le @change gère la vraie mise à jour du store)

Service Worker :
- Enregistrement depuis /ws.sw.js (scope /) au lieu de /js/ws.sw.js (scope /js/)
- build.mjs : copie ws.sw.js vers dist/ root en plus de dist/js/

LXC arrêté :
- checkTarget() : skip si target.status !== 'running' → évite les 502 SSH

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
enzo 2026-03-21 19:50:58 +01:00
parent 7c57b0ff84
commit b851dc61af
11 changed files with 53 additions and 15 deletions

View file

@ -13,7 +13,7 @@ const WsProxy = {
init() {
if (!('serviceWorker' in navigator)) return
navigator.serviceWorker.register('/js/ws.sw.js')
navigator.serviceWorker.register('/ws.sw.js')
.catch(e => console.warn('[WsProxy] SW registration failed:', e))
navigator.serviceWorker.addEventListener('message', event => {
const { channel, type, data, status } = event.data || {}
@ -253,14 +253,18 @@ document.addEventListener('alpine:init', () => {
get currentPage() { return Alpine.store('ui').currentPage },
navItems: [
{ id: 'dashboard', iconClass: 'lnid-dashboard-square-1', labelKey: 'nav.dashboard', href: '/dashboard.html' },
{ id: 'proxmox', iconClass: 'lnid-server-1', labelKey: 'nav.proxmox', href: '/proxmox.html' },
{ id: 'updates', iconClass: 'lnid-arrow-upward', labelKey: 'nav.updates', href: '/updates.html' },
{ id: 'terminal', iconClass: 'lnid-terminal', labelKey: 'nav.terminal', href: '/terminal.html' },
{ id: 'settings', iconClass: 'lnid-gear-1', labelKey: 'nav.settings', href: '/settings.html' },
{ id: 'modules', iconClass: 'lnid-puzzle', labelKey: 'nav.modules', href: '/modules.html' },
{ id: 'dashboard', iconClass: 'lnid-dashboard-square-1', iconColor: '#6c8ef4', labelKey: 'nav.dashboard', href: '/dashboard.html' },
{ id: 'proxmox', iconClass: 'lnid-server-1', iconColor: '#22c55e', labelKey: 'nav.proxmox', href: '/proxmox.html' },
{ id: 'updates', iconClass: 'lnid-arrow-upward', iconColor: '#f59e0b', labelKey: 'nav.updates', href: '/updates.html' },
{ id: 'terminal', iconClass: 'lnid-terminal', iconColor: '#a78bfa', labelKey: 'nav.terminal', href: '/terminal.html' },
{ id: 'settings', iconClass: 'lnid-gear-1', iconColor: '#94a3b8', labelKey: 'nav.settings', href: '/settings.html' },
{ id: 'modules', iconClass: 'lnid-puzzle', iconColor: '#f472b6', labelKey: 'nav.modules', href: '/modules.html' },
],
iconStyle(item) {
return this.isActive(item.id) ? '' : `color: ${item.iconColor}`
},
isActive(id) {
return this.currentPage === id
},
@ -282,6 +286,7 @@ document.addEventListener('alpine:init', () => {
get theme() { return Alpine.store('ui').theme },
get user() { return Alpine.store('auth').user },
get lang() { return Alpine.store('i18n').lang },
set lang(v) { /* x-model a besoin d'un setter ; @change gère la vraie MAJ */ },
toggleTheme() { Alpine.store('ui').toggleTheme() },
logout() { Alpine.store('auth').logout() },
@ -657,15 +662,19 @@ document.addEventListener('alpine:init', () => {
},
async checkTarget(target) {
if (target.status !== 'running') return // container arrêté → pas de SSH possible
target.checking = true
target.packages = null
try {
const res = await apiFetch(`/api/updates/packages?target=${encodeURIComponent(target.id)}`)
if (res.ok) {
target.packages = await res.json()
} else {
target.packages = []
}
} catch(e) {
console.error('checkTarget', e)
target.packages = []
} finally {
target.checking = false
}