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