feat: 全站 PageShell 设计系统与专业 UI 统一
- 新增 PageShell/PageTabs/ContentPanel/PageLoading/PageEmpty 页面骨架 - index.css 设计令牌文档化,布局令牌与纯色主按钮(去除渐变粉彩) - 全站路由页接入 PageShell,云账单三 Tab 为标杆 - 主题体系:跟随系统 + 主流/开发者分组,新增 Dracula/Tokyo Night,One Dark 暖灰差异化 - 登录页/侧栏/顶栏去渐变光球,企业克制风 - 修复 AIAlertAnalyzer JSX 与构建依赖导入问题
This commit is contained in:
1 parent
1acb0c49af
commit
e363ded445
213 files changed
+7148
-6818
No files matched your search
@@ -1,8 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { Plus, Settings, Bell, AlertTriangle, Clock, CheckCircle } from 'lucide-react';
|
||||
import { Plus, Settings, Bell } from 'lucide-react';
|
||||
import {
|
||||
ResponsiveContainer,
|
||||
AreaChart,
|
||||
@@ -17,6 +16,8 @@ import { AlertEventsTab } from './AlertEventsTab';
|
||||
import { AlertRulesTab } from './AlertRulesTab';
|
||||
import { AlertRuleDialog } from './AlertRuleDialog';
|
||||
import { AlertChannelDialog } from './AlertChannelDialog';
|
||||
import { PageShell } from '@/components/layout/PageShell';
|
||||
import { StatStrip } from '@/components/ui/stat-strip';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import type { AlertEventRecord, AlertRuleRecord, AlertChannel } from '@/types';
|
||||
|
||||
@@ -73,95 +74,51 @@ export function AlertManager() {
|
||||
{ time: '24:00', critical: 2, warning: 4, info: 7 },
|
||||
];
|
||||
|
||||
const pageTabs = [
|
||||
{ id: 'events', label: '告警事件' },
|
||||
{ id: 'rules', label: '告警规则' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
{/* Page Header */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-slate-100">监控告警</h1>
|
||||
<p className="text-sm text-slate-500 mt-1">告警规则管理与告警事件处理</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<PageShell
|
||||
variant="list"
|
||||
title="监控告警"
|
||||
subtitle="告警规则管理与告警事件处理"
|
||||
icon={<Bell className="h-5 w-5" />}
|
||||
tabs={pageTabs}
|
||||
activeTab={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
metrics={(
|
||||
<StatStrip
|
||||
items={[
|
||||
{ label: '告警规则', value: rules.length, color: 'blue' },
|
||||
{ label: '触发中', value: alerts.filter((e) => e.status === 'firing').length, color: 'red' },
|
||||
{ label: '今日告警', value: alerts.length, color: 'amber' },
|
||||
{ label: '已恢复', value: alerts.filter((e) => e.status === 'resolved').length, color: 'emerald' },
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
actions={(
|
||||
<>
|
||||
<Button
|
||||
variant="outline"
|
||||
className="border-slate-700 text-slate-300 hover:text-slate-100 hover:bg-slate-800"
|
||||
className="dg-btn-secondary"
|
||||
onClick={() => setChannelDialogOpen(true)}
|
||||
>
|
||||
<Settings className="h-4 w-4 mr-2" />
|
||||
通知配置
|
||||
</Button>
|
||||
<Button className="bg-blue-600 hover:bg-blue-700 text-white" onClick={openCreateRule}>
|
||||
<Button className="dg-btn-primary" onClick={openCreateRule}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
新建规则
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-slate-500">告警规则</p>
|
||||
<p className="text-2xl font-bold text-slate-100">{rules.length}</p>
|
||||
</div>
|
||||
<div className="p-3 rounded-lg bg-blue-500/10 text-blue-400">
|
||||
<Bell className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-slate-500">触发中</p>
|
||||
<p className="text-2xl font-bold text-red-400">
|
||||
{alerts.filter((e) => e.status === 'firing').length}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 rounded-lg bg-red-500/10 text-red-400">
|
||||
<AlertTriangle className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-slate-500">今日告警</p>
|
||||
<p className="text-2xl font-bold text-amber-400">{alerts.length}</p>
|
||||
</div>
|
||||
<div className="p-3 rounded-lg bg-amber-500/10 text-amber-400">
|
||||
<Clock className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
<CardContent className="p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<p className="text-sm text-slate-500">已恢复</p>
|
||||
<p className="text-2xl font-bold text-emerald-400">
|
||||
{alerts.filter((e) => e.status === 'resolved').length}
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 rounded-lg bg-emerald-500/10 text-emerald-400">
|
||||
<CheckCircle className="h-5 w-5" />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Alert Trend Chart */}
|
||||
<Card className="bg-slate-900 border-slate-800">
|
||||
</>
|
||||
)}
|
||||
>
|
||||
<Card className="dg-card">
|
||||
<CardHeader className="pb-2">
|
||||
<CardTitle className="text-slate-100">告警趋势</CardTitle>
|
||||
<CardDescription className="text-slate-500">过去24小时告警统计</CardDescription>
|
||||
<CardTitle className="text-[var(--dg-text-primary)]">告警趋势</CardTitle>
|
||||
<CardDescription className="dg-text-muted">过去24小时告警统计</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="h-[200px]">
|
||||
@@ -210,34 +167,18 @@ export function AlertManager() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Tabs */}
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
|
||||
<TabsList className="bg-slate-800 border border-slate-700">
|
||||
<TabsTrigger value="events" className="data-[state=active]:bg-slate-700">
|
||||
告警事件
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="rules" className="data-[state=active]:bg-slate-700">
|
||||
告警规则
|
||||
</TabsTrigger>
|
||||
{activeTab === 'events' && (
|
||||
<AlertEventsTab alerts={alerts} loading={loading} onReload={loadData} />
|
||||
)}
|
||||
{activeTab === 'rules' && (
|
||||
<AlertRulesTab
|
||||
rules={rules}
|
||||
notifyChannels={notifyChannels}
|
||||
onReload={loadData}
|
||||
onEditRule={openEditRule}
|
||||
/>
|
||||
)}
|
||||
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="events">
|
||||
<AlertEventsTab alerts={alerts} loading={loading} onReload={loadData} />
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="rules">
|
||||
<AlertRulesTab
|
||||
rules={rules}
|
||||
notifyChannels={notifyChannels}
|
||||
onReload={loadData}
|
||||
onEditRule={openEditRule}
|
||||
/>
|
||||
</TabsContent>
|
||||
|
||||
</Tabs>
|
||||
|
||||
{/* Dialogs */}
|
||||
<AlertRuleDialog
|
||||
open={ruleDialogOpen}
|
||||
onOpenChange={setRuleDialogOpen}
|
||||
@@ -251,6 +192,6 @@ export function AlertManager() {
|
||||
notifyChannels={notifyChannels}
|
||||
onChannelsChanged={loadData}
|
||||
/>
|
||||
</div>
|
||||
</PageShell>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user