4 Commits

Author SHA1 Message Date
f74c8e5410 v3.39.0
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-01-12 23:44:05 +00:00
abeb8ecda3 feat(eco-view-system): add memory usage history, process metrics, and top processes display with loading fallback 2026-01-12 23:44:05 +00:00
b5dc6204ce v3.38.0
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-01-12 18:10:20 +00:00
b800740d5d feat(eco-view-system): add extended system metrics and display formatted total network usage in eco system view 2026-01-12 18:10:20 +00:00
5 changed files with 249 additions and 219 deletions

View File

@@ -1,5 +1,22 @@
# Changelog # Changelog
## 2026-01-12 - 3.39.0 - feat(eco-view-system)
add memory usage history, process metrics, and top processes display with loading fallback
- Add memoryUsageHistory state and update it in setMetrics to track memory usage trend
- Introduce process state: processTotal, processRunning, processSleeping, processBlocked, and topProcesses
- Extend setProcesses signature to accept blocked and a typed process list and store values in state
- Use reactive state values in UI tiles (memory trend, process tiles) instead of hardcoded placeholders
- Replace 'Threads' tile with 'Blocked' tile and update its icon and color
- Render top processes from state and show a 'Loading...' fallback when the list is empty
## 2026-01-12 - 3.38.0 - feat(eco-view-system)
add extended system metrics and display formatted total network usage in eco system view
- Added numerous new observable properties for richer system telemetry: cpuPhysicalCores, cpuSpeedMax, memoryAvailable, memoryCached, memoryBuffers, swapTotal, swapUsed, diskTotal, diskUsed, diskFree, networkRxSec, networkTxSec, networkRxTotal, networkTxTotal, distro, and coreLoads.
- Reworked network/usage UI: removed several temporary network/latency cards and replaced them with Total Downloaded/Uploaded cards that use formatBytes(...) and show totals since boot.
- Bumped dependency @design.estate/dees-catalog from ^3.34.1 to ^3.35.0.
## 2026-01-12 - 3.37.0 - feat(elements) ## 2026-01-12 - 3.37.0 - feat(elements)
add eco-provider-frame and dataprovider interfaces; improve virtual keyboard interactions; add demos, exports and bump dev dependencies add eco-provider-frame and dataprovider interfaces; improve virtual keyboard interactions; add demos, exports and bump dev dependencies

View File

