@zhin.js/console 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +4 -4
- package/client/components.json +17 -0
- package/client/index.html +1 -1
- package/client/src/components/PluginConfigForm/BasicFieldRenderers.tsx +89 -180
- package/client/src/components/PluginConfigForm/CollectionFieldRenderers.tsx +97 -200
- package/client/src/components/PluginConfigForm/CompositeFieldRenderers.tsx +31 -70
- package/client/src/components/PluginConfigForm/FieldRenderer.tsx +27 -77
- package/client/src/components/PluginConfigForm/NestedFieldRenderer.tsx +33 -53
- package/client/src/components/PluginConfigForm/index.tsx +71 -173
- package/client/src/components/ui/accordion.tsx +54 -0
- package/client/src/components/ui/alert.tsx +62 -0
- package/client/src/components/ui/avatar.tsx +41 -0
- package/client/src/components/ui/badge.tsx +32 -0
- package/client/src/components/ui/button.tsx +50 -0
- package/client/src/components/ui/card.tsx +50 -0
- package/client/src/components/ui/checkbox.tsx +25 -0
- package/client/src/components/ui/dialog.tsx +87 -0
- package/client/src/components/ui/dropdown-menu.tsx +97 -0
- package/client/src/components/ui/input.tsx +21 -0
- package/client/src/components/ui/scroll-area.tsx +43 -0
- package/client/src/components/ui/select.tsx +127 -0
- package/client/src/components/ui/separator.tsx +23 -0
- package/client/src/components/ui/skeleton.tsx +12 -0
- package/client/src/components/ui/switch.tsx +26 -0
- package/client/src/components/ui/tabs.tsx +52 -0
- package/client/src/components/ui/textarea.tsx +20 -0
- package/client/src/components/ui/tooltip.tsx +27 -0
- package/client/src/layouts/dashboard.tsx +91 -221
- package/client/src/main.tsx +38 -42
- package/client/src/pages/dashboard-bots.tsx +91 -137
- package/client/src/pages/dashboard-home.tsx +133 -204
- package/client/src/pages/dashboard-logs.tsx +125 -196
- package/client/src/pages/dashboard-plugin-detail.tsx +261 -329
- package/client/src/pages/dashboard-plugins.tsx +108 -105
- package/client/src/style.css +156 -865
- package/client/src/theme/index.ts +60 -35
- package/client/tailwind.config.js +78 -69
- package/dist/client.js +1 -1
- package/dist/cva.js +47 -0
- package/dist/index.html +1 -1
- package/dist/index.js +6 -6
- package/dist/react-router.js +7121 -5585
- package/dist/react.js +192 -149
- package/dist/style.css +2 -2
- package/lib/bin.js +2 -2
- package/lib/build.js +2 -2
- package/lib/index.d.ts +0 -3
- package/lib/index.js +160 -205
- package/lib/transform.d.ts +26 -0
- package/lib/transform.js +78 -0
- package/lib/websocket.d.ts +0 -1
- package/package.json +9 -8
- package/dist/radix-ui-themes.js +0 -9305
- package/lib/dev.d.ts +0 -18
- package/lib/dev.js +0 -87
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react'
|
|
2
2
|
import { useNavigate } from 'react-router'
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import { AlertCircle, Package, Terminal, Box as IconBox, Layers, Clock, Brain, Wrench, Database, Shield, Settings, Plug, Server, type LucideIcon } from 'lucide-react'
|
|
4
|
+
import { Card, CardContent } from '../components/ui/card'
|
|
5
|
+
import { Badge } from '../components/ui/badge'
|
|
6
|
+
import { Alert, AlertDescription } from '../components/ui/alert'
|
|
7
|
+
import { Skeleton } from '../components/ui/skeleton'
|
|
8
|
+
import { Separator } from '../components/ui/separator'
|
|
9
|
+
|
|
10
|
+
/** Feature 序列化格式(与后端 FeatureJSON 一致) */
|
|
11
|
+
interface FeatureJSON {
|
|
12
|
+
name: string
|
|
13
|
+
icon: string
|
|
14
|
+
desc: string
|
|
15
|
+
count: number
|
|
16
|
+
items: any[]
|
|
17
|
+
}
|
|
7
18
|
|
|
8
19
|
interface Plugin {
|
|
9
20
|
name: string
|
|
10
21
|
status: 'active' | 'inactive'
|
|
11
|
-
commandCount: number
|
|
12
|
-
componentCount: number
|
|
13
|
-
middlewareCount: number
|
|
14
|
-
contextCount: number
|
|
15
22
|
description: string
|
|
23
|
+
features: FeatureJSON[]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** 根据后端返回的 icon 名称映射到 lucide-react 图标组件 */
|
|
27
|
+
const iconMap: Record<string, LucideIcon> = {
|
|
28
|
+
Terminal,
|
|
29
|
+
Box: IconBox,
|
|
30
|
+
Layers,
|
|
31
|
+
Clock,
|
|
32
|
+
Brain,
|
|
33
|
+
Wrench,
|
|
34
|
+
Database,
|
|
35
|
+
Shield,
|
|
36
|
+
Settings,
|
|
37
|
+
Plug,
|
|
38
|
+
Server,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getIcon(iconName: string): LucideIcon {
|
|
42
|
+
return iconMap[iconName] || Package
|
|
16
43
|
}
|
|
17
44
|
|
|
18
45
|
export default function DashboardPlugins() {
|
|
@@ -31,14 +58,9 @@ export default function DashboardPlugins() {
|
|
|
31
58
|
try {
|
|
32
59
|
const res = await fetch('/api/plugins', { credentials: 'include' })
|
|
33
60
|
if (!res.ok) throw new Error('API 请求失败')
|
|
34
|
-
|
|
35
61
|
const data = await res.json()
|
|
36
|
-
if (data.success) {
|
|
37
|
-
|
|
38
|
-
setError(null)
|
|
39
|
-
} else {
|
|
40
|
-
throw new Error('数据格式错误')
|
|
41
|
-
}
|
|
62
|
+
if (data.success) { setPlugins(data.data); setError(null) }
|
|
63
|
+
else throw new Error('数据格式错误')
|
|
42
64
|
} catch (err) {
|
|
43
65
|
setError((err as Error).message)
|
|
44
66
|
} finally {
|
|
@@ -48,119 +70,100 @@ export default function DashboardPlugins() {
|
|
|
48
70
|
|
|
49
71
|
if (loading) {
|
|
50
72
|
return (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
</
|
|
56
|
-
</
|
|
73
|
+
<div className="space-y-4">
|
|
74
|
+
<Skeleton className="h-8 w-48" />
|
|
75
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
|
|
76
|
+
{[...Array(6)].map((_, i) => <Skeleton key={i} className="h-40" />)}
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
57
79
|
)
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
if (error) {
|
|
61
83
|
return (
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
加载失败: {error}
|
|
69
|
-
</Callout.Text>
|
|
70
|
-
</Callout.Root>
|
|
71
|
-
</Flex>
|
|
84
|
+
<div className="flex items-center justify-center h-full">
|
|
85
|
+
<Alert variant="destructive" className="max-w-md">
|
|
86
|
+
<AlertCircle className="h-4 w-4" />
|
|
87
|
+
<AlertDescription>加载失败: {error}</AlertDescription>
|
|
88
|
+
</Alert>
|
|
89
|
+
</div>
|
|
72
90
|
)
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
return (
|
|
76
|
-
<
|
|
77
|
-
{/*
|
|
78
|
-
<
|
|
79
|
-
<
|
|
80
|
-
<
|
|
81
|
-
<
|
|
82
|
-
<Badge
|
|
83
|
-
<
|
|
84
|
-
</
|
|
85
|
-
</
|
|
86
|
-
|
|
87
|
-
{/*
|
|
88
|
-
<
|
|
94
|
+
<div className="space-y-4">
|
|
95
|
+
{/* Header */}
|
|
96
|
+
<div>
|
|
97
|
+
<h1 className="text-2xl font-bold tracking-tight">插件管理</h1>
|
|
98
|
+
<div className="flex items-center gap-2 mt-1">
|
|
99
|
+
<span className="text-sm text-muted-foreground">共 {plugins.length} 个插件</span>
|
|
100
|
+
<Badge variant="success">{plugins.filter(p => p.status === 'active').length}</Badge>
|
|
101
|
+
<span className="text-sm text-muted-foreground">个运行中</span>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
{/* Plugin grid */}
|
|
106
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
|
|
89
107
|
{plugins.map((plugin, index) => (
|
|
90
|
-
<Card
|
|
108
|
+
<Card
|
|
91
109
|
key={`${plugin.name}-${index}`}
|
|
92
|
-
className="cursor-pointer hover-
|
|
110
|
+
className="cursor-pointer transition-all hover:shadow-md hover:-translate-y-0.5"
|
|
93
111
|
onClick={() => navigate(`/plugins/${encodeURIComponent(plugin.name)}`)}
|
|
94
112
|
>
|
|
95
|
-
<
|
|
96
|
-
{/*
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
<Package className="w-4 h-4
|
|
101
|
-
</
|
|
102
|
-
<
|
|
103
|
-
</
|
|
104
|
-
<Badge
|
|
105
|
-
color={plugin.status === 'active' ? 'green' : 'gray'}
|
|
106
|
-
size="1"
|
|
107
|
-
>
|
|
113
|
+
<CardContent className="p-4 space-y-3">
|
|
114
|
+
{/* Header */}
|
|
115
|
+
<div className="flex justify-between items-center">
|
|
116
|
+
<div className="flex items-center gap-2">
|
|
117
|
+
<div className="flex items-center justify-center w-8 h-8 rounded-md bg-secondary">
|
|
118
|
+
<Package className="w-4 h-4" />
|
|
119
|
+
</div>
|
|
120
|
+
<span className="font-semibold text-sm">{plugin.name}</span>
|
|
121
|
+
</div>
|
|
122
|
+
<Badge variant={plugin.status === 'active' ? 'success' : 'secondary'}>
|
|
108
123
|
{plugin.status === 'active' ? '运行中' : '已停止'}
|
|
109
124
|
</Badge>
|
|
110
|
-
</
|
|
125
|
+
</div>
|
|
111
126
|
|
|
112
|
-
|
|
113
|
-
<Text size="1" color="gray" className="line-clamp-2">
|
|
127
|
+
<p className="text-xs text-muted-foreground line-clamp-2">
|
|
114
128
|
{plugin.description || '暂无描述'}
|
|
115
|
-
</
|
|
116
|
-
|
|
117
|
-
<Separator
|
|
118
|
-
|
|
119
|
-
{/*
|
|
120
|
-
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</Flex>
|
|
138
|
-
|
|
139
|
-
<Flex gap="2" justify="center" align="center" className="rounded-md bg-orange-500/5 dark:bg-orange-400/5 p-1.5">
|
|
140
|
-
<Database className="w-3 h-3 text-orange-600 dark:text-orange-400" />
|
|
141
|
-
<Text size="2" weight="bold" className="mt-0.5">{plugin.contextCount}</Text>
|
|
142
|
-
<Text size="1" color="gray">上下文</Text>
|
|
143
|
-
</Flex>
|
|
144
|
-
</Grid>
|
|
145
|
-
</Flex>
|
|
129
|
+
</p>
|
|
130
|
+
|
|
131
|
+
<Separator />
|
|
132
|
+
|
|
133
|
+
{/* Features - 动态渲染,每个 Feature 自带 icon/name/count */}
|
|
134
|
+
{plugin.features.length > 0 ? (
|
|
135
|
+
<div className={`grid gap-1`} style={{ gridTemplateColumns: `repeat(${Math.min(plugin.features.length, 4)}, 1fr)` }}>
|
|
136
|
+
{plugin.features.map((feature) => {
|
|
137
|
+
const Icon = getIcon(feature.icon)
|
|
138
|
+
return (
|
|
139
|
+
<div key={feature.name} className="flex flex-col items-center gap-0.5 rounded-md bg-secondary/50 p-1.5">
|
|
140
|
+
<Icon className="w-3 h-3 text-muted-foreground" />
|
|
141
|
+
<span className="text-sm font-bold">{feature.count}</span>
|
|
142
|
+
<span className="text-[10px] text-muted-foreground">{feature.desc}</span>
|
|
143
|
+
</div>
|
|
144
|
+
)
|
|
145
|
+
})}
|
|
146
|
+
</div>
|
|
147
|
+
) : (
|
|
148
|
+
<p className="text-xs text-muted-foreground text-center py-1">无注册功能</p>
|
|
149
|
+
)}
|
|
150
|
+
</CardContent>
|
|
146
151
|
</Card>
|
|
147
152
|
))}
|
|
148
|
-
</
|
|
153
|
+
</div>
|
|
149
154
|
|
|
150
|
-
{/*
|
|
155
|
+
{/* Empty state */}
|
|
151
156
|
{plugins.length === 0 && (
|
|
152
157
|
<Card className="mt-6">
|
|
153
|
-
<
|
|
154
|
-
<
|
|
155
|
-
<Package className="w-8 h-8 text-
|
|
156
|
-
</
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
</Flex>
|
|
161
|
-
</Flex>
|
|
158
|
+
<CardContent className="flex flex-col items-center gap-3 py-12">
|
|
159
|
+
<div className="flex items-center justify-center w-16 h-16 rounded-full bg-muted">
|
|
160
|
+
<Package className="w-8 h-8 text-muted-foreground" />
|
|
161
|
+
</div>
|
|
162
|
+
<h3 className="text-lg font-semibold">暂无插件</h3>
|
|
163
|
+
<p className="text-sm text-muted-foreground">请先安装并启用插件</p>
|
|
164
|
+
</CardContent>
|
|
162
165
|
</Card>
|
|
163
166
|
)}
|
|
164
|
-
</
|
|
167
|
+
</div>
|
|
165
168
|
)
|
|
166
169
|
}
|