secubox-openwrt/luci-app-system-hub/htdocs/luci-static/resources/view/system-hub/overview.js

175 lines
6.7 KiB
JavaScript

'use strict';
'require view';
'require dom';
'require poll';
'require ui';
var api = L.require('system-hub.api');
return view.extend({
refreshInterval: 30000,
load: function() {
return api.getAllData();
},
render: function(data) {
var status = data.status;
var components = data.components || [];
var health = data.health;
var self = this;
var healthInfo = api.getHealthStatus(health.score || 0);
var installedComponents = components.filter(function(c) { return c.status === 'installed'; });
var runningComponents = installedComponents.filter(function(c) { return c.running; });
var issueComponents = installedComponents.filter(function(c) { return !c.running; });
var view = E('div', { 'class': 'system-hub-dashboard' }, [
E('link', { 'rel': 'stylesheet', 'href': L.resource('system-hub/dashboard.css') }),
// Header
E('div', { 'class': 'sh-header' }, [
E('div', { 'class': 'sh-logo' }, [
E('div', { 'class': 'sh-logo-icon' }, '🎛️'),
E('div', { 'class': 'sh-logo-text' }, [ 'System ', E('span', {}, 'Hub') ])
]),
E('div', { 'class': 'sh-health-score' }, [
E('div', { 'class': 'sh-score-circle ' + healthInfo.status }, (health.score || 0).toString()),
E('div', { 'class': 'sh-score-info' }, [
E('div', { 'class': 'sh-score-label' }, healthInfo.label),
E('div', { 'class': 'sh-score-status' }, 'Dernière vérif: ' + (status.last_health_check || 'Jamais'))
])
])
]),
// Stats Grid
E('div', { 'class': 'sh-stats-grid' }, [
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '🧩'),
E('div', { 'class': 'sh-stat-value' }, installedComponents.length.toString()),
E('div', { 'class': 'sh-stat-label' }, 'Composants')
]),
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '✅'),
E('div', { 'class': 'sh-stat-value' }, runningComponents.length.toString()),
E('div', { 'class': 'sh-stat-label' }, 'En Marche')
]),
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '⚠️'),
E('div', { 'class': 'sh-stat-value' }, issueComponents.length.toString()),
E('div', { 'class': 'sh-stat-label' }, 'Attention')
]),
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '📊'),
E('div', { 'class': 'sh-stat-value' }, (health.score || 0).toString()),
E('div', { 'class': 'sh-stat-label' }, 'Score Santé')
]),
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '📱'),
E('div', { 'class': 'sh-stat-value' }, (status.network?.connected_clients || 0).toString()),
E('div', { 'class': 'sh-stat-label' }, 'Clients')
]),
E('div', { 'class': 'sh-stat-card' }, [
E('div', { 'class': 'sh-stat-icon' }, '⏱️'),
E('div', { 'class': 'sh-stat-value' }, api.formatUptime(status.system?.uptime || 0)),
E('div', { 'class': 'sh-stat-label' }, 'Uptime')
])
]),
// System Info Card
E('div', { 'class': 'sh-card' }, [
E('div', { 'class': 'sh-card-header' }, [
E('div', { 'class': 'sh-card-title' }, [ E('span', { 'class': 'sh-card-title-icon' }, '💻'), 'Informations Système' ])
]),
E('div', { 'class': 'sh-card-body' }, [
E('div', { 'class': 'sh-sysinfo-grid' }, [
this.renderSysInfo('Hostname', status.system?.hostname || 'N/A'),
this.renderSysInfo('Modèle', status.system?.model || 'N/A'),
this.renderSysInfo('Architecture', status.system?.architecture || 'N/A'),
this.renderSysInfo('Kernel', status.system?.kernel || 'N/A'),
this.renderSysInfo('OpenWrt', status.system?.openwrt_version || 'N/A'),
this.renderSysInfo('Uptime', api.formatUptime(status.system?.uptime || 0)),
this.renderSysInfo('WAN IP', status.network?.wan_ip || 'N/A'),
this.renderSysInfo('LAN IP', status.network?.lan_ip || 'N/A')
])
])
]),
// Health Metrics Card
E('div', { 'class': 'sh-card' }, [
E('div', { 'class': 'sh-card-header' }, [
E('div', { 'class': 'sh-card-title' }, [ E('span', { 'class': 'sh-card-title-icon' }, '📊'), 'Métriques Rapides' ])
]),
E('div', { 'class': 'sh-card-body' }, [
E('div', { 'class': 'sh-health-grid' }, [
this.renderMetric('🔲', 'CPU', status.cpu?.usage_percent || 0, 80, 95, '%'),
this.renderMetric('💾', 'RAM', status.memory?.usage_percent || 0, 80, 95, '%'),
this.renderMetric('💿', 'Disque', status.storage?.usage_percent || 0, 80, 95, '%'),
this.renderMetric('🌡️', 'Temp', status.temperature || 0, 70, 85, '°C')
])
])
]),
// Components Card
E('div', { 'class': 'sh-card' }, [
E('div', { 'class': 'sh-card-header' }, [
E('div', { 'class': 'sh-card-title' }, [ E('span', { 'class': 'sh-card-title-icon' }, '🧩'), 'Composants Actifs' ]),
E('div', { 'class': 'sh-card-badge' }, installedComponents.length + ' installés')
]),
E('div', { 'class': 'sh-card-body' }, [
E('div', { 'class': 'sh-components-grid' },
installedComponents.slice(0, 6).map(function(c) { return self.renderComponent(c, false); })
)
])
])
]);
poll.add(L.bind(this.pollData, this), this.refreshInterval);
return view;
},
renderSysInfo: function(label, value) {
return E('div', { 'class': 'sh-sysinfo-item' }, [
E('span', { 'class': 'sh-sysinfo-label' }, label),
E('span', { 'class': 'sh-sysinfo-value' }, value)
]);
},
renderMetric: function(icon, label, value, warning, critical, unit) {
var status = api.getMetricStatus(value, warning, critical);
return E('div', { 'class': 'sh-health-metric' }, [
E('div', { 'class': 'sh-metric-header' }, [
E('div', { 'class': 'sh-metric-title' }, [ E('span', { 'class': 'sh-metric-icon' }, icon), label ]),
E('div', { 'class': 'sh-metric-value ' + status }, value + unit)
]),
E('div', { 'class': 'sh-progress-bar' }, [
E('div', { 'class': 'sh-progress-fill ' + status, 'style': 'width: ' + Math.min(value, 100) + '%' })
])
]);
},
renderComponent: function(c, showActions) {
return E('div', { 'class': 'sh-component-card', 'style': '--component-color: ' + c.color }, [
E('div', { 'class': 'sh-component-header' }, [
E('div', { 'class': 'sh-component-info' }, [
E('div', { 'class': 'sh-component-icon' }, api.getComponentIcon(c.icon)),
E('div', {}, [
E('div', { 'class': 'sh-component-name' }, c.name),
E('div', { 'class': 'sh-component-desc' }, c.description)
])
]),
E('div', { 'class': 'sh-component-status ' + (c.running ? 'running' : 'stopped') },
c.running ? 'Running' : 'Stopped')
])
]);
},
pollData: function() {
// Poll implementation
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});