@@ -1,6 +1,6 @@
{ {
"name": "@ecobridge.xyz/catalog", "name": "@ecobridge.xyz/catalog",
"version": "3.37.0", "version": "3.39.0",
"private": false, "private": false,
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.", "description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",
@@ -15,7 +15,7 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-catalog": "^3.34.1", "@design.estate/dees-catalog": "^3.35.0",
"@design.estate/dees-domtools": "^2.3.7", "@design.estate/dees-domtools": "^2.3.7",
"@design.estate/dees-element": "^2.1.5", "@design.estate/dees-element": "^2.1.5",
"@push.rocks/smartpromise": "^4.2.3", "@push.rocks/smartpromise": "^4.2.3",

12
pnpm-lock.yaml generated
View File

@@ -9,8 +9,8 @@ importers:
.: .:
dependencies: dependencies:
'@design.estate/dees-catalog': '@design.estate/dees-catalog':
specifier: ^3.34.1 specifier: ^3.35.0
version: 3.34.1(@tiptap/pm@2.27.2) version: 3.35.0(@tiptap/pm@2.27.2)
'@design.estate/dees-domtools': '@design.estate/dees-domtools':
specifier: ^2.3.7 specifier: ^2.3.7
version: 2.3.7 version: 2.3.7
@@ -398,8 +398,8 @@ packages:
'@configvault.io/interfaces@1.0.17': '@configvault.io/interfaces@1.0.17':
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==} resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
'@design.estate/dees-catalog@3.34.1': '@design.estate/dees-catalog@3.35.0':
resolution: {integrity: sha512-jm/ZPoLgBHicIlrGPTiCynztFEemJGHweiz+GQK9FppFfjCCC47AOHI4ZjIhrNibfyPXGfqfFWr7DI0zCOl1gw==} resolution: {integrity: sha512-6K5ddjpZOh8JVmxr/XkBGOARGLDIXKWPeyo+NeGrmNMG5HOFSdGj2RnDqK9FkH0zxG1u1hG9T/EdIMmcEKgIvw==}
'@design.estate/dees-comms@1.0.30': '@design.estate/dees-comms@1.0.30':
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==} resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
@@ -4309,7 +4309,7 @@ snapshots:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@1.4.0) '@api.global/typedsocket': 4.1.0(@push.rocks/smartserve@1.4.0)
'@cloudflare/workers-types': 4.20251211.0 '@cloudflare/workers-types': 4.20251211.0
'@design.estate/dees-catalog': 3.34.1(@tiptap/pm@2.27.2) '@design.estate/dees-catalog': 3.35.0(@tiptap/pm@2.27.2)
'@design.estate/dees-comms': 1.0.30 '@design.estate/dees-comms': 1.0.30
'@push.rocks/lik': 6.2.2 '@push.rocks/lik': 6.2.2
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
@@ -5317,7 +5317,7 @@ snapshots:
dependencies: dependencies:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@design.estate/dees-catalog@3.34.1(@tiptap/pm@2.27.2)': '@design.estate/dees-catalog@3.35.0(@tiptap/pm@2.27.2)':
dependencies: dependencies:
'@design.estate/dees-domtools': 2.3.7 '@design.estate/dees-domtools': 2.3.7
'@design.estate/dees-element': 2.1.5 '@design.estate/dees-element': 2.1.5

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@ecobridge.xyz/catalog', name: '@ecobridge.xyz/catalog',
version: '3.37.0', version: '3.39.0',
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.' description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
} }

View File

