UI: polish
This commit is contained in:
@@ -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
@@ -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 |
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user