first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,482 @@
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import type {
CostHistogramResponse,
LatencyHistogramResponse,
LogsHistogramResponse,
ModelHistogramResponse,
TokenHistogramResponse,
} from "@/lib/types/logs";
import {
CHART_COLORS,
CHART_HEADER_ACTIONS_CLASS,
CHART_HEADER_CONTROLS_CLASS,
CHART_HEADER_LEGEND_CLASS,
LATENCY_COLORS,
getModelColor,
} from "../utils/chartUtils";
import CacheTokenMeterChart from "./charts/cacheTokenMeterChart";
import { ChartCard } from "./charts/chartCard";
import { type ChartType, ChartTypeToggle } from "./charts/chartTypeToggle";
import { CostChart } from "./charts/costChart";
import { LatencyChart } from "./charts/latencyChart";
import { LogVolumeChart } from "./charts/logVolumeChart";
import { ModelFilterSelect } from "./charts/modelFilterSelect";
import { ModelUsageChart } from "./charts/modelUsageChart";
import { TokenUsageChart } from "./charts/tokenUsageChart";
export interface OverviewTabProps {
// Data
histogramData: LogsHistogramResponse | null;
tokenData: TokenHistogramResponse | null;
costData: CostHistogramResponse | null;
modelData: ModelHistogramResponse | null;
latencyData: LatencyHistogramResponse | null;
// Loading states
loadingHistogram: boolean;
loadingTokens: boolean;
loadingCost: boolean;
loadingModels: boolean;
loadingLatency: boolean;
// Time range
startTime: number;
endTime: number;
// Chart types
volumeChartType: ChartType;
tokenChartType: ChartType;
costChartType: ChartType;
modelChartType: ChartType;
latencyChartType: ChartType;
// Model selections
costModel: string;
usageModel: string;
// Derived model lists
costModels: string[];
usageModels: string[];
availableModels: string[];
// Chart type toggle callbacks
onVolumeChartToggle: (type: ChartType) => void;
onTokenChartToggle: (type: ChartType) => void;
onCostChartToggle: (type: ChartType) => void;
onModelChartToggle: (type: ChartType) => void;
onLatencyChartToggle: (type: ChartType) => void;
// Filter callbacks
onCostModelChange: (model: string) => void;
onUsageModelChange: (model: string) => void;
}
export function OverviewTab({
histogramData,
tokenData,
costData,
modelData,
latencyData,
loadingHistogram,
loadingTokens,
loadingCost,
loadingModels,
loadingLatency,
startTime,
endTime,
volumeChartType,
tokenChartType,
costChartType,
modelChartType,
latencyChartType,
costModel,
usageModel,
costModels,
usageModels,
availableModels,
onVolumeChartToggle,
onTokenChartToggle,
onCostChartToggle,
onModelChartToggle,
onLatencyChartToggle,
onCostModelChange,
onUsageModelChange,
}: OverviewTabProps) {
return (
<>
{/* Charts Grid */}
<div className="grid grid-cols-1 gap-2 lg:grid-cols-2 2xl:grid-cols-3">
{/* Log Volume Chart */}
<ChartCard
title="Request Volume"
loading={loadingHistogram}
testId="chart-log-volume"
headerActions={
<div className={CHART_HEADER_ACTIONS_CLASS}>
<div className={CHART_HEADER_LEGEND_CLASS}>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: CHART_COLORS.success }}
/>
<span className="text-muted-foreground">Success</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: CHART_COLORS.error }}
/>
<span className="text-muted-foreground">Error</span>
</span>
</div>
<div className={CHART_HEADER_CONTROLS_CLASS}>
<ChartTypeToggle
chartType={volumeChartType}
onToggle={onVolumeChartToggle}
data-testid="dashboard-volume-chart-toggle"
/>
</div>
</div>
}
>
<LogVolumeChart
data={histogramData}
chartType={volumeChartType}
startTime={startTime}
endTime={endTime}
/>
</ChartCard>
{/* Token Usage Chart */}
<ChartCard
title="Token Usage"
loading={loadingTokens}
testId="chart-token-usage"
headerActions={
<div className={CHART_HEADER_ACTIONS_CLASS}>
<div className={CHART_HEADER_LEGEND_CLASS}>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: CHART_COLORS.promptTokens }}
/>
<span className="text-muted-foreground">Input</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: CHART_COLORS.completionTokens }}
/>
<span className="text-muted-foreground">Output</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: CHART_COLORS.cachedReadTokens }}
/>
<span className="text-muted-foreground">Cached</span>
</span>
</div>
<div className={CHART_HEADER_CONTROLS_CLASS}>
<ChartTypeToggle
chartType={tokenChartType}
onToggle={onTokenChartToggle}
data-testid="dashboard-token-chart-toggle"
/>
</div>
</div>
}
>
<TokenUsageChart
data={tokenData}
chartType={tokenChartType}
startTime={startTime}
endTime={endTime}
/>
</ChartCard>
{/* Cache Hit Rate Meter */}
<ChartCard
title="Cache Hit Rate"
loading={loadingTokens}
testId="chart-cache-meter"
>
<CacheTokenMeterChart data={tokenData} />
</ChartCard>
{/* Cost Chart */}
<ChartCard
title="Cost"
loading={loadingCost}
testId="chart-cost-total"
headerActions={
<div className={CHART_HEADER_ACTIONS_CLASS}>
<div className={CHART_HEADER_LEGEND_CLASS}>
{costModel === "all" ? (
costModels.length > 0 && (
<>
<Tooltip>
<TooltipTrigger asChild>
<span
tabIndex={0}
data-testid="cost-legend-trigger"
className="flex items-center gap-1"
>
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{ backgroundColor: getModelColor(0) }}
/>
<span className="text-muted-foreground max-w-[100px] truncate">
{costModels[0]}
</span>
</span>
</TooltipTrigger>
<TooltipContent>{costModels[0]}</TooltipContent>
</Tooltip>
{costModels.length > 1 && (
<Tooltip>
<TooltipTrigger asChild>
<span
tabIndex={0}
data-testid="cost-legend-more-trigger"
className="text-muted-foreground cursor-default"
>
+{costModels.length - 1} more
</span>
</TooltipTrigger>
<TooltipContent>
<div className="flex flex-col gap-1">
{costModels.slice(1).map((model, idx) => (
<span
key={model}
className="flex items-center gap-1"
>
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{
backgroundColor: getModelColor(idx + 1),
}}
/>
{model}
</span>
))}
</div>
</TooltipContent>
</Tooltip>
)}
</>
)
) : (
<Tooltip>
<TooltipTrigger asChild>
<span
tabIndex={0}
data-testid="cost-legend-single-trigger"
className="flex items-center gap-1"
>
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{ backgroundColor: getModelColor(0) }}
/>
<span className="text-muted-foreground max-w-[100px] truncate">
{costModel}
</span>
</span>
</TooltipTrigger>
<TooltipContent>{costModel}</TooltipContent>
</Tooltip>
)}
</div>
<div className={CHART_HEADER_CONTROLS_CLASS}>
<ModelFilterSelect
models={availableModels}
selectedModel={costModel}
onModelChange={onCostModelChange}
data-testid="dashboard-cost-model-filter"
/>
<ChartTypeToggle
chartType={costChartType}
onToggle={onCostChartToggle}
data-testid="dashboard-cost-chart-toggle"
/>
</div>
</div>
}
>
<CostChart
data={costData}
chartType={costChartType}
startTime={startTime}
endTime={endTime}
selectedModel={costModel}
/>
</ChartCard>
{/* Model Usage Chart */}
<ChartCard
title="Model Usage"
loading={loadingModels}
testId="chart-model-usage"
headerActions={
<div className={CHART_HEADER_ACTIONS_CLASS}>
<div className={CHART_HEADER_LEGEND_CLASS}>
{usageModel === "all" ? (
usageModels.length > 0 && (
<>
<Tooltip>
<TooltipTrigger asChild>
<span
tabIndex={0}
data-testid="usage-legend-trigger"
className="flex items-center gap-1"
>
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{ backgroundColor: getModelColor(0) }}
/>
<span className="text-muted-foreground max-w-[100px] truncate">
{usageModels[0]}
</span>
</span>
</TooltipTrigger>
<TooltipContent>{usageModels[0]}</TooltipContent>
</Tooltip>
{usageModels.length > 1 && (
<Tooltip>
<TooltipTrigger asChild>
<span
tabIndex={0}
data-testid="usage-legend-more-trigger"
className="text-muted-foreground cursor-default"
>
+{usageModels.length - 1} more
</span>
</TooltipTrigger>
<TooltipContent>
<div className="flex flex-col gap-1">
{usageModels.slice(1).map((model, idx) => (
<span
key={model}
className="flex items-center gap-1"
>
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{
backgroundColor: getModelColor(idx + 1),
}}
/>
{model}
</span>
))}
</div>
</TooltipContent>
</Tooltip>
)}
</>
)
) : (
<>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{ backgroundColor: CHART_COLORS.success }}
/>
<span className="text-muted-foreground">Success</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 shrink-0 rounded-full"
style={{ backgroundColor: CHART_COLORS.error }}
/>
<span className="text-muted-foreground">Error</span>
</span>
</>
)}
</div>
<div className={CHART_HEADER_CONTROLS_CLASS}>
<ModelFilterSelect
models={availableModels}
selectedModel={usageModel}
onModelChange={onUsageModelChange}
data-testid="dashboard-usage-model-filter"
/>
<ChartTypeToggle
chartType={modelChartType}
onToggle={onModelChartToggle}
data-testid="dashboard-usage-chart-toggle"
/>
</div>
</div>
}
>
<ModelUsageChart
data={modelData}
chartType={modelChartType}
startTime={startTime}
endTime={endTime}
selectedModel={usageModel}
/>
</ChartCard>
{/* Latency Chart */}
<ChartCard
title="Latency"
loading={loadingLatency}
testId="chart-latency"
headerActions={
<div className={CHART_HEADER_ACTIONS_CLASS}>
<div className={CHART_HEADER_LEGEND_CLASS}>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: LATENCY_COLORS.avg }}
/>
<span className="text-muted-foreground">Avg</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: LATENCY_COLORS.p90 }}
/>
<span className="text-muted-foreground">P90</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: LATENCY_COLORS.p95 }}
/>
<span className="text-muted-foreground">P95</span>
</span>
<span className="flex items-center gap-1">
<span
className="h-2 w-2 rounded-full"
style={{ backgroundColor: LATENCY_COLORS.p99 }}
/>
<span className="text-muted-foreground">P99</span>
</span>
</div>
<div className={CHART_HEADER_CONTROLS_CLASS}>
<ChartTypeToggle
chartType={latencyChartType}
onToggle={onLatencyChartToggle}
data-testid="dashboard-latency-chart-toggle"
/>
</div>
</div>
}
>
<LatencyChart
data={latencyData}
chartType={latencyChartType}
startTime={startTime}
endTime={endTime}
/>
</ChartCard>
</div>
</>
);
}