style(network-tweaks): Migrate overview.js to KISS theme

- Remove external CSS loading (dashboard.css)
- Convert impact cards to KISS grid with CSS variables
- Update proxy settings cards (AdGuard, CDN Cache, WPAD) to KISS styling
- Convert components grid and cards to KISS theme
- Update sync section and component details modal
- Use KissTheme.E() throughout with consistent styling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-12 12:14:04 +01:00
parent 7a9de56ba1
commit 4ef8fdbe07

View File

@ -83,6 +83,11 @@ var callSetAdGuardEnabled = rpc.declare({
expect: { } expect: { }
}); });
/**
* Network Services Dashboard - KISS Style
* Copyright (C) 2025 CyberMind.fr
*/
return view.extend({ return view.extend({
proxyStatusData: {}, proxyStatusData: {},
componentsData: [], componentsData: [],
@ -90,14 +95,6 @@ return view.extend({
networkModeData: {}, networkModeData: {},
load: function() { load: function() {
// Load CSS
var cssLink = E('link', {
'rel': 'stylesheet',
'type': 'text/css',
'href': L.resource('network-tweaks/dashboard.css')
});
document.head.appendChild(cssLink);
return Promise.all([ return Promise.all([
callNetworkTweaksStatus(), callNetworkTweaksStatus(),
callGetNetworkComponents(), callGetNetworkComponents(),
@ -172,7 +169,8 @@ return view.extend({
}, },
renderDashboard: function() { renderDashboard: function() {
return E('div', { 'class': 'network-tweaks-dashboard' }, [ var K = KissTheme;
return K.E('div', { 'class': 'network-tweaks-dashboard' }, [
this.renderCumulativeImpact(), this.renderCumulativeImpact(),
this.renderNetworkModeStatus(), this.renderNetworkModeStatus(),
this.renderProxySettings(), this.renderProxySettings(),
@ -182,185 +180,169 @@ return view.extend({
}, },
renderCumulativeImpact: function() { renderCumulativeImpact: function() {
var K = KissTheme;
var cumulative = this.cumulativeData; var cumulative = this.cumulativeData;
var colors = {
primary: 'var(--kiss-blue, #3b82f6)',
info: 'var(--kiss-purple, #6366f1)',
success: 'var(--kiss-green, #22c55e)',
warning: 'var(--kiss-yellow, #fbbf24)'
};
return E('div', { 'class': 'cumulative-impact-section' }, [ return K.E('div', { 'class': 'kiss-card', 'style': 'margin-bottom: 16px;' }, [
E('h3', {}, _('Network Impact Summary')), K.E('div', { 'class': 'kiss-card-title' }, ['📊 ', 'Network Impact Summary']),
E('div', { 'class': 'impact-grid' }, [ K.E('div', { 'class': 'kiss-grid kiss-grid-4', 'style': 'gap: 16px;' }, [
this.renderImpactCard( this.renderImpactCard(K, 'Active Components', cumulative.active_components || 0, '🔧', colors.primary),
_('Active Components'), this.renderImpactCard(K, 'DNS Entries', cumulative.total_dns_entries || 0, '🌐', colors.info),
cumulative.active_components || 0, this.renderImpactCard(K, 'Published VHosts', cumulative.total_vhosts || 0, '📡', colors.success),
'\ud83d\udd27', this.renderImpactCard(K, 'Exposed Ports', cumulative.total_ports_exposed || 0, '🔌', colors.warning)
'primary'
),
this.renderImpactCard(
_('DNS Entries'),
cumulative.total_dns_entries || 0,
'\ud83c\udf10',
'info'
),
this.renderImpactCard(
_('Published VHosts'),
cumulative.total_vhosts || 0,
'\ud83d\udce1',
'success'
),
this.renderImpactCard(
_('Exposed Ports'),
cumulative.total_ports_exposed || 0,
'\ud83d\udd0c',
'warning'
)
]) ])
]); ]);
}, },
renderImpactCard: function(label, value, icon, color) { renderImpactCard: function(K, label, value, icon, color) {
return E('div', { 'class': 'impact-card impact-' + color }, [ return K.E('div', {
E('div', { 'class': 'impact-icon' }, icon), 'style': 'background: var(--kiss-bg2, #111827); border: 1px solid var(--kiss-line, #1e293b); border-radius: 12px; padding: 20px; text-align: center;'
E('div', { 'class': 'impact-value' }, String(value)), }, [
E('div', { 'class': 'impact-label' }, label) K.E('div', { 'style': 'font-size: 24px; margin-bottom: 8px;' }, icon),
K.E('div', { 'style': 'font-size: 32px; font-weight: bold; color: ' + color }, String(value)),
K.E('div', { 'style': 'font-size: 12px; color: var(--kiss-muted); margin-top: 4px;' }, label)
]); ]);
}, },
renderNetworkModeStatus: function() { renderNetworkModeStatus: function() {
var K = KissTheme;
var mode = this.networkModeData; var mode = this.networkModeData;
var modeId = mode.current_mode || 'unknown'; var modeId = mode.current_mode || 'unknown';
var modeName = mode.mode_name || modeId; var modeName = mode.mode_name || modeId;
var syncEnabled = mode.sync_enabled || false; var syncEnabled = mode.sync_enabled || false;
return E('div', { 'class': 'network-mode-status' }, [ return K.E('div', { 'class': 'kiss-card', 'style': 'margin-bottom: 16px;' }, [
E('h3', {}, _('Network Mode Integration')), K.E('div', { 'class': 'kiss-card-title' }, ['🎯 ', 'Network Mode Integration']),
E('div', { 'class': 'mode-info' }, [ K.E('div', { 'style': 'display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;' }, [
E('div', { 'class': 'mode-indicator' }, [ K.E('div', { 'style': 'display: flex; align-items: center; gap: 10px;' }, [
E('span', { 'class': 'mode-icon' }, '\ud83c\udfaf'), K.E('span', { 'style': 'font-size: 20px;' }, '🎯'),
E('span', { 'class': 'mode-name' }, modeName) K.E('span', { 'style': 'font-size: 16px; font-weight: bold;' }, modeName)
]), ]),
E('div', { 'class': 'sync-status' }, [ K.E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [
E('span', { 'class': 'status-label' }, _('DNS Sync: ')), K.E('span', { 'style': 'color: var(--kiss-muted); font-size: 13px;' }, 'DNS Sync:'),
E('span', { 'class': 'status-value' }, syncEnabled
syncEnabled ? _('Enabled') : _('Disabled')) ? K.E('span', { 'style': 'background: var(--kiss-green); color: #000; padding: 4px 10px; border-radius: 6px; font-size: 12px; font-weight: bold;' }, 'Enabled')
: K.E('span', { 'style': 'background: var(--kiss-muted); color: #fff; padding: 4px 10px; border-radius: 6px; font-size: 12px;' }, 'Disabled')
]) ])
]) ])
]); ]);
}, },
renderProxySettings: function() { renderProxySettings: function() {
var K = KissTheme;
var self = this;
var proxy = this.proxyStatusData; var proxy = this.proxyStatusData;
var cdnCache = proxy.cdn_cache || {}; var cdnCache = proxy.cdn_cache || {};
var wpad = proxy.wpad || {}; var wpad = proxy.wpad || {};
var adguard = proxy.adguard_home || {}; var adguard = proxy.adguard_home || {};
var cdnStatusClass = cdnCache.running ? 'status-running' : 'status-stopped'; var cardStyle = 'background: var(--kiss-bg2, #111827); border: 1px solid var(--kiss-line, #1e293b); border-radius: 12px; padding: 16px;';
var cdnStatusText = cdnCache.running ? _('Running') : _('Stopped'); var headerStyle = 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;';
var cdnListeningText = cdnCache.listening ? var infoStyle = 'font-size: 13px; color: var(--kiss-muted); margin-bottom: 12px;';
_('Listening on port ') + (cdnCache.port || 3128) : var actionsStyle = 'display: flex; gap: 8px;';
_('Not listening');
var wpadStatusClass = wpad.enabled ? 'status-running' : 'status-stopped'; var statusBadge = function(running, text) {
var wpadStatusText = wpad.enabled ? _('Enabled') : _('Disabled'); return K.E('span', {
'style': 'padding: 4px 10px; border-radius: 6px; font-size: 12px; font-weight: bold; ' +
(running ? 'background: var(--kiss-green); color: #000;' : 'background: var(--kiss-red); color: #fff;')
}, text);
};
var adguardStatusClass = adguard.running ? 'status-running' : 'status-stopped'; return K.E('div', { 'class': 'kiss-card', 'style': 'margin-bottom: 16px;' }, [
var adguardStatusText = adguard.running ? _('Running') : _('Stopped'); K.E('div', { 'class': 'kiss-card-title' }, ['🛡️ ', 'DNS & Proxy Services']),
K.E('div', { 'class': 'kiss-grid kiss-grid-3', 'style': 'gap: 16px;' }, [
return E('div', { 'class': 'proxy-settings-section' }, [
E('h3', {}, _('DNS & Proxy Services')),
E('div', { 'class': 'proxy-grid', 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1rem;' }, [
// AdGuard Home Card // AdGuard Home Card
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [ K.E('div', { 'style': cardStyle }, [
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': headerStyle }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [ K.E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83d\udee1\ufe0f'), K.E('span', { 'style': 'font-size: 20px;' }, '🛡️'),
E('span', { 'style': 'font-weight: bold;' }, _('AdGuard Home')) K.E('span', { 'style': 'font-weight: bold;' }, 'AdGuard Home')
]), ]),
E('span', { statusBadge(adguard.running, adguard.running ? 'Running' : 'Stopped')
'class': 'status-badge ' + adguardStatusClass,
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
(adguard.running ? 'background: #22c55e;' : 'background: #ef4444;')
}, adguardStatusText)
]), ]),
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': infoStyle }, [
E('div', {}, adguard.installed ? K.E('div', {}, adguard.installed ? 'Web UI: port ' + (adguard.port || 3000) : 'Not installed'),
_('Web UI: port ') + (adguard.port || 3000) : K.E('div', {}, adguard.installed ? 'DNS: port ' + (adguard.dns_port || 53) : 'Install via adguardhomectl')
_('Not installed')),
E('div', {}, adguard.installed ?
_('DNS: port ') + (adguard.dns_port || 53) :
_('Install via adguardhomectl'))
]), ]),
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [ K.E('div', { 'style': actionsStyle }, [
adguard.installed ? adguard.installed
E('button', { ? K.E('button', {
'class': 'btn cbi-button', 'class': 'kiss-btn ' + (adguard.enabled ? 'kiss-btn-red' : 'kiss-btn-green'),
'click': L.bind(this.handleAdGuardToggle, this) 'style': 'padding: 6px 12px; font-size: 12px;',
}, adguard.enabled ? _('Disable') : _('Enable')) : 'click': L.bind(self.handleAdGuardToggle, self)
E('button', { }, adguard.enabled ? 'Disable' : 'Enable')
'class': 'btn cbi-button', : K.E('button', {
'class': 'kiss-btn',
'style': 'padding: 6px 12px; font-size: 12px; opacity: 0.5;',
'disabled': 'disabled' 'disabled': 'disabled'
}, _('Not Installed')), }, 'Not Installed'),
adguard.running ? E('a', { adguard.running ? K.E('a', {
'class': 'btn cbi-button', 'class': 'kiss-btn kiss-btn-blue',
'style': 'padding: 6px 12px; font-size: 12px; text-decoration: none;',
'href': 'http://' + window.location.hostname + ':' + (adguard.port || 3000), 'href': 'http://' + window.location.hostname + ':' + (adguard.port || 3000),
'target': '_blank' 'target': '_blank'
}, _('Open UI')) : null }, 'Open UI') : null
].filter(Boolean)) ].filter(Boolean))
]), ]),
// CDN Cache Card // CDN Cache Card
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [ K.E('div', { 'style': cardStyle }, [
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': headerStyle }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [ K.E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83d\udce6'), K.E('span', { 'style': 'font-size: 20px;' }, '📦'),
E('span', { 'style': 'font-weight: bold;' }, _('CDN Cache')) K.E('span', { 'style': 'font-weight: bold;' }, 'CDN Cache')
]), ]),
E('span', { statusBadge(cdnCache.running, cdnCache.running ? 'Running' : 'Stopped')
'class': 'status-badge ' + cdnStatusClass,
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
(cdnCache.running ? 'background: #22c55e;' : 'background: #ef4444;')
}, cdnStatusText)
]), ]),
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': infoStyle }, [
E('div', {}, cdnListeningText), K.E('div', {}, cdnCache.listening ? 'Listening on port ' + (cdnCache.port || 3128) : 'Not listening'),
E('div', {}, cdnCache.installed ? _('nginx proxy installed') : _('Not installed')) K.E('div', {}, cdnCache.installed ? 'nginx proxy installed' : 'Not installed')
]), ]),
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, K.E('div', { 'style': actionsStyle },
cdnCache.installed ? [ cdnCache.installed ? [
E('button', { K.E('button', {
'class': 'btn cbi-button', 'class': 'kiss-btn ' + (cdnCache.enabled ? 'kiss-btn-red' : 'kiss-btn-green'),
'click': L.bind(this.handleCdnCacheToggle, this) 'style': 'padding: 6px 12px; font-size: 12px;',
}, cdnCache.enabled ? _('Disable') : _('Enable')), 'click': L.bind(self.handleCdnCacheToggle, self)
E('button', { }, cdnCache.enabled ? 'Disable' : 'Enable'),
'class': 'btn cbi-button', K.E('button', {
'click': L.bind(this.handleCdnCacheRestart, this) 'class': 'kiss-btn kiss-btn-blue',
}, _('Restart')) 'style': 'padding: 6px 12px; font-size: 12px;',
] : [ 'click': L.bind(self.handleCdnCacheRestart, self)
E('button', { }, 'Restart')
'class': 'btn cbi-button', ] : [
'disabled': 'disabled' K.E('button', {
}, _('Not Installed')) 'class': 'kiss-btn',
] 'style': 'padding: 6px 12px; font-size: 12px; opacity: 0.5;',
) 'disabled': 'disabled'
}, 'Not Installed')
]
)
]), ]),
// WPAD Card // WPAD Card
E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [ K.E('div', { 'style': cardStyle }, [
E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': headerStyle }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [ K.E('div', { 'style': 'display: flex; align-items: center; gap: 8px;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '\ud83c\udf10'), K.E('span', { 'style': 'font-size: 20px;' }, '🌐'),
E('span', { 'style': 'font-weight: bold;' }, _('WPAD Auto-Proxy')) K.E('span', { 'style': 'font-weight: bold;' }, 'WPAD Auto-Proxy')
]), ]),
E('span', { statusBadge(wpad.enabled, wpad.enabled ? 'Enabled' : 'Disabled')
'class': 'status-badge ' + wpadStatusClass,
'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' +
(wpad.enabled ? 'background: #22c55e;' : 'background: #ef4444;')
}, wpadStatusText)
]), ]),
E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [ K.E('div', { 'style': infoStyle }, [
E('div', {}, wpad.dhcp_configured ? _('DHCP Option 252 configured') : _('DHCP not configured')), K.E('div', {}, wpad.dhcp_configured ? 'DHCP Option 252 configured' : 'DHCP not configured'),
E('div', {}, wpad.url ? wpad.url : _('No PAC URL set')) K.E('div', {}, wpad.url ? wpad.url : 'No PAC URL set')
]), ]),
E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [ K.E('div', { 'style': actionsStyle }, [
E('button', { K.E('button', {
'class': 'btn cbi-button', 'class': 'kiss-btn ' + (wpad.enabled ? 'kiss-btn-red' : 'kiss-btn-green'),
'click': L.bind(this.handleWpadToggle, this) 'style': 'padding: 6px 12px; font-size: 12px;',
}, wpad.enabled ? _('Disable') : _('Enable')) 'click': L.bind(self.handleWpadToggle, self)
}, wpad.enabled ? 'Disable' : 'Enable')
]) ])
]) ])
]) ])
@ -447,89 +429,84 @@ return view.extend({
}, },
renderComponentsGrid: function() { renderComponentsGrid: function() {
var K = KissTheme;
var components = this.componentsData; var components = this.componentsData;
if (components.length === 0) { if (components.length === 0) {
return E('div', { 'class': 'empty-state' }, [ return K.E('div', { 'class': 'kiss-card', 'style': 'text-align: center; padding: 40px;' }, [
E('p', {}, _('No network-impacting components detected')) K.E('div', { 'style': 'font-size: 48px; margin-bottom: 12px;' }, '📭'),
K.E('p', { 'style': 'color: var(--kiss-muted);' }, 'No network-impacting components detected')
]); ]);
} }
return E('div', { 'class': 'components-grid-section' }, [ return K.E('div', { 'class': 'kiss-card', 'style': 'margin-bottom: 16px;' }, [
E('h3', {}, _('Network Services')), K.E('div', { 'class': 'kiss-card-title' }, ['🔧 ', 'Network Services']),
E('div', { K.E('div', {
'class': 'components-grid', 'class': 'kiss-grid kiss-grid-3',
'style': 'gap: 16px;',
'id': 'components-grid' 'id': 'components-grid'
}, components.map(L.bind(this.renderComponentCard, this))) }, components.map(L.bind(this.renderComponentCard, this)))
]); ]);
}, },
renderComponentCard: function(component) { renderComponentCard: function(component) {
var statusClass = 'status-' + component.service_state.replace('/', '\\/'); var K = KissTheme;
var self = this;
var stateLabel = { var stateLabel = {
'running': _('Running'), 'running': 'Running',
'stopped': _('Stopped'), 'stopped': 'Stopped',
'n/a': _('N/A') 'n/a': 'N/A'
}[component.service_state] || component.service_state; }[component.service_state] || component.service_state;
var stateColor = component.service_state === 'running' ? 'var(--kiss-green)' : 'var(--kiss-muted)';
var impact = component.network_impact || {}; var impact = component.network_impact || {};
return E('div', { return K.E('div', {
'class': 'component-card ' + statusClass, 'style': 'background: var(--kiss-bg2, #111827); border: 1px solid var(--kiss-line, #1e293b); border-radius: 12px; padding: 16px;',
'data-component-id': component.id 'data-component-id': component.id
}, [ }, [
E('div', { 'class': 'component-header' }, [ K.E('div', { 'style': 'display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px;' }, [
E('div', { 'class': 'component-title' }, [ K.E('div', {}, [
E('h4', {}, component.name), K.E('h4', { 'style': 'margin: 0 0 4px; font-size: 14px;' }, component.name),
E('span', { 'class': 'component-status ' + statusClass }, stateLabel) K.E('span', { 'style': 'font-size: 12px; color: ' + stateColor + ';' }, '● ' + stateLabel)
]), ]),
E('span', { K.E('span', {
'class': 'install-badge install-' + component.install_state.replace('/', '\\/') 'style': 'background: var(--kiss-purple, #6366f1); color: #fff; padding: 2px 8px; border-radius: 4px; font-size: 11px;'
}, component.install_state) }, component.install_state)
]), ]),
E('div', { 'class': 'component-impact' }, [ K.E('div', { 'style': 'font-size: 12px; color: var(--kiss-muted); margin-bottom: 12px;' }, [
E('div', { 'class': 'impact-row' }, [ K.E('div', { 'style': 'display: flex; gap: 16px; flex-wrap: wrap;' }, [
E('span', { 'class': 'impact-icon' }, '\ud83c\udf10'), K.E('span', {}, '🌐 ' + (impact.dns_entries || 0) + ' DNS'),
E('span', { 'class': 'impact-text' }, K.E('span', {}, '📡 ' + (impact.vhosts || 0) + ' VHosts'),
(impact.dns_entries || 0) + ' ' + _('DNS entries')) K.E('span', {}, '🔌 ' + (impact.ports || 0) + ' ports')
]),
E('div', { 'class': 'impact-row' }, [
E('span', { 'class': 'impact-icon' }, '\ud83d\udce1'),
E('span', { 'class': 'impact-text' },
(impact.vhosts || 0) + ' ' + _('VHosts'))
]),
E('div', { 'class': 'impact-row' }, [
E('span', { 'class': 'impact-icon' }, '\ud83d\udd0c'),
E('span', { 'class': 'impact-text' },
(impact.ports || 0) + ' ' + _('ports'))
]) ])
]), ]),
E('div', { 'class': 'component-contribution' }, [ K.E('div', { 'style': 'font-size: 11px; color: var(--kiss-muted); margin-bottom: 12px;' }, [
E('small', {}, _('Contributes: ')), 'Contributes: ',
E('span', {}, (component.cumulative_contribution?.dnsmasq_entries || 0) + ' dnsmasq, ' +
(component.cumulative_contribution?.dnsmasq_entries || 0) + ' dnsmasq, ' + (component.cumulative_contribution?.hosts_entries || 0) + ' hosts'
(component.cumulative_contribution?.hosts_entries || 0) + ' hosts')
]), ]),
E('div', { 'class': 'component-actions' }, [ K.E('div', {}, [
E('button', { K.E('button', {
'class': 'btn', 'class': 'kiss-btn',
'click': L.bind(function(componentId, ev) { 'style': 'padding: 6px 12px; font-size: 12px;',
this.showComponentDetails(componentId); 'click': function() { self.showComponentDetails(component.id); }
}, this, component.id) }, 'Details')
}, _('Details'))
]) ])
]); ]);
}, },
renderSyncSection: function() { renderSyncSection: function() {
return E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2rem;' }, [ var K = KissTheme;
E('h3', {}, _('Manual Synchronization')), return K.E('div', { 'class': 'kiss-card' }, [
E('div', { 'class': 'cbi-section-descr' }, K.E('div', { 'class': 'kiss-card-title' }, ['🔄 ', 'Manual Synchronization']),
_('Trigger immediate synchronization of DNS and hosts entries')), K.E('p', { 'style': 'color: var(--kiss-muted); margin-bottom: 16px; font-size: 13px;' },
E('button', { 'Trigger immediate synchronization of DNS and hosts entries'),
'class': 'btn cbi-button-apply', K.E('button', {
'class': 'kiss-btn kiss-btn-green',
'style': 'padding: 10px 20px;',
'click': L.bind(this.handleSyncNow, this) 'click': L.bind(this.handleSyncNow, this)
}, _('Sync Now')) }, '🔄 Sync Now')
]); ]);
}, },
@ -563,44 +540,50 @@ return view.extend({
var capabilities = component.capabilities || []; var capabilities = component.capabilities || [];
var content = [ var content = [
E('h3', {}, component.name), E('h3', { 'style': 'margin: 0 0 16px; display: flex; align-items: center; gap: 10px;' }, [
E('div', { 'style': 'margin: 1rem 0;' }, [ E('span', {}, '🔧'),
E('strong', {}, _('Category: ')), component.name
E('span', {}, component.category)
]), ]),
E('div', { 'style': 'margin: 1rem 0;' }, [ E('div', { 'style': 'display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px;' }, [
E('strong', {}, _('Install State: ')), E('div', {}, [
E('span', {}, component.install_state) E('div', { 'style': 'font-size: 11px; color: var(--kiss-muted); text-transform: uppercase;' }, 'Category'),
E('div', { 'style': 'font-size: 14px;' }, component.category)
]),
E('div', {}, [
E('div', { 'style': 'font-size: 11px; color: var(--kiss-muted); text-transform: uppercase;' }, 'Install State'),
E('div', { 'style': 'font-size: 14px;' }, component.install_state)
]),
E('div', {}, [
E('div', { 'style': 'font-size: 11px; color: var(--kiss-muted); text-transform: uppercase;' }, 'Service State'),
E('div', { 'style': 'font-size: 14px;' }, component.service_state)
])
]), ]),
E('div', { 'style': 'margin: 1rem 0;' }, [ E('h4', { 'style': 'margin: 0 0 12px; font-size: 14px;' }, '📊 Network Impact'),
E('strong', {}, _('Service State: ')), E('div', { 'style': 'display: flex; gap: 20px; margin-bottom: 20px;' }, [
E('span', {}, component.service_state) E('span', {}, '🌐 ' + (impact.dns_entries || 0) + ' DNS entries'),
E('span', {}, '📡 ' + (impact.vhosts || 0) + ' VHosts'),
E('span', {}, '🔌 ' + (impact.ports || 0) + ' ports')
]), ]),
E('h4', {}, _('Network Impact')), E('h4', { 'style': 'margin: 0 0 12px; font-size: 14px;' }, '⚡ Capabilities'),
E('ul', {}, [ E('div', { 'style': 'margin-bottom: 20px;' },
E('li', {}, _('DNS Entries: ') + (impact.dns_entries || 0)),
E('li', {}, _('VHosts: ') + (impact.vhosts || 0)),
E('li', {}, _('Ports: ') + (impact.ports || 0))
]),
E('h4', {}, _('Capabilities')),
E('div', {},
capabilities.length > 0 capabilities.length > 0
? capabilities.map(function(cap) { ? capabilities.map(function(cap) {
return E('span', { return E('span', {
'style': 'display: inline-block; background: #e9ecef; padding: 0.25rem 0.5rem; margin: 0.25rem; border-radius: 4px; font-size: 0.875rem;' 'style': 'display: inline-block; background: var(--kiss-purple, #6366f1); color: #fff; padding: 4px 10px; margin: 4px; border-radius: 6px; font-size: 12px;'
}, cap); }, cap);
}) })
: E('p', {}, _('None')) : E('p', { 'style': 'color: var(--kiss-muted);' }, 'None')
), ),
E('div', { 'class': 'right', 'style': 'margin-top: 2rem;' }, [ E('div', { 'style': 'text-align: right;' }, [
E('button', { E('button', {
'class': 'btn cbi-button', 'class': 'kiss-btn',
'style': 'padding: 10px 20px;',
'click': ui.hideModal 'click': ui.hideModal
}, _('Close')) }, 'Close')
]) ])
]; ];
ui.showModal(_('Component Details'), content, 'cbi-modal'); ui.showModal('Component Details', content, 'cbi-modal');
}, },
pollData: function() { pollData: function() {