2025-11-27 09:26:04 +00:00
|
|
|
import { Component, Input } from '@angular/core';
|
|
|
|
|
import { RouterLink } from '@angular/router';
|
|
|
|
|
import { TPlatformServiceType, TPlatformServiceStatus } from '../../core/types/api.types';
|
|
|
|
|
import {
|
|
|
|
|
CardComponent,
|
|
|
|
|
CardHeaderComponent,
|
|
|
|
|
CardTitleComponent,
|
|
|
|
|
CardDescriptionComponent,
|
|
|
|
|
CardContentComponent,
|
|
|
|
|
} from '../../ui/card/card.component';
|
|
|
|
|
|
|
|
|
|
interface IPlatformServiceSummary {
|
|
|
|
|
type: TPlatformServiceType;
|
|
|
|
|
displayName: string;
|
|
|
|
|
status: TPlatformServiceStatus;
|
|
|
|
|
resourceCount: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
|
selector: 'app-platform-services-card',
|
|
|
|
|
standalone: true,
|
2025-11-27 09:50:06 +00:00
|
|
|
host: { class: 'block h-full' },
|
2025-11-27 09:26:04 +00:00
|
|
|
imports: [
|
|
|
|
|
RouterLink,
|
|
|
|
|
CardComponent,
|
|
|
|
|
CardHeaderComponent,
|
|
|
|
|
CardTitleComponent,
|
|
|
|
|
CardDescriptionComponent,
|
|
|
|
|
CardContentComponent,
|
|
|
|
|
],
|
|
|
|
|
template: `
|
2025-11-27 09:50:06 +00:00
|
|
|
<ui-card class="h-full">
|
2025-11-27 09:26:04 +00:00
|
|
|
<ui-card-header class="flex flex-col space-y-1.5">
|
|
|
|
|
<ui-card-title>Platform Services</ui-card-title>
|
|
|
|
|
<ui-card-description>Infrastructure status</ui-card-description>
|
|
|
|
|
</ui-card-header>
|
|
|
|
|
<ui-card-content class="space-y-2">
|
|
|
|
|
@for (service of services; track service.type) {
|
|
|
|
|
<a [routerLink]="['/platform-services', service.type]"
|
|
|
|
|
class="flex items-center justify-between py-1 hover:bg-muted/50 rounded px-1 -mx-1 transition-colors">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
<!-- Status indicator -->
|
|
|
|
|
<span
|
|
|
|
|
class="h-2 w-2 rounded-full"
|
|
|
|
|
[class.bg-success]="service.status === 'running'"
|
|
|
|
|
[class.bg-muted-foreground]="service.status === 'not-deployed' || service.status === 'stopped'"
|
|
|
|
|
[class.bg-warning]="service.status === 'starting' || service.status === 'stopping'"
|
|
|
|
|
[class.bg-destructive]="service.status === 'failed'">
|
|
|
|
|
</span>
|
|
|
|
|
<span class="text-sm">{{ service.displayName }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2 text-sm text-muted-foreground">
|
|
|
|
|
@if (service.status === 'running') {
|
|
|
|
|
@if (service.resourceCount > 0) {
|
|
|
|
|
<span>{{ service.resourceCount }} {{ service.resourceCount === 1 ? getResourceLabel(service.type) : getResourceLabelPlural(service.type) }}</span>
|
|
|
|
|
} @else {
|
|
|
|
|
<span>Running</span>
|
|
|
|
|
}
|
|
|
|
|
} @else {
|
|
|
|
|
<span class="capitalize">{{ formatStatus(service.status) }}</span>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
</a>
|
|
|
|
|
} @empty {
|
|
|
|
|
<div class="text-sm text-muted-foreground">No platform services</div>
|
|
|
|
|
}
|
|
|
|
|
</ui-card-content>
|
|
|
|
|
</ui-card>
|
|
|
|
|
`,
|
|
|
|
|
})
|
|
|
|
|
export class PlatformServicesCardComponent {
|
|
|
|
|
@Input() services: IPlatformServiceSummary[] = [];
|
|
|
|
|
|
|
|
|
|
formatStatus(status: string): string {
|
|
|
|
|
return status.replace('-', ' ');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getResourceLabel(type: TPlatformServiceType): string {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'mongodb':
|
|
|
|
|
case 'postgresql':
|
|
|
|
|
case 'clickhouse':
|
|
|
|
|
return 'DB';
|
|
|
|
|
case 'minio':
|
|
|
|
|
return 'bucket';
|
|
|
|
|
case 'redis':
|
|
|
|
|
return 'cache';
|
|
|
|
|
case 'rabbitmq':
|
|
|
|
|
return 'queue';
|
|
|
|
|
default:
|
|
|
|
|
return 'resource';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getResourceLabelPlural(type: TPlatformServiceType): string {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'mongodb':
|
|
|
|
|
case 'postgresql':
|
|
|
|
|
case 'clickhouse':
|
|
|
|
|
return 'DBs';
|
|
|
|
|
case 'minio':
|
|
|
|
|
return 'buckets';
|
|
|
|
|
case 'redis':
|
|
|
|
|
return 'caches';
|
|
|
|
|
case 'rabbitmq':
|
|
|
|
|
return 'queues';
|
|
|
|
|
default:
|
|
|
|
|
return 'resources';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|