feat(eco-view-system): add extended system metrics and display formatted total network usage in eco system view
This commit is contained in:
@@ -168,12 +168,18 @@ export class EcoViewSystem extends DeesElement {
|
||||
@property({ type: Number })
|
||||
accessor cpuCores = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
accessor cpuPhysicalCores = 0;
|
||||
|
||||
@property({ type: String })
|
||||
accessor cpuModel = 'Unknown';
|
||||
|
||||
@property({ type: Number })
|
||||
accessor cpuSpeed = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
accessor cpuSpeedMax = 0;
|
||||
|
||||
@property({ type: Number })
|
||||
accessor memoryTotal = 0;
|
||||
|
||||
@@ -183,41 +189,129 @@ export class EcoViewSystem extends DeesElement {
|
||||
@property({ type: Number })
|
||||
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 })
|
||||
accessor hostname = 'Unknown';
|
||||
|
||||
@property({ type: String })
|
||||
accessor platform = 'Unknown';
|
||||
|
||||
@property({ type: String })
|
||||
accessor distro = '';
|
||||
|
||||
@property({ type: Array })
|
||||
accessor loadAvg: number[] = [0, 0, 0];
|
||||
|
||||
@state()
|
||||
accessor networkIn = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||
@property({ type: Array })
|
||||
accessor coreLoads: number[] = [];
|
||||
|
||||
@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];
|
||||
|
||||
// Public method to update metrics from backend
|
||||
public setMetrics(metrics: {
|
||||
cpu: { usage: number; cores: number; model: string; speed: number; loadAvg: number[] };
|
||||
memory: { total: number; used: number; free: number; usagePercent: number };
|
||||
system: { platform: string; hostname: string; uptimeFormatted: string };
|
||||
cpu: { usage: number; cores: number; physicalCores?: number; model: string; speed: number; speedMax?: number; loadAvg: number[]; coreLoads?: number[] };
|
||||
memory: { total: number; used: number; free: number; available?: number; usagePercent: number; swapTotal?: number; swapUsed?: number; cached?: number; buffers?: number };
|
||||
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 {
|
||||
// CPU metrics
|
||||
this.cpuUsage = metrics.cpu.usage;
|
||||
this.cpuCores = metrics.cpu.cores;
|
||||
this.cpuPhysicalCores = metrics.cpu.physicalCores || metrics.cpu.cores;
|
||||
this.cpuModel = metrics.cpu.model;
|
||||
this.cpuSpeed = metrics.cpu.speed;
|
||||
this.cpuSpeedMax = metrics.cpu.speedMax || metrics.cpu.speed;
|
||||
this.loadAvg = metrics.cpu.loadAvg;
|
||||
this.coreLoads = metrics.cpu.coreLoads || [];
|
||||
|
||||
// Memory metrics
|
||||
this.memoryUsage = metrics.memory.usagePercent;
|
||||
this.memoryTotal = metrics.memory.total;
|
||||
this.memoryUsed = metrics.memory.used;
|
||||
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;
|
||||
|
||||
// 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.platform = metrics.system.platform;
|
||||
this.distro = metrics.system.distro || '';
|
||||
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; list: any[] }): void {
|
||||
// Could store and display process data if needed
|
||||
}
|
||||
|
||||
// Helper to format bytes
|
||||
private formatBytes(bytes: number): string {
|
||||
if (bytes === 0) return '0 B';
|
||||
@@ -331,6 +425,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 {
|
||||
const overviewTiles = [
|
||||
{
|
||||
@@ -339,6 +442,7 @@ export class EcoViewSystem extends DeesElement {
|
||||
value: this.cpuUsage,
|
||||
type: 'gauge' as const,
|
||||
icon: 'lucide:cpu',
|
||||
description: this.cpuModel !== 'Unknown' ? `${this.cpuPhysicalCores} cores @ ${this.cpuSpeed} GHz` : undefined,
|
||||
gaugeOptions: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
@@ -372,6 +476,7 @@ export class EcoViewSystem extends DeesElement {
|
||||
value: this.diskUsage,
|
||||
type: 'gauge' as const,
|
||||
icon: 'lucide:hardDrive',
|
||||
description: this.diskTotal ? `${this.formatBytes(this.diskUsed)} of ${this.formatBytes(this.diskTotal)}` : undefined,
|
||||
gaugeOptions: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
@@ -403,22 +508,22 @@ export class EcoViewSystem extends DeesElement {
|
||||
{
|
||||
id: 'network-in',
|
||||
title: 'Network In',
|
||||
value: '85',
|
||||
unit: 'Mbps',
|
||||
value: this.formatSpeed(this.networkRxSec),
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:download',
|
||||
trendData: this.networkIn,
|
||||
trendData: this.networkInHistory,
|
||||
color: 'hsl(142 71% 45%)',
|
||||
description: `Total: ${this.formatBytes(this.networkRxTotal)}`,
|
||||
},
|
||||
{
|
||||
id: 'network-out',
|
||||
title: 'Network Out',
|
||||
value: '65',
|
||||
unit: 'Mbps',
|
||||
value: this.formatSpeed(this.networkTxSec),
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:upload',
|
||||
trendData: this.networkOut,
|
||||
trendData: this.networkOutHistory,
|
||||
color: 'hsl(217 91% 60%)',
|
||||
description: `Total: ${this.formatBytes(this.networkTxTotal)}`,
|
||||
},
|
||||
{
|
||||
id: 'uptime',
|
||||
@@ -435,7 +540,7 @@ export class EcoViewSystem extends DeesElement {
|
||||
value: this.hostname,
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:server',
|
||||
description: `${this.platform} - ${this.cpuCores} cores`,
|
||||
description: this.distro ? `${this.distro} - ${this.cpuCores} threads` : `${this.platform} - ${this.cpuCores} threads`,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -456,6 +561,13 @@ export class EcoViewSystem extends DeesElement {
|
||||
}
|
||||
|
||||
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 = [
|
||||
{
|
||||
id: 'cpu-total',
|
||||
@@ -463,6 +575,7 @@ export class EcoViewSystem extends DeesElement {
|
||||
value: this.cpuUsage,
|
||||
type: 'gauge' as const,
|
||||
icon: 'lucide:cpu',
|
||||
description: `${this.cpuCores} threads on ${this.cpuPhysicalCores} cores`,
|
||||
gaugeOptions: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
@@ -474,73 +587,21 @@ export class EcoViewSystem extends DeesElement {
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'core-0',
|
||||
title: 'Core 0',
|
||||
value: 38,
|
||||
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-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: 'cpu-cores',
|
||||
title: 'Core Usage',
|
||||
value: this.cpuUsage,
|
||||
type: 'cpuCores' as const,
|
||||
coresData: coresData,
|
||||
columnSpan: 2,
|
||||
},
|
||||
{
|
||||
id: 'load-avg',
|
||||
title: 'Load Average',
|
||||
value: '2.45',
|
||||
value: this.loadAvg[0]?.toFixed(2) || '0',
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:activity',
|
||||
trendData: [1.8, 2.1, 2.4, 2.2, 2.5, 2.3, 2.6, 2.4, 2.45],
|
||||
description: '1m: 2.45, 5m: 2.32, 15m: 2.18',
|
||||
trendData: this.loadAvg,
|
||||
description: `1m: ${this.loadAvg[0]?.toFixed(2)}, 5m: ${this.loadAvg[1]?.toFixed(2)}, 15m: ${this.loadAvg[2]?.toFixed(2)}`,
|
||||
},
|
||||
{
|
||||
id: 'cpu-temp',
|
||||
@@ -563,18 +624,18 @@ export class EcoViewSystem extends DeesElement {
|
||||
{
|
||||
id: 'freq',
|
||||
title: 'Clock Speed',
|
||||
value: '3.2',
|
||||
value: this.cpuSpeed.toFixed(1),
|
||||
unit: 'GHz',
|
||||
type: 'number' as const,
|
||||
icon: 'lucide:gauge',
|
||||
description: 'Max: 4.2 GHz',
|
||||
description: this.cpuSpeedMax ? `Max: ${this.cpuSpeedMax.toFixed(1)} GHz` : undefined,
|
||||
},
|
||||
];
|
||||
|
||||
return html`
|
||||
<div class="panel-header">
|
||||
<div class="panel-title">CPU</div>
|
||||
<div class="panel-description">Processor usage and performance</div>
|
||||
<div class="panel-description">${this.cpuModel}</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-section">
|
||||
@@ -588,6 +649,8 @@ export class EcoViewSystem extends DeesElement {
|
||||
}
|
||||
|
||||
private renderMemoryPanel(): TemplateResult {
|
||||
const swapUsagePercent = this.swapTotal > 0 ? Math.round((this.swapUsed / this.swapTotal) * 100) : 0;
|
||||
|
||||
const memoryTiles = [
|
||||
{
|
||||
id: 'ram-usage',
|
||||
@@ -604,12 +667,12 @@ export class EcoViewSystem extends DeesElement {
|
||||
{ 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',
|
||||
title: 'Swap Usage',
|
||||
value: 12,
|
||||
value: swapUsagePercent,
|
||||
type: 'gauge' as const,
|
||||
icon: 'lucide:hardDrive',
|
||||
gaugeOptions: {
|
||||
@@ -621,41 +684,38 @@ export class EcoViewSystem extends DeesElement {
|
||||
{ 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',
|
||||
title: 'Memory History',
|
||||
value: '67%',
|
||||
value: `${this.memoryUsage}%`,
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:trendingUp',
|
||||
trendData: [58, 62, 65, 63, 68, 72, 70, 65, 67],
|
||||
description: 'Last hour',
|
||||
trendData: [58, 62, 65, 63, 68, 72, 70, 65, this.memoryUsage],
|
||||
description: 'Recent usage',
|
||||
},
|
||||
{
|
||||
id: 'cached',
|
||||
title: 'Cached',
|
||||
value: '3.2',
|
||||
unit: 'GB',
|
||||
type: 'number' as const,
|
||||
value: this.formatBytes(this.memoryCached),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:database',
|
||||
color: 'hsl(217 91% 60%)',
|
||||
},
|
||||
{
|
||||
id: 'buffers',
|
||||
title: 'Buffers',
|
||||
value: '512',
|
||||
unit: 'MB',
|
||||
type: 'number' as const,
|
||||
value: this.formatBytes(this.memoryBuffers),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:layers',
|
||||
color: 'hsl(262 83% 58%)',
|
||||
},
|
||||
{
|
||||
id: 'available',
|
||||
title: 'Available',
|
||||
value: '5.3',
|
||||
unit: 'GB',
|
||||
type: 'number' as const,
|
||||
value: this.formatBytes(this.memoryAvailable),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:checkCircle',
|
||||
color: 'hsl(142 71% 45%)',
|
||||
},
|
||||
@@ -680,58 +740,39 @@ export class EcoViewSystem extends DeesElement {
|
||||
private renderStoragePanel(): TemplateResult {
|
||||
const storageTiles = [
|
||||
{
|
||||
id: 'disk-main',
|
||||
title: 'System Drive',
|
||||
id: 'disk-total',
|
||||
title: 'Total Storage',
|
||||
value: this.diskUsage,
|
||||
type: 'percentage' as const,
|
||||
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%)',
|
||||
},
|
||||
{
|
||||
id: 'disk-data',
|
||||
title: 'Data Drive',
|
||||
value: 38,
|
||||
type: 'percentage' as const,
|
||||
id: 'disk-free',
|
||||
title: 'Free Space',
|
||||
value: this.formatBytes(this.diskFree),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:hardDrive',
|
||||
description: '380 GB of 1 TB used',
|
||||
description: 'Available storage',
|
||||
color: 'hsl(142 71% 45%)',
|
||||
},
|
||||
{
|
||||
id: 'read-speed',
|
||||
title: 'Read Speed',
|
||||
value: '245',
|
||||
unit: 'MB/s',
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:download',
|
||||
trendData: [180, 220, 195, 280, 245, 210, 265, 230, 245],
|
||||
color: 'hsl(142 71% 45%)',
|
||||
id: 'disk-used',
|
||||
title: 'Used Space',
|
||||
value: this.formatBytes(this.diskUsed),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:database',
|
||||
description: 'Currently in use',
|
||||
color: 'hsl(45 93% 47%)',
|
||||
},
|
||||
{
|
||||
id: 'write-speed',
|
||||
title: 'Write Speed',
|
||||
value: '128',
|
||||
unit: 'MB/s',
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:upload',
|
||||
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',
|
||||
id: 'disk-total-size',
|
||||
title: 'Total Capacity',
|
||||
value: this.formatBytes(this.diskTotal),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:server',
|
||||
description: 'All filesystems',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -755,83 +796,38 @@ export class EcoViewSystem extends DeesElement {
|
||||
const networkTiles = [
|
||||
{
|
||||
id: 'download',
|
||||
title: 'Download',
|
||||
value: '85.2',
|
||||
unit: 'Mbps',
|
||||
title: 'Download Speed',
|
||||
value: this.formatSpeed(this.networkRxSec),
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:download',
|
||||
trendData: this.networkIn,
|
||||
trendData: this.networkInHistory,
|
||||
color: 'hsl(142 71% 45%)',
|
||||
},
|
||||
{
|
||||
id: 'upload',
|
||||
title: 'Upload',
|
||||
value: '64.8',
|
||||
unit: 'Mbps',
|
||||
title: 'Upload Speed',
|
||||
value: this.formatSpeed(this.networkTxSec),
|
||||
type: 'trend' as const,
|
||||
icon: 'lucide:upload',
|
||||
trendData: this.networkOut,
|
||||
trendData: this.networkOutHistory,
|
||||
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',
|
||||
title: 'Total Downloaded',
|
||||
value: '24.5',
|
||||
unit: 'GB',
|
||||
type: 'number' as const,
|
||||
icon: 'lucide:database',
|
||||
description: 'This session',
|
||||
value: this.formatBytes(this.networkRxTotal),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:arrowDownCircle',
|
||||
description: 'Since boot',
|
||||
color: 'hsl(142 71% 45%)',
|
||||
},
|
||||
{
|
||||
id: 'total-up',
|
||||
title: 'Total Uploaded',
|
||||
value: '8.2',
|
||||
unit: 'GB',
|
||||
type: 'number' as const,
|
||||
icon: 'lucide:database',
|
||||
description: 'This session',
|
||||
value: this.formatBytes(this.networkTxTotal),
|
||||
type: 'text' as const,
|
||||
icon: 'lucide:arrowUpCircle',
|
||||
description: 'Since boot',
|
||||
color: 'hsl(217 91% 60%)',
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user