feat: Enhance container stats monitoring and UI integration with new ContainerStatsComponent

This commit is contained in:
2025-11-26 16:36:01 +00:00
parent a14af4af9c
commit 9de32cd00d
5 changed files with 228 additions and 151 deletions

View File

@@ -4,6 +4,7 @@ import { ApiService } from '../../core/services/api.service';
import { ToastService } from '../../core/services/toast.service';
import { WebSocketService } from '../../core/services/websocket.service';
import { IPlatformService, IContainerStats, TPlatformServiceType } from '../../core/types/api.types';
import { ContainerStatsComponent } from '../../shared/components/container-stats/container-stats.component';
import {
CardComponent,
CardHeaderComponent,
@@ -28,6 +29,7 @@ import { SkeletonComponent } from '../../ui/skeleton/skeleton.component';
ButtonComponent,
BadgeComponent,
SkeletonComponent,
ContainerStatsComponent,
],
template: `
<div class="space-y-6">
@@ -141,62 +143,8 @@ import { SkeletonComponent } from '../../ui/skeleton/skeleton.component';
</ui-card>
<!-- Resource Stats (only shown when service is running) -->
@if (service()!.status === 'running' && stats()) {
<ui-card>
<ui-card-header class="flex flex-col space-y-1.5">
<ui-card-title>Resource Usage</ui-card-title>
<ui-card-description>
<span class="flex items-center gap-2">
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
</span>
Live stats
</span>
</ui-card-description>
</ui-card-header>
<ui-card-content>
<div class="grid grid-cols-2 gap-4">
<!-- CPU -->
<div class="space-y-2">
<div class="flex items-center justify-between text-sm">
<span class="text-muted-foreground">CPU</span>
<span class="font-medium">{{ formatPercent(stats()!.cpuPercent) }}</span>
</div>
<div class="h-2 bg-muted rounded-full overflow-hidden">
<div class="h-full bg-primary transition-all duration-300" [style.width.%]="stats()!.cpuPercent"></div>
</div>
</div>
<!-- Memory -->
<div class="space-y-2">
<div class="flex items-center justify-between text-sm">
<span class="text-muted-foreground">Memory</span>
<span class="font-medium">{{ formatBytes(stats()!.memoryUsed) }} / {{ formatBytes(stats()!.memoryLimit) }}</span>
</div>
<div class="h-2 bg-muted rounded-full overflow-hidden">
<div class="h-full bg-primary transition-all duration-300" [style.width.%]="stats()!.memoryPercent"></div>
</div>
</div>
<!-- Network RX -->
<div class="space-y-1">
<div class="flex items-center justify-between text-sm">
<span class="text-muted-foreground">Network In</span>
<span class="font-medium">{{ formatBytes(stats()!.networkRx) }}</span>
</div>
</div>
<!-- Network TX -->
<div class="space-y-1">
<div class="flex items-center justify-between text-sm">
<span class="text-muted-foreground">Network Out</span>
<span class="font-medium">{{ formatBytes(stats()!.networkTx) }}</span>
</div>
</div>
</div>
</ui-card-content>
</ui-card>
@if (service()!.status === 'running') {
<app-container-stats [stats]="stats()" [showLiveIndicator]="true" />
}
<!-- Service Description -->
@@ -309,18 +257,6 @@ export class PlatformServiceDetailComponent implements OnInit {
return new Date(timestamp).toLocaleString();
}
formatBytes(bytes: number): string {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
formatPercent(value: number): string {
return value.toFixed(1) + '%';
}
getServiceDescription(type: TPlatformServiceType): string {
const descriptions: Record<TPlatformServiceType, string> = {
mongodb: 'MongoDB is a document-oriented NoSQL database used for high volume data storage. It stores data in flexible, JSON-like documents.',