feat(analysis): Ingress 访问分析卡 — 自动加载、无 ingress 自动折叠
- 新增常驻「Ingress 访问分析」卡:自动探测 ingress-nginx/ingress 命名空间并聚合访问日志 (PV/UV、4xx/5xx、慢请求、接口排行、异常/慢请求 Top10、请求明细),随数据源与时间范围刷新 - 从历史恢复 ingress 洞察表与聚合工具到 analysis 域(ingress-access-log 解析已在 lib) - 折叠交互:未检测到 ingress-nginx 时自动收起并显示徽章;手动切换记入 localStorage 优先生效
This commit is contained in:
1 parent
16306a9532
commit
2da0a2bece
4 files changed
+280
-6
No files matched your search
@@ -21,6 +21,7 @@ import { AppStreamChart } from './components/AppStreamChart'
|
||||
import { DailyVolumeChart } from './components/DailyVolumeChart'
|
||||
import { NamespacePie } from './components/NamespacePie'
|
||||
import { TopAppsTable } from './components/TopAppsTable'
|
||||
import { IngressAnalysisSection } from './components/IngressAnalysisSection'
|
||||
|
||||
const toLocal = (date: Date) => new Date(date.getTime() - date.getTimezoneOffset() * 60000).toISOString().slice(0, 19)
|
||||
|
||||
@@ -120,14 +121,14 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
|
||||
<div className="grid gap-4 lg:grid-cols-3">
|
||||
<Card className="lg:col-span-2">
|
||||
<CardHeader className="pb-2">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">{t('trend.title')}</CardTitle>
|
||||
<p className="text-xs text-muted-foreground">{t('trend.subtitle')}</p>
|
||||
</CardHeader>
|
||||
<CardContent><TrendChart trend={data.trend} /></CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">{t('pie.title')}</CardTitle>
|
||||
<p className="text-xs text-muted-foreground">{t('pie.subtitle')}</p>
|
||||
</CardHeader>
|
||||
@@ -136,7 +137,7 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">{t('stream.title')}</CardTitle>
|
||||
<p className="text-xs text-muted-foreground">{t('stream.subtitle', { count: Math.min(data.apps.length, 10) })}</p>
|
||||
</CardHeader>
|
||||
@@ -144,7 +145,7 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<CardTitle className="text-base">{t('daily.title')}</CardTitle>
|
||||
<span className="rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium text-muted-foreground">{t('daily.fixedBadge')}</span>
|
||||
@@ -153,7 +154,7 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{daily.error ? (
|
||||
<p className="py-6 text-center text-xs text-destructive">{daily.error}</p>
|
||||
<ErrorState message={daily.error} onRetry={daily.refresh} />
|
||||
) : daily.loading && !daily.data ? (
|
||||
<LoadingSpinner className="h-40" />
|
||||
) : (
|
||||
@@ -163,7 +164,7 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader className="pb-2">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-base">{t('table.title')}</CardTitle>
|
||||
<p className="text-xs text-muted-foreground">{t('table.subtitle')}</p>
|
||||
</CardHeader>
|
||||
@@ -177,6 +178,7 @@ const AnalysisPage = memo(function AnalysisPage() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<IngressAnalysisSection sourceId={sourceId} start={start} end={end} />
|
||||
</>
|
||||
)}
|
||||
</PageContainer>
|
||||
|
||||
Reference in new issue
Block a user