add runtime log views and standardize status dots
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -5,6 +5,7 @@ import { useToast } from '../../components/toast';
|
||||
import { PageTitle } from '../../layout/AppLayout';
|
||||
import { formatDateTime } from '../../lib/date-format';
|
||||
import { getStoredSelectedAppId, getStoredSelectedComponentId, selectedComponentChangedEventName, setStoredSelectedAppId, setStoredSelectedComponentId } from '../../lib/selected-app';
|
||||
import { statusDotToneClass } from '../../lib/status-dot';
|
||||
import type { ApiApp, ApiAppComponent, RuntimeEnvProfile, RuntimeEnvVariable, RuntimeIngressRule, RuntimeResource } from '../../types/runtime';
|
||||
import { LoadingModal, useMinimumLoading } from '../operations/operation-utils';
|
||||
import {
|
||||
@@ -40,13 +41,6 @@ function getWorkloadKind(kind: string) {
|
||||
return '';
|
||||
}
|
||||
|
||||
function statusDot(status?: string) {
|
||||
if (['Running', 'Bound', 'ClusterIP', 'LoadBalancer'].includes(status ?? '')) return 'bg-emerald-400';
|
||||
if (['Pending', 'ContainerCreating'].includes(status ?? '')) return 'bg-amber-400';
|
||||
if (['Error', 'CrashLoopBackOff', 'ImagePullBackOff', 'Failed'].includes(status ?? '')) return 'bg-rose-400';
|
||||
return 'bg-muted-foreground';
|
||||
}
|
||||
|
||||
function isStopped(resource: RuntimeResource) {
|
||||
return resource.ready.endsWith('/0');
|
||||
}
|
||||
@@ -520,7 +514,7 @@ export function RuntimeConfigPage() {
|
||||
<tr key={variable.id} className="hover:bg-muted/20">
|
||||
<td className="px-4 py-3">
|
||||
<span className="inline-flex items-center gap-2">
|
||||
<span className={variable.isSecret ? 'block size-2.5 rounded-full bg-amber-400' : 'block size-2.5 rounded-full bg-emerald-400'} />
|
||||
<span className={`block size-2.5 shrink-0 rounded-full ${variable.isSecret ? statusDotToneClass('amber') : statusDotToneClass('green')}`} />
|
||||
<span className="truncate">{variable.component?.name ?? '-'}</span>
|
||||
</span>
|
||||
</td>
|
||||
@@ -626,7 +620,7 @@ export function RuntimeConfigPage() {
|
||||
<tr key={rule.id} className="hover:bg-muted/20">
|
||||
<td className="px-4 py-3">
|
||||
<span className="inline-flex items-center gap-2">
|
||||
<span className="block size-2.5 rounded-full bg-sky-400" />
|
||||
<span className={`block size-2.5 shrink-0 rounded-full ${statusDotToneClass('blue')}`} />
|
||||
<span className="truncate">{rule.component?.name ?? '-'}</span>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -4,18 +4,12 @@ import { Badge, Button, Card } from '../../components/ui';
|
||||
import { PageTitle } from '../../layout/AppLayout';
|
||||
import { formatDateTime } from '../../lib/date-format';
|
||||
import { getStoredSelectedAppId, setStoredSelectedAppId } from '../../lib/selected-app';
|
||||
import { runtimeStatusDotClass, statusDotToneClass } from '../../lib/status-dot';
|
||||
import { cn } from '../../lib/utils';
|
||||
import type { ApiApp, RuntimeEvent, RuntimePodMetric, RuntimeResource, RuntimeResourceResponse } from '../../types/runtime';
|
||||
import { LoadingModal, useMinimumLoading } from '../operations/operation-utils';
|
||||
import { loadApps, loadRuntimeEvents, loadRuntimePodMetrics, loadRuntimeResources, loadRuntimeWorkloadLogs } from './runtime-api';
|
||||
|
||||
function statusDot(status?: string) {
|
||||
if (['Running', 'Bound', 'ClusterIP', 'LoadBalancer', 'Normal'].includes(status ?? '')) return 'bg-emerald-400';
|
||||
if (['Pending', 'ContainerCreating', 'Warning'].includes(status ?? '')) return 'bg-amber-400';
|
||||
if (['Error', 'CrashLoopBackOff', 'ImagePullBackOff', 'Failed'].includes(status ?? '')) return 'bg-rose-400';
|
||||
return 'bg-muted-foreground';
|
||||
}
|
||||
|
||||
function eventTone(type?: string) {
|
||||
if (type === 'Normal') return 'green';
|
||||
if (type === 'Warning') return 'amber';
|
||||
@@ -59,12 +53,12 @@ function isActiveLogTarget(resource: RuntimeResource) {
|
||||
}
|
||||
|
||||
function workloadStatusDot(resource: RuntimeResource) {
|
||||
if (resource.kind === 'Pod') return statusDot(resource.status);
|
||||
if (resource.kind === 'Job') return resource.status === 'Running' ? 'bg-emerald-400' : 'bg-muted-foreground';
|
||||
if (hasReadyReplica(resource) && resource.status === 'Running') return 'bg-emerald-400';
|
||||
if (resource.status === 'Pending') return 'bg-amber-400';
|
||||
if (['Error', 'CrashLoopBackOff', 'ImagePullBackOff', 'Failed'].includes(resource.status)) return 'bg-rose-400';
|
||||
return 'bg-muted-foreground';
|
||||
if (resource.kind === 'Pod') return runtimeStatusDotClass(resource.status);
|
||||
if (resource.kind === 'Job') return resource.status === 'Running' ? statusDotToneClass('green') : statusDotToneClass('neutral');
|
||||
if (hasReadyReplica(resource) && resource.status === 'Running') return statusDotToneClass('green');
|
||||
if (resource.status === 'Pending') return statusDotToneClass('amber');
|
||||
if (['Error', 'CrashLoopBackOff', 'ImagePullBackOff', 'Failed'].includes(resource.status)) return statusDotToneClass('red');
|
||||
return statusDotToneClass('neutral');
|
||||
}
|
||||
|
||||
function metricKey(namespace: string, pod: string) {
|
||||
@@ -311,7 +305,7 @@ export function RuntimeLogsPage() {
|
||||
onClick={() => loadLogs(resource)}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className={cn('size-2 rounded-full', workloadStatusDot(resource))} />
|
||||
<span className={cn('size-2.5 shrink-0 rounded-full', workloadStatusDot(resource))} />
|
||||
<span className="truncate text-sm font-medium">{resource.name}</span>
|
||||
</div>
|
||||
<div className="mt-2 flex flex-wrap gap-x-3 gap-y-1 text-xs text-muted-foreground">
|
||||
|
||||
Reference in New Issue
Block a user