UI: polish

This commit is contained in:
qixinbo
2026-03-22 17:42:10 +08:00
parent 6f074df40e
commit e7d799ffe1
6 changed files with 28 additions and 16 deletions
+9 -3
View File
@@ -22,11 +22,17 @@
- **🛠️ 强大的 Agent 技能拓展**: 基于核心 `nanobot`框架(`OpenClaw`的精简版)构建。支持通过斜杠命令 (`/`) 快速调用自定义工具 (Skills),完美贴合特定业务逻辑。 - **🛠️ 强大的 Agent 技能拓展**: 基于核心 `nanobot`框架(`OpenClaw`的精简版)构建。支持通过斜杠命令 (`/`) 快速调用自定义工具 (Skills),完美贴合特定业务逻辑。
- **📊 可定制仪表盘 (Dashboard)**: 一键将对话中生成的图表固定到看板,拖拽布局,随时查看核心指标。 - **📊 可定制仪表盘 (Dashboard)**: 一键将对话中生成的图表固定到看板,拖拽布局,随时查看核心指标。
<br /> ***
## 📸 界面预览
<div align="center"> <div align="center">
<img src="./examples/index.png" width="48%" /> <h3>对话式分析界面</h3>
<img src="./examples/dashboard.png" width="48%" /> <img src="./examples/index.png" width="80%" />
<br />
<br />
<h3>可定制仪表盘</h3>
<img src="./examples/dashboard.png" width="80%" />
</div> </div>
<br /> <br />
+9 -3
View File
@@ -22,11 +22,17 @@ Whether you're querying a massive Supabase/PostgreSQL database or just tossing i
- **🛠️ Extensible Agent Skills**: Built on top of the powerful `nanobot` framework (a lightweight version of `OpenClaw`). Add custom tools and slash commands (`/`) to tailor the agent to your specific business logic. - **🛠️ Extensible Agent Skills**: Built on top of the powerful `nanobot` framework (a lightweight version of `OpenClaw`). Add custom tools and slash commands (`/`) to tailor the agent to your specific business logic.
- **📊 Customizable Dashboards**: Pin your favorite chat-generated charts to a drag-and-drop dashboard for quick access. - **📊 Customizable Dashboards**: Pin your favorite chat-generated charts to a drag-and-drop dashboard for quick access.
<br /> ***
## 📸 Screenshots
<div align="center"> <div align="center">
<img src="./examples/index.png" width="48%" /> <h3>Chat Interface</h3>
<img src="./examples/dashboard.png" width="48%" /> <img src="./examples/index.png" width="80%" />
<br />
<br />
<h3>Customizable Dashboard</h3>
<img src="./examples/dashboard.png" width="80%" />
</div> </div>
<br /> <br />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 344 KiB

After

Width:  |  Height:  |  Size: 398 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 314 KiB

+1 -1
View File
@@ -812,7 +812,7 @@ export function ChatInterface() {
<PopoverTrigger className="flex items-center justify-center h-9 w-9 rounded-full hover:bg-zinc-100 transition-colors text-zinc-500"> <PopoverTrigger className="flex items-center justify-center h-9 w-9 rounded-full hover:bg-zinc-100 transition-colors text-zinc-500">
<Plus className="h-5 w-5" /> <Plus className="h-5 w-5" />
</PopoverTrigger> </PopoverTrigger>
<PopoverContent side="top" align="start" className="w-[480px] p-0 mb-2 overflow-hidden rounded-2xl border-zinc-200 shadow-xl"> <PopoverContent side="bottom" align="start" className="w-[480px] p-0 mt-2 overflow-hidden rounded-2xl border-zinc-200 shadow-xl">
<div className="flex divide-x divide-zinc-100"> <div className="flex divide-x divide-zinc-100">
{/* Left Column: Data Source */} {/* Left Column: Data Source */}
<div className="flex-1 p-3 bg-zinc-50/50"> <div className="flex-1 p-3 bg-zinc-50/50">
+9 -9
View File
@@ -250,10 +250,10 @@ export function Dashboard() {
return ( return (
<div key={chart.id} className="relative group"> <div key={chart.id} className="relative group">
<Card className="h-full flex flex-col shadow-sm border-muted"> <Card className="h-full flex flex-col shadow-sm border-muted">
<CardHeader className="pb-2 shrink-0 flex flex-row items-center justify-between space-y-0"> <CardHeader className="p-3 pb-1 shrink-0 flex flex-row items-center justify-between space-y-0">
<div> <div>
<CardTitle className="text-base">{chart.title}</CardTitle> <CardTitle className="text-sm">{chart.title}</CardTitle>
<CardDescription className="text-xs"> <CardDescription className="text-[10px] mt-0.5">
{chart.type === "table" {chart.type === "table"
? t('tableRowColDesc', { rowCount: rows.length, colCount: columns.length }) ? t('tableRowColDesc', { rowCount: rows.length, colCount: columns.length })
: `${chart.type.toUpperCase()} Chart`} : `${chart.type.toUpperCase()} Chart`}
@@ -262,13 +262,13 @@ export function Dashboard() {
<Button <Button
variant="ghost" variant="ghost"
size="icon" size="icon"
className="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity" className="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity -mr-1"
onClick={() => removeChart(chart.id, activeDashboard.id, currentProject.id)} onClick={() => removeChart(chart.id, activeDashboard.id, currentProject.id)}
> >
<X className="h-4 w-4" /> <X className="h-4 w-4" />
</Button> </Button>
</CardHeader> </CardHeader>
<CardContent className="flex-1 min-h-0 p-2"> <CardContent className="flex-1 min-h-0 p-3 pt-1 flex flex-col">
{(() => { {(() => {
if (chart.type === "table") { if (chart.type === "table") {
if (rows.length === 0) { if (rows.length === 0) {
@@ -286,11 +286,11 @@ export function Dashboard() {
); );
} }
return ( return (
<div className="h-full w-full flex flex-col gap-2"> <div className="flex-1 w-full flex flex-col min-h-0">
<div className="text-[11px] text-zinc-500 px-1"> <div className="text-[11px] text-zinc-500 mb-1 shrink-0">
{isTableTruncated ? t('previewTableRows', { previewLimit: TABLE_PREVIEW_LIMIT, rowCount: rows.length, colCount: columns.length }) : t('totalTableRows', { rowCount: rows.length, colCount: columns.length })} {isTableTruncated ? t('previewTableRows', { previewLimit: TABLE_PREVIEW_LIMIT, rowCount: rows.length, colCount: columns.length }) : t('totalTableRows', { rowCount: rows.length, colCount: columns.length })}
</div> </div>
<ScrollArea className="flex-1 w-full border rounded-md"> <ScrollArea className="flex-1 w-full border border-zinc-100 rounded-md bg-white">
<Table> <Table>
<TableHeader> <TableHeader>
<TableRow> <TableRow>
@@ -313,7 +313,7 @@ export function Dashboard() {
} }
if (chart.chartSpec && rows.length > 0) { if (chart.chartSpec && rows.length > 0) {
return ( return (
<div className="h-full w-full rounded-xl border border-zinc-100 p-2 overflow-hidden"> <div className="flex-1 w-full overflow-hidden">
<VegaChart data={rows} spec={chart.chartSpec} /> <VegaChart data={rows} spec={chart.chartSpec} />
</div> </div>
); );