@@ -168,12 +168,18 @@ export class EcoViewSystem extends DeesElement {
@property({ type: Number }) @property({ type: Number })
accessor cpuCores = 0; accessor cpuCores = 0;
@property({ type: Number })
accessor cpuPhysicalCores = 0;
@property({ type: String }) @property({ type: String })
accessor cpuModel = 'Unknown'; accessor cpuModel = 'Unknown';
@property({ type: Number }) @property({ type: Number })
accessor cpuSpeed = 0; accessor cpuSpeed = 0;
@property({ type: Number })
accessor cpuSpeedMax = 0;
@property({ type: Number }) @property({ type: Number })
accessor memoryTotal = 0; accessor memoryTotal = 0;
@@ -183,41 +189,155 @@ export class EcoViewSystem extends DeesElement {
@property({ type: Number }) @property({ type: Number })
accessor memoryFree = 0; accessor memoryFree = 0;
@property({ type: Number })
accessor memoryAvailable = 0;
@property({ type: Number })
accessor memoryCached = 0;
@property({ type: Number })
accessor memoryBuffers = 0;
@property({ type: Number })
accessor swapTotal = 0;
@property({ type: Number })
accessor swapUsed = 0;
@property({ type: Number })
accessor diskTotal = 0;
@property({ type: Number })
accessor diskUsed = 0;
@property({ type: Number })
accessor diskFree = 0;
@property({ type: Number })
accessor networkRxSec = 0;
@property({ type: Number })
accessor networkTxSec = 0;
@property({ type: Number })
accessor networkRxTotal = 0;
@property({ type: Number })
accessor networkTxTotal = 0;
@property({ type: String }) @property({ type: String })
accessor hostname = 'Unknown'; accessor hostname = 'Unknown';
@property({ type: String }) @property({ type: String })
accessor platform = 'Unknown'; accessor platform = 'Unknown';
@property({ type: String })
accessor distro = '';
@property({ type: Array }) @property({ type: Array })
accessor loadAvg: number[] = [0, 0, 0]; accessor loadAvg: number[] = [0, 0, 0];
@state() @property({ type: Array })
accessor networkIn = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; accessor coreLoads: number[] = [];
@state() @state()
accessor networkOut = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; accessor networkInHistory: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@state()
accessor networkOutHistory: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
@state()
accessor memoryUsageHistory: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Process data
@state()
accessor processTotal = 0;
@state()
accessor processRunning = 0;
@state()
accessor processSleeping = 0;
@state()
accessor processBlocked = 0;
@state()
accessor topProcesses: Array<{ name: string; pid: number; cpu: number; memory: number; state: string }> = [];
// Public method to update metrics from backend // Public method to update metrics from backend
public setMetrics(metrics: { public setMetrics(metrics: {
cpu: { usage: number; cores: number; model: string; speed: number; loadAvg: number[] }; cpu: { usage: number; cores: number; physicalCores?: number; model: string; speed: number; speedMax?: number; loadAvg: number[]; coreLoads?: number[] };
memory: { total: number; used: number; free: number; usagePercent: number }; memory: { total: number; used: number; free: number; available?: number; usagePercent: number; swapTotal?: number; swapUsed?: number; cached?: number; buffers?: number };
system: { platform: string; hostname: string; uptimeFormatted: string }; disk?: { total: number; used: number; free: number; usagePercent: number };
network?: { rxSec: number; txSec: number; rxTotal: number; txTotal: number };
system: { platform: string; distro?: string; hostname: string; uptimeFormatted: string };
}): void { }): void {
// CPU metrics
this.cpuUsage = metrics.cpu.usage; this.cpuUsage = metrics.cpu.usage;
this.cpuCores = metrics.cpu.cores; this.cpuCores = metrics.cpu.cores;
this.cpuPhysicalCores = metrics.cpu.physicalCores || metrics.cpu.cores;
this.cpuModel = metrics.cpu.model; this.cpuModel = metrics.cpu.model;
this.cpuSpeed = metrics.cpu.speed; this.cpuSpeed = metrics.cpu.speed;
this.cpuSpeedMax = metrics.cpu.speedMax || metrics.cpu.speed;
this.loadAvg = metrics.cpu.loadAvg; this.loadAvg = metrics.cpu.loadAvg;
this.coreLoads = metrics.cpu.coreLoads || [];
// Memory metrics
this.memoryUsage = metrics.memory.usagePercent; this.memoryUsage = metrics.memory.usagePercent;
this.memoryTotal = metrics.memory.total; this.memoryTotal = metrics.memory.total;
this.memoryUsed = metrics.memory.used; this.memoryUsed = metrics.memory.used;
this.memoryFree = metrics.memory.free; this.memoryFree = metrics.memory.free;
this.memoryAvailable = metrics.memory.available || metrics.memory.free;
this.memoryCached = metrics.memory.cached || 0;
this.memoryBuffers = metrics.memory.buffers || 0;
this.swapTotal = metrics.memory.swapTotal || 0;
this.swapUsed = metrics.memory.swapUsed || 0;
// Update memory usage history for trend chart
this.memoryUsageHistory = [...this.memoryUsageHistory.slice(1), metrics.memory.usagePercent];
// Disk metrics
if (metrics.disk) {
this.diskUsage = metrics.disk.usagePercent;
this.diskTotal = metrics.disk.total;
this.diskUsed = metrics.disk.used;
this.diskFree = metrics.disk.free;
}
// Network metrics
if (metrics.network) {
this.networkRxSec = metrics.network.rxSec;
this.networkTxSec = metrics.network.txSec;
this.networkRxTotal = metrics.network.rxTotal;
this.networkTxTotal = metrics.network.txTotal;
// Update history for trend charts
this.networkInHistory = [...this.networkInHistory.slice(1), metrics.network.rxSec];
this.networkOutHistory = [...this.networkOutHistory.slice(1), metrics.network.txSec];
}
// System metrics
this.hostname = metrics.system.hostname; this.hostname = metrics.system.hostname;
this.platform = metrics.system.platform; this.platform = metrics.system.platform;
this.distro = metrics.system.distro || '';
this.uptime = metrics.system.uptimeFormatted; this.uptime = metrics.system.uptimeFormatted;
} }
// Method to set CPU temperature separately (may not always be available)
public setTemperature(temp: { main: number; cores?: number[]; max?: number }): void {
this.cpuTemp = temp.main || 0;
}
// Method to set processes data
public setProcesses(data: { total: number; running: number; sleeping: number; blocked?: number; list: Array<{ name: string; pid: number; cpu: number; memory: number; state: string }> }): void {
this.processTotal = data.total;
this.processRunning = data.running;
this.processSleeping = data.sleeping;
this.processBlocked = data.blocked || 0;
this.topProcesses = data.list || [];
}
// Helper to format bytes // Helper to format bytes
private formatBytes(bytes: number): string { private formatBytes(bytes: number): string {
if (bytes === 0) return '0 B'; if (bytes === 0) return '0 B';
@@ -331,6 +451,15 @@ export class EcoViewSystem extends DeesElement {
} }
} }
// Helper to format bytes per second as speed
private formatSpeed(bytesPerSec: number): string {
if (bytesPerSec === 0) return '0 B/s';
const k = 1024;
const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s'];
const i = Math.floor(Math.log(bytesPerSec) / Math.log(k));
return parseFloat((bytesPerSec / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
private renderOverviewPanel(): TemplateResult { private renderOverviewPanel(): TemplateResult {
const overviewTiles = [ const overviewTiles = [
{ {
@@ -339,6 +468,7 @@ export class EcoViewSystem extends DeesElement {
value: this.cpuUsage, value: this.cpuUsage,
type: 'gauge' as const, type: 'gauge' as const,
icon: 'lucide:cpu', icon: 'lucide:cpu',
description: this.cpuModel !== 'Unknown' ? `${this.cpuPhysicalCores} cores @ ${this.cpuSpeed} GHz` : undefined,
gaugeOptions: { gaugeOptions: {
min: 0, min: 0,
max: 100, max: 100,
@@ -372,6 +502,7 @@ export class EcoViewSystem extends DeesElement {
value: this.diskUsage, value: this.diskUsage,
type: 'gauge' as const, type: 'gauge' as const,
icon: 'lucide:hardDrive', icon: 'lucide:hardDrive',
description: this.diskTotal ? `${this.formatBytes(this.diskUsed)} of ${this.formatBytes(this.diskTotal)}` : undefined,
gaugeOptions: { gaugeOptions: {
min: 0, min: 0,
max: 100, max: 100,
@@ -403,22 +534,22 @@ export class EcoViewSystem extends DeesElement {
{ {
id: 'network-in', id: 'network-in',
title: 'Network In', title: 'Network In',
value: '85', value: this.formatSpeed(this.networkRxSec),
unit: 'Mbps',
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:download', icon: 'lucide:download',
trendData: this.networkIn, trendData: this.networkInHistory,
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
description: `Total: ${this.formatBytes(this.networkRxTotal)}`,
}, },
{ {
id: 'network-out', id: 'network-out',
title: 'Network Out', title: 'Network Out',
value: '65', value: this.formatSpeed(this.networkTxSec),
unit: 'Mbps',
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:upload', icon: 'lucide:upload',
trendData: this.networkOut, trendData: this.networkOutHistory,
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
description: `Total: ${this.formatBytes(this.networkTxTotal)}`,
}, },
{ {
id: 'uptime', id: 'uptime',
@@ -435,7 +566,7 @@ export class EcoViewSystem extends DeesElement {
value: this.hostname, value: this.hostname,
type: 'text' as const, type: 'text' as const,
icon: 'lucide:server', icon: 'lucide:server',
description: `${this.platform} - ${this.cpuCores} cores`, description: this.distro ? `${this.distro} - ${this.cpuCores} threads` : `${this.platform} - ${this.cpuCores} threads`,
}, },
]; ];
@@ -456,6 +587,13 @@ export class EcoViewSystem extends DeesElement {
} }
private renderCpuPanel(): TemplateResult { private renderCpuPanel(): TemplateResult {
// Generate cores data for cpuCores tile type
const coresData = this.coreLoads.map((load, index) => ({
id: index,
usage: load,
label: `Core ${index}`,
}));
const cpuTiles = [ const cpuTiles = [
{ {
id: 'cpu-total', id: 'cpu-total',
@@ -463,6 +601,7 @@ export class EcoViewSystem extends DeesElement {
value: this.cpuUsage, value: this.cpuUsage,
type: 'gauge' as const, type: 'gauge' as const,
icon: 'lucide:cpu', icon: 'lucide:cpu',
description: `${this.cpuCores} threads on ${this.cpuPhysicalCores} cores`,
gaugeOptions: { gaugeOptions: {
min: 0, min: 0,
max: 100, max: 100,
@@ -474,73 +613,21 @@ export class EcoViewSystem extends DeesElement {
}, },
}, },
{ {
id: 'core-0', id: 'cpu-cores',
title: 'Core 0', title: 'Core Usage',
value: 38, value: this.cpuUsage,
type: 'gauge' as const, type: 'cpuCores' as const,
gaugeOptions: { coresData: coresData,
min: 0, columnSpan: 2,
max: 100,
thresholds: [
{ value: 0, color: 'hsl(142 71% 45%)' },
{ value: 60, color: 'hsl(45 93% 47%)' },
{ value: 80, color: 'hsl(0 84% 60%)' },
],
},
},
{
id: 'core-1',
title: 'Core 1',
value: 52,
type: 'gauge' as const,
gaugeOptions: {
min: 0,
max: 100,
thresholds: [
{ value: 0, color: 'hsl(142 71% 45%)' },
{ value: 60, color: 'hsl(45 93% 47%)' },
{ value: 80, color: 'hsl(0 84% 60%)' },
],
},
},
{
id: 'core-2',
title: 'Core 2',
value: 45,
type: 'gauge' as const,
gaugeOptions: {
min: 0,
max: 100,
thresholds: [
{ value: 0, color: 'hsl(142 71% 45%)' },
{ value: 60, color: 'hsl(45 93% 47%)' },
{ value: 80, color: 'hsl(0 84% 60%)' },
],
},
},
{
id: 'core-3',
title: 'Core 3',
value: 33,
type: 'gauge' as const,
gaugeOptions: {
min: 0,
max: 100,
thresholds: [
{ value: 0, color: 'hsl(142 71% 45%)' },
{ value: 60, color: 'hsl(45 93% 47%)' },
{ value: 80, color: 'hsl(0 84% 60%)' },
],
},
}, },
{ {
id: 'load-avg', id: 'load-avg',
title: 'Load Average', title: 'Load Average',
value: '2.45', value: this.loadAvg[0]?.toFixed(2) || '0',
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:activity', icon: 'lucide:activity',
trendData: [1.8, 2.1, 2.4, 2.2, 2.5, 2.3, 2.6, 2.4, 2.45], trendData: this.loadAvg,
description: '1m: 2.45, 5m: 2.32, 15m: 2.18', description: `1m: ${this.loadAvg[0]?.toFixed(2)}, 5m: ${this.loadAvg[1]?.toFixed(2)}, 15m: ${this.loadAvg[2]?.toFixed(2)}`,
}, },
{ {
id: 'cpu-temp', id: 'cpu-temp',
@@ -563,18 +650,18 @@ export class EcoViewSystem extends DeesElement {
{ {
id: 'freq', id: 'freq',
title: 'Clock Speed', title: 'Clock Speed',
value: '3.2', value: this.cpuSpeed.toFixed(1),
unit: 'GHz', unit: 'GHz',
type: 'number' as const, type: 'number' as const,
icon: 'lucide:gauge', icon: 'lucide:gauge',
description: 'Max: 4.2 GHz', description: this.cpuSpeedMax ? `Max: ${this.cpuSpeedMax.toFixed(1)} GHz` : undefined,
}, },
]; ];
return html` return html`
<div class="panel-header"> <div class="panel-header">
<div class="panel-title">CPU</div> <div class="panel-title">CPU</div>
<div class="panel-description">Processor usage and performance</div> <div class="panel-description">${this.cpuModel}</div>
</div> </div>
<div class="stats-section"> <div class="stats-section">
@@ -588,6 +675,8 @@ export class EcoViewSystem extends DeesElement {
} }
private renderMemoryPanel(): TemplateResult { private renderMemoryPanel(): TemplateResult {
const swapUsagePercent = this.swapTotal > 0 ? Math.round((this.swapUsed / this.swapTotal) * 100) : 0;
const memoryTiles = [ const memoryTiles = [
{ {
id: 'ram-usage', id: 'ram-usage',
@@ -604,12 +693,12 @@ export class EcoViewSystem extends DeesElement {
{ value: 85, color: 'hsl(0 84% 60%)' }, { value: 85, color: 'hsl(0 84% 60%)' },
], ],
}, },
description: '10.7 GB of 16 GB', description: `${this.formatBytes(this.memoryUsed)} of ${this.formatBytes(this.memoryTotal)}`,
}, },
{ {
id: 'swap-usage', id: 'swap-usage',
title: 'Swap Usage', title: 'Swap Usage',
value: 12, value: swapUsagePercent,
type: 'gauge' as const, type: 'gauge' as const,
icon: 'lucide:hardDrive', icon: 'lucide:hardDrive',
gaugeOptions: { gaugeOptions: {
@@ -621,41 +710,38 @@ export class EcoViewSystem extends DeesElement {
{ value: 75, color: 'hsl(0 84% 60%)' }, { value: 75, color: 'hsl(0 84% 60%)' },
], ],
}, },
description: '0.5 GB of 4 GB', description: this.swapTotal > 0 ? `${this.formatBytes(this.swapUsed)} of ${this.formatBytes(this.swapTotal)}` : 'No swap',
}, },
{ {
id: 'mem-trend', id: 'mem-trend',
title: 'Memory History', title: 'Memory History',
value: '67%', value: `${this.memoryUsage}%`,
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:trendingUp', icon: 'lucide:trendingUp',
trendData: [58, 62, 65, 63, 68, 72, 70, 65, 67], trendData: this.memoryUsageHistory,
description: 'Last hour', description: 'Recent usage',
}, },
{ {
id: 'cached', id: 'cached',
title: 'Cached', title: 'Cached',
value: '3.2', value: this.formatBytes(this.memoryCached),
unit: 'GB', type: 'text' as const,
type: 'number' as const,
icon: 'lucide:database', icon: 'lucide:database',
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
}, },
{ {
id: 'buffers', id: 'buffers',
title: 'Buffers', title: 'Buffers',
value: '512', value: this.formatBytes(this.memoryBuffers),
unit: 'MB', type: 'text' as const,
type: 'number' as const,
icon: 'lucide:layers', icon: 'lucide:layers',
color: 'hsl(262 83% 58%)', color: 'hsl(262 83% 58%)',
}, },
{ {
id: 'available', id: 'available',
title: 'Available', title: 'Available',
value: '5.3', value: this.formatBytes(this.memoryAvailable),
unit: 'GB', type: 'text' as const,
type: 'number' as const,
icon: 'lucide:checkCircle', icon: 'lucide:checkCircle',
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
}, },
@@ -680,58 +766,39 @@ export class EcoViewSystem extends DeesElement {
private renderStoragePanel(): TemplateResult { private renderStoragePanel(): TemplateResult {
const storageTiles = [ const storageTiles = [
{ {
id: 'disk-main', id: 'disk-total',
title: 'System Drive', title: 'Total Storage',
value: this.diskUsage, value: this.diskUsage,
type: 'percentage' as const, type: 'percentage' as const,
icon: 'lucide:hardDrive', icon: 'lucide:hardDrive',
description: '275 GB of 512 GB used', description: `${this.formatBytes(this.diskUsed)} of ${this.formatBytes(this.diskTotal)} used`,
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
}, },
{ {
id: 'disk-data', id: 'disk-free',
title: 'Data Drive', title: 'Free Space',
value: 38, value: this.formatBytes(this.diskFree),
type: 'percentage' as const, type: 'text' as const,
icon: 'lucide:hardDrive', icon: 'lucide:hardDrive',
description: '380 GB of 1 TB used', description: 'Available storage',
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
}, },
{ {
id: 'read-speed', id: 'disk-used',
title: 'Read Speed', title: 'Used Space',
value: '245', value: this.formatBytes(this.diskUsed),
unit: 'MB/s', type: 'text' as const,
type: 'trend' as const, icon: 'lucide:database',
icon: 'lucide:download', description: 'Currently in use',
trendData: [180, 220, 195, 280, 245, 210, 265, 230, 245], color: 'hsl(45 93% 47%)',
color: 'hsl(142 71% 45%)',
}, },
{ {
id: 'write-speed', id: 'disk-total-size',
title: 'Write Speed', title: 'Total Capacity',
value: '128', value: this.formatBytes(this.diskTotal),
unit: 'MB/s', type: 'text' as const,
type: 'trend' as const, icon: 'lucide:server',
icon: 'lucide:upload', description: 'All filesystems',
trendData: [95, 110, 85, 145, 120, 105, 138, 115, 128],
color: 'hsl(217 91% 60%)',
},
{
id: 'iops-read',
title: 'Read IOPS',
value: '12.4k',
type: 'number' as const,
icon: 'lucide:gauge',
description: 'Operations/sec',
},
{
id: 'iops-write',
title: 'Write IOPS',
value: '8.2k',
type: 'number' as const,
icon: 'lucide:gauge',
description: 'Operations/sec',
}, },
]; ];
@@ -755,83 +822,38 @@ export class EcoViewSystem extends DeesElement {
const networkTiles = [ const networkTiles = [
{ {
id: 'download', id: 'download',
title: 'Download', title: 'Download Speed',
value: '85.2', value: this.formatSpeed(this.networkRxSec),
unit: 'Mbps',
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:download', icon: 'lucide:download',
trendData: this.networkIn, trendData: this.networkInHistory,
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
}, },
{ {
id: 'upload', id: 'upload',
title: 'Upload', title: 'Upload Speed',
value: '64.8', value: this.formatSpeed(this.networkTxSec),
unit: 'Mbps',
type: 'trend' as const, type: 'trend' as const,
icon: 'lucide:upload', icon: 'lucide:upload',
trendData: this.networkOut, trendData: this.networkOutHistory,
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
}, },
{
id: 'latency',
title: 'Latency',
value: 12,
unit: 'ms',
type: 'gauge' as const,
icon: 'lucide:activity',
gaugeOptions: {
min: 0,
max: 100,
thresholds: [
{ value: 0, color: 'hsl(142 71% 45%)' },
{ value: 30, color: 'hsl(45 93% 47%)' },
{ value: 60, color: 'hsl(0 84% 60%)' },
],
},
},
{
id: 'packets-in',
title: 'Packets In',
value: '1.2M',
type: 'number' as const,
icon: 'lucide:arrowDownCircle',
description: 'Per second',
},
{
id: 'packets-out',
title: 'Packets Out',
value: '892k',
type: 'number' as const,
icon: 'lucide:arrowUpCircle',
description: 'Per second',
},
{
id: 'connections',
title: 'Active Connections',
value: 48,
type: 'number' as const,
icon: 'lucide:link',
description: '12 established, 36 waiting',
},
{ {
id: 'total-down', id: 'total-down',
title: 'Total Downloaded', title: 'Total Downloaded',
value: '24.5', value: this.formatBytes(this.networkRxTotal),
unit: 'GB', type: 'text' as const,
type: 'number' as const, icon: 'lucide:arrowDownCircle',
icon: 'lucide:database', description: 'Since boot',
description: 'This session',
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
}, },
{ {
id: 'total-up', id: 'total-up',
title: 'Total Uploaded', title: 'Total Uploaded',
value: '8.2', value: this.formatBytes(this.networkTxTotal),
unit: 'GB', type: 'text' as const,
type: 'number' as const, icon: 'lucide:arrowUpCircle',
icon: 'lucide:database', description: 'Since boot',
description: 'This session',
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
}, },
]; ];
@@ -857,14 +879,14 @@ export class EcoViewSystem extends DeesElement {
{ {
id: 'total-processes', id: 'total-processes',
title: 'Total Processes', title: 'Total Processes',
value: 247, value: this.processTotal,
type: 'number' as const, type: 'number' as const,
icon: 'lucide:layers', icon: 'lucide:layers',
}, },
{ {
id: 'running', id: 'running',
title: 'Running', title: 'Running',
value: 12, value: this.processRunning,
type: 'number' as const, type: 'number' as const,
icon: 'lucide:play', icon: 'lucide:play',
color: 'hsl(142 71% 45%)', color: 'hsl(142 71% 45%)',
@@ -872,30 +894,21 @@ export class EcoViewSystem extends DeesElement {
{ {
id: 'sleeping', id: 'sleeping',
title: 'Sleeping', title: 'Sleeping',
value: 235, value: this.processSleeping,
type: 'number' as const, type: 'number' as const,
icon: 'lucide:moon', icon: 'lucide:moon',
color: 'hsl(217 91% 60%)', color: 'hsl(217 91% 60%)',
}, },
{ {
id: 'threads', id: 'blocked',
title: 'Threads', title: 'Blocked',
value: 1842, value: this.processBlocked,
type: 'number' as const, type: 'number' as const,
icon: 'lucide:gitBranch', icon: 'lucide:pauseCircle',
color: 'hsl(0 84% 60%)',
}, },
]; ];
const topProcesses = [
{ name: 'node', pid: 1234, cpu: 12.5, memory: 8.2 },
{ name: 'chrome', pid: 2345, cpu: 8.3, memory: 15.4 },
{ name: 'code', pid: 3456, cpu: 5.2, memory: 12.1 },
{ name: 'docker', pid: 4567, cpu: 4.8, memory: 6.8 },
{ name: 'postgres', pid: 5678, cpu: 3.2, memory: 4.5 },
{ name: 'nginx', pid: 6789, cpu: 1.5, memory: 2.1 },
{ name: 'redis', pid: 7890, cpu: 0.8, memory: 1.8 },
];
return html` return html`
<div class="panel-header"> <div class="panel-header">
<div class="panel-title">Processes</div> <div class="panel-title">Processes</div>
@@ -919,14 +932,14 @@ export class EcoViewSystem extends DeesElement {
<span>CPU %</span> <span>CPU %</span>
<span>Memory %</span> <span>Memory %</span>
</div> </div>
${topProcesses.map(proc => html` ${this.topProcesses.length > 0 ? this.topProcesses.map(proc => html`
<div class="process-row"> <div class="process-row">
<span class="process-name">${proc.name}</span> <span class="process-name">${proc.name}</span>
<span class="process-value">${proc.pid}</span> <span class="process-value">${proc.pid}</span>
<span class="process-value ${proc.cpu > 10 ? 'high' : ''}">${proc.cpu}%</span> <span class="process-value ${proc.cpu > 10 ? 'high' : ''}">${proc.cpu}%</span>
<span class="process-value ${proc.memory > 10 ? 'high' : ''}">${proc.memory}%</span> <span class="process-value ${proc.memory > 10 ? 'high' : ''}">${proc.memory}%</span>
</div> </div>
`)} `) : html`<div class="process-row"><span class="process-name">Loading...</span></div>`}
</div> </div>
</div> </div>
`; `;