omnix-chat 0.1.0 → 0.1.1
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 +8 -0
- package/README.md +36 -32
- package/dist/ChartBlockView-BxeyV5k3.js +187 -0
- package/dist/ChartBlockView-BxeyV5k3.js.map +1 -0
- package/dist/blockExport-BM_kHo4u.js +15878 -0
- package/dist/blockExport-BM_kHo4u.js.map +1 -0
- package/dist/{es-BoccmK_s.js → es-CMa51LKF.js} +1 -1
- package/dist/{es-BoccmK_s.js.map → es-CMa51LKF.js.map} +1 -1
- package/dist/omnix-chat.es.js +1761 -696
- package/dist/omnix-chat.es.js.map +1 -1
- package/dist/omnix-chat.umd.js +24 -3
- package/dist/omnix-chat.umd.js.map +1 -1
- package/dist/react.es.js +25683 -19842
- package/dist/react.es.js.map +1 -1
- package/dist/react.umd.js +521 -117
- package/dist/react.umd.js.map +1 -1
- package/dist/recharts-BToJQbDQ.js +17924 -0
- package/dist/recharts-BToJQbDQ.js.map +1 -0
- package/dist/rolldown-runtime-gEudmnaM.js +23 -0
- package/dist/src/chat/ChatRoot.d.ts.map +1 -1
- package/dist/src/chat/bridge/messageBridge.d.ts +1 -1
- package/dist/src/chat/bridge/messageBridge.d.ts.map +1 -1
- package/dist/src/chat/components/LoginForm.d.ts.map +1 -1
- package/dist/src/chat/components/message/BlockExportActions.d.ts.map +1 -1
- package/dist/src/chat/components/message/ChartBlockView.d.ts +8 -0
- package/dist/src/chat/components/message/ChartBlockView.d.ts.map +1 -0
- package/dist/src/chat/components/message/MessageBlockRenderer.d.ts.map +1 -1
- package/dist/src/chat/components/panel/AIAssistantPanel.d.ts.map +1 -1
- package/dist/src/chat/components/panel/ConversationSidebar.d.ts +1 -1
- package/dist/src/chat/components/panel/ConversationSidebar.d.ts.map +1 -1
- package/dist/src/chat/components/panel/DownFeedbackModal.d.ts.map +1 -1
- package/dist/src/chat/components/panel/MessageBody.d.ts.map +1 -1
- package/dist/src/chat/components/panel/MessageFeedbackFooter.d.ts.map +1 -1
- package/dist/src/chat/components/panel/MessageList.d.ts +1 -1
- package/dist/src/chat/components/panel/MessageList.d.ts.map +1 -1
- package/dist/src/chat/components/panel/PromptsSection.d.ts +1 -1
- package/dist/src/chat/components/panel/PromptsSection.d.ts.map +1 -1
- package/dist/src/chat/components/panel/constants.d.ts +1 -1
- package/dist/src/chat/components/panel/constants.d.ts.map +1 -1
- package/dist/src/chat/components/panel/types.d.ts +1 -1
- package/dist/src/chat/components/panel/types.d.ts.map +1 -1
- package/dist/src/chat/components/panel/useBubbleItems.d.ts +1 -1
- package/dist/src/chat/components/panel/useBubbleItems.d.ts.map +1 -1
- package/dist/src/chat/config/assistantPrompts.d.ts +1 -1
- package/dist/src/chat/config/assistantPrompts.d.ts.map +1 -1
- package/dist/{xlsx-CXTDRHcz.js → xlsx-BkT4zGNX.js} +2225 -2218
- package/dist/{xlsx-CXTDRHcz.js.map → xlsx-BkT4zGNX.js.map} +1 -1
- package/package.json +10 -20
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
### Changed
|
|
11
11
|
|
|
12
|
+
- **开箱即用**:`omnix-chat/react` 内置 antd、@ant-design/x、icons、recharts 等 UI
|
|
13
|
+
依赖;消费者仅需安装 `react` + `react-dom`。
|
|
14
|
+
- **摇树优化**:源码改为 `antd/es/*`、`@ant-design/x/es/*`、单图标路径引入;recharts /
|
|
15
|
+
xlsx 拆为异步 chunk,主包体积更小。
|
|
16
|
+
- Headless `omnix-chat` 继续独立发布,体积保持轻量。
|
|
17
|
+
|
|
18
|
+
### Changed (earlier)
|
|
19
|
+
|
|
12
20
|
- npm package renamed from `agent-chat` to **`omnix-chat`**; build artifacts are
|
|
13
21
|
now `dist/omnix-chat.es.js` and `dist/omnix-chat.umd.js`.
|
|
14
22
|
|
package/README.md
CHANGED
|
@@ -4,11 +4,11 @@ Embeddable Agent chat SDK for the browser. Configure with a **DSN**, drop a
|
|
|
4
4
|
chat widget into any web page, and let your end users talk to your agent
|
|
5
5
|
backend.
|
|
6
6
|
|
|
7
|
-
- 🪶 **
|
|
8
|
-
|
|
7
|
+
- 🪶 **Headless core** — `omnix-chat` is a small client; the full UI ships in
|
|
8
|
+
`omnix-chat/react` with antd + @ant-design/x **bundled in**.
|
|
9
9
|
- 🔌 **Two integrations** — vanilla JS (`AgentChat.init({...})`) and React
|
|
10
|
-
(`<AgentChat />` from `omnix-chat/react
|
|
11
|
-
|
|
10
|
+
(`<AgentChat />` from `omnix-chat/react`). **Only `react` + `react-dom` are
|
|
11
|
+
required peers** — no need to install antd or @ant-design/x yourself.
|
|
12
12
|
- 🎨 **Ant Design X UI** — the chat surface is built on
|
|
13
13
|
[@ant-design/x](https://x.ant.design/) (Bubble, Sender, Welcome) with full
|
|
14
14
|
antd theming (`light`/`dark`/`auto` + token overrides).
|
|
@@ -23,46 +23,34 @@ backend.
|
|
|
23
23
|
|
|
24
24
|
### CDN drop-in (`<script>` tag)
|
|
25
25
|
|
|
26
|
+
Only **React** is required besides the SDK — antd and @ant-design/x are bundled
|
|
27
|
+
inside `omnix-chat/react`.
|
|
28
|
+
|
|
26
29
|
```html
|
|
27
|
-
<!-- Peer dependencies (load order matters) -->
|
|
28
30
|
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
|
|
29
31
|
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
|
|
30
|
-
<script
|
|
31
|
-
<script crossorigin src="https://unpkg.com/@ant-design/cssinjs/dist/cssinjs.min.js"></script>
|
|
32
|
-
<script crossorigin src="https://unpkg.com/@ant-design/icons/dist/index.umd.min.js"></script>
|
|
33
|
-
<script crossorigin src="https://unpkg.com/antd@5/dist/antd.min.js"></script>
|
|
34
|
-
<script crossorigin src="https://unpkg.com/@ant-design/x@1/dist/index.min.js"></script>
|
|
35
|
-
|
|
36
|
-
<!-- The SDK -->
|
|
37
|
-
<script src="https://unpkg.com/omnix-chat@latest/dist/omnix-chat.umd.js"></script>
|
|
32
|
+
<script src="https://unpkg.com/omnix-chat@latest/dist/react.umd.js"></script>
|
|
38
33
|
<script>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
locale: 'zh-CN',
|
|
42
|
-
theme: 'auto',
|
|
43
|
-
});
|
|
34
|
+
// Use the named export from the UMD build (see dist types for full API).
|
|
35
|
+
const { AgentChat } = OmnixChatReact;
|
|
44
36
|
</script>
|
|
45
37
|
```
|
|
46
38
|
|
|
47
|
-
|
|
39
|
+
For the **headless** client (`AgentChat.init` without pre-built UI):
|
|
48
40
|
|
|
49
|
-
```
|
|
50
|
-
|
|
41
|
+
```html
|
|
42
|
+
<script src="https://unpkg.com/omnix-chat@latest/dist/omnix-chat.umd.js"></script>
|
|
43
|
+
<script>
|
|
44
|
+
OmnixChat.init({ dsn: 'your-app-dsn', baseUrl: 'https://api.example.com' });
|
|
45
|
+
</script>
|
|
51
46
|
```
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
import { AgentChat } from 'omnix-chat';
|
|
48
|
+
### npm + React(推荐,开箱即用)
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
user: { id: 'u-123', email: 'alice@example.com' },
|
|
59
|
-
locale: 'zh-CN',
|
|
60
|
-
theme: 'auto',
|
|
61
|
-
});
|
|
50
|
+
```bash
|
|
51
|
+
pnpm add omnix-chat react react-dom
|
|
62
52
|
```
|
|
63
53
|
|
|
64
|
-
### React (recommended)
|
|
65
|
-
|
|
66
54
|
```tsx
|
|
67
55
|
import { AgentChat } from 'omnix-chat/react';
|
|
68
56
|
|
|
@@ -79,7 +67,23 @@ export function App() {
|
|
|
79
67
|
}
|
|
80
68
|
```
|
|
81
69
|
|
|
82
|
-
###
|
|
70
|
+
### npm + vanilla JavaScript(无 UI)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm add omnix-chat
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { AgentChat } from 'omnix-chat';
|
|
78
|
+
|
|
79
|
+
AgentChat.init({
|
|
80
|
+
dsn: 'your-app-dsn',
|
|
81
|
+
baseUrl: 'https://api.example.com',
|
|
82
|
+
locale: 'zh-CN',
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### React(自定义布局)
|
|
83
87
|
|
|
84
88
|
```tsx
|
|
85
89
|
import { AgentChatProvider, AgentChatEmbedded, useAgentChat } from 'omnix-chat/react';
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, r as c, s as l, t as u, u as d } from "./recharts-BToJQbDQ.js";
|
|
2
|
+
import { i as f, m as p, r as m, s as h, t as g } from "./blockExport-BM_kHo4u.js";
|
|
3
|
+
import { useEffect as _, useRef as v, useState as y } from "react";
|
|
4
|
+
import { jsx as b, jsxs as x } from "react/jsx-runtime";
|
|
5
|
+
//#region src/chat/components/message/ChartBlockView.tsx
|
|
6
|
+
var { Text: S } = p, C = [
|
|
7
|
+
"#1677ff",
|
|
8
|
+
"#52c41a",
|
|
9
|
+
"#fa8c16",
|
|
10
|
+
"#722ed1",
|
|
11
|
+
"#13c2c2",
|
|
12
|
+
"#eb2f96"
|
|
13
|
+
];
|
|
14
|
+
function w(e) {
|
|
15
|
+
return Array.isArray(e) && e.every((e) => typeof e == "string");
|
|
16
|
+
}
|
|
17
|
+
function T(e) {
|
|
18
|
+
return Array.isArray(e) && e.every((e) => {
|
|
19
|
+
if (typeof e != "object" || !e) return !1;
|
|
20
|
+
let t = e, n = e.renderType, r = e.yAxisId, i = n === void 0 || n === "bar" || n === "line", a = r === void 0 || r === "left" || r === "right";
|
|
21
|
+
return typeof t.name == "string" && Array.isArray(t.values) && t.values.every((e) => typeof e == "number") && i && a;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function E(e) {
|
|
25
|
+
if (w(e.xAxis)) return e.xAxis;
|
|
26
|
+
let t = e.xaxis;
|
|
27
|
+
return w(t) ? t : [];
|
|
28
|
+
}
|
|
29
|
+
function D(e) {
|
|
30
|
+
return T(e.series) ? e.series : [];
|
|
31
|
+
}
|
|
32
|
+
function O(e) {
|
|
33
|
+
let t = E(e), n = D(e);
|
|
34
|
+
return t.map((e, t) => {
|
|
35
|
+
let r = { x: e };
|
|
36
|
+
return n.forEach((e) => {
|
|
37
|
+
r[e.name] = e.values[t] ?? 0;
|
|
38
|
+
}), r;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function k({ block: p, locale: w }) {
|
|
42
|
+
let T = v(null), [E, k] = y([]);
|
|
43
|
+
_(() => {
|
|
44
|
+
k([]);
|
|
45
|
+
}, [p.id]);
|
|
46
|
+
let A = /* @__PURE__ */ b(m, {
|
|
47
|
+
locale: w,
|
|
48
|
+
label: h("blockExport.png", w),
|
|
49
|
+
onExport: async () => {
|
|
50
|
+
if (!T.current) throw Error("chart not ready");
|
|
51
|
+
await g(T.current, p.title);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
if (p.chartType === "pie") {
|
|
55
|
+
let e = f(p);
|
|
56
|
+
return /* @__PURE__ */ x("div", {
|
|
57
|
+
className: "ai-assistant-block-shell",
|
|
58
|
+
children: [/* @__PURE__ */ x("div", {
|
|
59
|
+
className: "ai-assistant-block-header",
|
|
60
|
+
children: [p.title ? /* @__PURE__ */ b(S, {
|
|
61
|
+
strong: !0,
|
|
62
|
+
children: p.title
|
|
63
|
+
}) : /* @__PURE__ */ b("span", { "aria-hidden": !0 }), A]
|
|
64
|
+
}), /* @__PURE__ */ b("div", {
|
|
65
|
+
ref: T,
|
|
66
|
+
className: "ai-assistant-chart-export-target w-full overflow-x-auto [&::-webkit-scrollbar]:hidden",
|
|
67
|
+
style: {
|
|
68
|
+
scrollbarWidth: "none",
|
|
69
|
+
msOverflowStyle: "none"
|
|
70
|
+
},
|
|
71
|
+
children: /* @__PURE__ */ b("div", {
|
|
72
|
+
className: "h-80 min-w-[320px]",
|
|
73
|
+
children: /* @__PURE__ */ b(r, {
|
|
74
|
+
width: "100%",
|
|
75
|
+
height: "100%",
|
|
76
|
+
children: /* @__PURE__ */ x(o, { children: [
|
|
77
|
+
/* @__PURE__ */ b(d, {}),
|
|
78
|
+
/* @__PURE__ */ b(n, {}),
|
|
79
|
+
/* @__PURE__ */ b(t, {
|
|
80
|
+
data: e,
|
|
81
|
+
dataKey: "value",
|
|
82
|
+
nameKey: "name",
|
|
83
|
+
label: !0,
|
|
84
|
+
children: e.map((e, t) => /* @__PURE__ */ b(a, { fill: C[t % C.length] }, `slice-${t}`))
|
|
85
|
+
})
|
|
86
|
+
] })
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
})]
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
let j = O(p), M = D(p), N = p.layout === "horizontal", P = M.some((e) => e.yAxisId === "right"), F = (e) => {
|
|
93
|
+
let t = typeof e?.dataKey == "string" ? e.dataKey : null;
|
|
94
|
+
t && k((e) => e.includes(t) ? e.filter((e) => e !== t) : [...e, t]);
|
|
95
|
+
};
|
|
96
|
+
return /* @__PURE__ */ x("div", {
|
|
97
|
+
className: "ai-assistant-block-shell",
|
|
98
|
+
children: [/* @__PURE__ */ x("div", {
|
|
99
|
+
className: "ai-assistant-block-header",
|
|
100
|
+
children: [p.title ? /* @__PURE__ */ b(S, {
|
|
101
|
+
strong: !0,
|
|
102
|
+
children: p.title
|
|
103
|
+
}) : /* @__PURE__ */ b("span", { "aria-hidden": !0 }), A]
|
|
104
|
+
}), /* @__PURE__ */ b("div", {
|
|
105
|
+
ref: T,
|
|
106
|
+
className: "ai-assistant-chart-export-target w-full overflow-x-auto [&::-webkit-scrollbar]:hidden",
|
|
107
|
+
style: {
|
|
108
|
+
scrollbarWidth: "none",
|
|
109
|
+
msOverflowStyle: "none"
|
|
110
|
+
},
|
|
111
|
+
children: /* @__PURE__ */ b("div", {
|
|
112
|
+
className: "h-80 min-w-[640px]",
|
|
113
|
+
children: /* @__PURE__ */ b(r, {
|
|
114
|
+
width: "100%",
|
|
115
|
+
height: "100%",
|
|
116
|
+
children: N ? /* @__PURE__ */ x(u, {
|
|
117
|
+
data: j,
|
|
118
|
+
layout: "vertical",
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ b(l, { strokeDasharray: "3 3" }),
|
|
121
|
+
/* @__PURE__ */ b(i, { type: "number" }),
|
|
122
|
+
/* @__PURE__ */ b(c, {
|
|
123
|
+
yAxisId: "left",
|
|
124
|
+
type: "category",
|
|
125
|
+
dataKey: "x",
|
|
126
|
+
width: 140
|
|
127
|
+
}),
|
|
128
|
+
/* @__PURE__ */ b(d, {}),
|
|
129
|
+
/* @__PURE__ */ b(n, { onClick: F }),
|
|
130
|
+
M.map((t, n) => {
|
|
131
|
+
let r = t.renderType ?? p.chartType ?? "bar", i = E.includes(t.name);
|
|
132
|
+
return r === "line" ? /* @__PURE__ */ b(s, {
|
|
133
|
+
yAxisId: "left",
|
|
134
|
+
type: "monotone",
|
|
135
|
+
dataKey: t.name,
|
|
136
|
+
stroke: C[n % C.length],
|
|
137
|
+
strokeWidth: 2,
|
|
138
|
+
dot: !1,
|
|
139
|
+
hide: i
|
|
140
|
+
}, t.name) : /* @__PURE__ */ b(e, {
|
|
141
|
+
yAxisId: "left",
|
|
142
|
+
dataKey: t.name,
|
|
143
|
+
fill: C[n % C.length],
|
|
144
|
+
hide: i
|
|
145
|
+
}, t.name);
|
|
146
|
+
})
|
|
147
|
+
]
|
|
148
|
+
}) : /* @__PURE__ */ x(u, {
|
|
149
|
+
data: j,
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ b(l, { strokeDasharray: "3 3" }),
|
|
152
|
+
/* @__PURE__ */ b(i, { dataKey: "x" }),
|
|
153
|
+
/* @__PURE__ */ b(c, { yAxisId: "left" }),
|
|
154
|
+
P ? /* @__PURE__ */ b(c, {
|
|
155
|
+
yAxisId: "right",
|
|
156
|
+
orientation: "right"
|
|
157
|
+
}) : null,
|
|
158
|
+
/* @__PURE__ */ b(d, {}),
|
|
159
|
+
/* @__PURE__ */ b(n, { onClick: F }),
|
|
160
|
+
M.map((t, n) => {
|
|
161
|
+
let r = t.renderType ?? p.chartType ?? "bar", i = t.yAxisId ?? "left", a = E.includes(t.name);
|
|
162
|
+
return r === "line" ? /* @__PURE__ */ b(s, {
|
|
163
|
+
yAxisId: i,
|
|
164
|
+
type: "monotone",
|
|
165
|
+
dataKey: t.name,
|
|
166
|
+
stroke: C[n % C.length],
|
|
167
|
+
strokeWidth: 2,
|
|
168
|
+
dot: !1,
|
|
169
|
+
hide: a
|
|
170
|
+
}, t.name) : /* @__PURE__ */ b(e, {
|
|
171
|
+
yAxisId: i,
|
|
172
|
+
dataKey: t.name,
|
|
173
|
+
fill: C[n % C.length],
|
|
174
|
+
hide: a
|
|
175
|
+
}, t.name);
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
})]
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { k as default };
|
|
186
|
+
|
|
187
|
+
//# sourceMappingURL=ChartBlockView-BxeyV5k3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChartBlockView-BxeyV5k3.js","names":[],"sources":["../src/chat/components/message/ChartBlockView.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport Typography from \"antd/es/typography\";\nimport {\n Bar,\n CartesianGrid,\n Cell,\n ComposedChart,\n Legend,\n Line,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { buildPieChartData } from \"./chartBlockUtils\";\nimport { BlockExportActions } from \"./BlockExportActions\";\nimport { exportChartToPng } from \"./blockExport\";\nimport { t } from \"../../utils\";\nimport type { MessageBlock } from \"./types\";\n\nconst { Text } = Typography;\n\nconst CHART_SERIES_COLORS = [\n \"#1677ff\",\n \"#52c41a\",\n \"#fa8c16\",\n \"#722ed1\",\n \"#13c2c2\",\n \"#eb2f96\",\n];\n\ninterface ChartSeriesLike {\n name: string;\n values: number[];\n renderType?: \"bar\" | \"line\";\n yAxisId?: \"left\" | \"right\";\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction isChartSeriesArray(value: unknown): value is ChartSeriesLike[] {\n return (\n Array.isArray(value) &&\n value.every((item) => {\n if (typeof item !== \"object\" || item === null) {\n return false;\n }\n const candidate = item as { name?: unknown; values?: unknown };\n const renderTypeCandidate = (item as { renderType?: unknown }).renderType;\n const yAxisIdCandidate = (item as { yAxisId?: unknown }).yAxisId;\n const renderTypeValid =\n renderTypeCandidate === undefined ||\n renderTypeCandidate === \"bar\" ||\n renderTypeCandidate === \"line\";\n const yAxisIdValid =\n yAxisIdCandidate === undefined ||\n yAxisIdCandidate === \"left\" ||\n yAxisIdCandidate === \"right\";\n return (\n typeof candidate.name === \"string\" &&\n Array.isArray(candidate.values) &&\n candidate.values.every((v) => typeof v === \"number\") &&\n renderTypeValid &&\n yAxisIdValid\n );\n })\n );\n}\n\nfunction getChartXAxis(block: Extract<MessageBlock, { type: \"chart\" }>): string[] {\n if (isStringArray(block.xAxis)) {\n return block.xAxis;\n }\n const fallback = (block as unknown as { xaxis?: unknown }).xaxis;\n if (isStringArray(fallback)) {\n return fallback;\n }\n return [];\n}\n\nfunction getChartSeries(block: Extract<MessageBlock, { type: \"chart\" }>): ChartSeriesLike[] {\n if (isChartSeriesArray(block.series)) {\n return block.series;\n }\n return [];\n}\n\nfunction renderChartData(block: Extract<MessageBlock, { type: \"chart\" }>) {\n const xAxis = getChartXAxis(block);\n const series = getChartSeries(block);\n return xAxis.map((x, index) => {\n const row: Record<string, number | string> = { x };\n series.forEach((s) => {\n row[s.name] = s.values[index] ?? 0;\n });\n return row;\n });\n}\n\nexport default function ChartBlockView({\n block,\n locale,\n}: {\n block: Extract<MessageBlock, { type: \"chart\" }>;\n locale?: string;\n}) {\n const chartRef = useRef<HTMLDivElement>(null);\n const [hiddenSeriesNames, setHiddenSeriesNames] = useState<string[]>([]);\n useEffect(() => {\n setHiddenSeriesNames([]);\n }, [block.id]);\n\n const exportToolbar = (\n <BlockExportActions\n locale={locale}\n label={t(\"blockExport.png\", locale)}\n onExport={async () => {\n if (!chartRef.current) {\n throw new Error(\"chart not ready\");\n }\n await exportChartToPng(chartRef.current, block.title);\n }}\n />\n );\n\n if (block.chartType === \"pie\") {\n const pieData = buildPieChartData(block);\n return (\n <div className=\"ai-assistant-block-shell\">\n <div className=\"ai-assistant-block-header\">\n {block.title ? <Text strong>{block.title}</Text> : <span aria-hidden />}\n {exportToolbar}\n </div>\n <div\n ref={chartRef}\n className=\"ai-assistant-chart-export-target w-full overflow-x-auto [&::-webkit-scrollbar]:hidden\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <div className=\"h-80 min-w-[320px]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <PieChart>\n <Tooltip />\n <Legend />\n <Pie data={pieData} dataKey=\"value\" nameKey=\"name\" label>\n {pieData.map((_, index) => (\n <Cell\n key={`slice-${index}`}\n fill={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]}\n />\n ))}\n </Pie>\n </PieChart>\n </ResponsiveContainer>\n </div>\n </div>\n </div>\n );\n }\n\n const data = renderChartData(block);\n const series = getChartSeries(block);\n const horizontalLayout = block.layout === \"horizontal\";\n const hasRightAxis = series.some((seriesItem) => seriesItem.yAxisId === \"right\");\n\n const handleLegendClick = (\n entry:\n | {\n dataKey?: string | number | ((obj: unknown) => unknown);\n }\n | undefined,\n ) => {\n const seriesName = typeof entry?.dataKey === \"string\" ? entry.dataKey : null;\n if (!seriesName) {\n return;\n }\n setHiddenSeriesNames((prev) =>\n prev.includes(seriesName)\n ? prev.filter((item) => item !== seriesName)\n : [...prev, seriesName],\n );\n };\n\n return (\n <div className=\"ai-assistant-block-shell\">\n <div className=\"ai-assistant-block-header\">\n {block.title ? <Text strong>{block.title}</Text> : <span aria-hidden />}\n {exportToolbar}\n </div>\n <div\n ref={chartRef}\n className=\"ai-assistant-chart-export-target w-full overflow-x-auto [&::-webkit-scrollbar]:hidden\"\n style={{ scrollbarWidth: \"none\", msOverflowStyle: \"none\" }}\n >\n <div className=\"h-80 min-w-[640px]\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {horizontalLayout ? (\n <ComposedChart data={data} layout=\"vertical\">\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis type=\"number\" />\n <YAxis yAxisId=\"left\" type=\"category\" dataKey=\"x\" width={140} />\n <Tooltip />\n <Legend onClick={handleLegendClick} />\n {series.map((seriesItem, index) => {\n const renderType = seriesItem.renderType ?? block.chartType ?? \"bar\";\n const hidden = hiddenSeriesNames.includes(seriesItem.name);\n if (renderType === \"line\") {\n return (\n <Line\n key={seriesItem.name}\n yAxisId=\"left\"\n type=\"monotone\"\n dataKey={seriesItem.name}\n stroke={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]}\n strokeWidth={2}\n dot={false}\n hide={hidden}\n />\n );\n }\n return (\n <Bar\n key={seriesItem.name}\n yAxisId=\"left\"\n dataKey={seriesItem.name}\n fill={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]}\n hide={hidden}\n />\n );\n })}\n </ComposedChart>\n ) : (\n <ComposedChart data={data}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"x\" />\n <YAxis yAxisId=\"left\" />\n {hasRightAxis ? <YAxis yAxisId=\"right\" orientation=\"right\" /> : null}\n <Tooltip />\n <Legend onClick={handleLegendClick} />\n {series.map((seriesItem, index) => {\n const renderType = seriesItem.renderType ?? block.chartType ?? \"bar\";\n const yAxisId = seriesItem.yAxisId ?? \"left\";\n const hidden = hiddenSeriesNames.includes(seriesItem.name);\n if (renderType === \"line\") {\n return (\n <Line\n key={seriesItem.name}\n yAxisId={yAxisId}\n type=\"monotone\"\n dataKey={seriesItem.name}\n stroke={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]}\n strokeWidth={2}\n dot={false}\n hide={hidden}\n />\n );\n }\n return (\n <Bar\n key={seriesItem.name}\n yAxisId={yAxisId}\n dataKey={seriesItem.name}\n fill={CHART_SERIES_COLORS[index % CHART_SERIES_COLORS.length]}\n hide={hidden}\n />\n );\n })}\n </ComposedChart>\n )}\n </ResponsiveContainer>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|