@pactor-app/ui 1.21.0 → 1.22.0
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/dist/{chunk-7WB4TS55.js → chunk-44DAGWXZ.js} +2 -0
- package/dist/{chunk-XXOY57SN.js → chunk-EDUMGNT6.js} +993 -244
- package/dist/{chunk-2A5MHANX.js → chunk-QQBAMERO.js} +1 -1
- package/dist/components/index.cjs +982 -242
- package/dist/components/index.d.cts +181 -55
- package/dist/components/index.d.ts +181 -55
- package/dist/components/index.js +2 -2
- package/dist/index.cjs +1132 -392
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/layout/index.cjs +1 -0
- package/dist/layout/index.js +2 -2
- package/package.json +6 -6
- package/styles.css +66 -0
|
@@ -486,6 +486,7 @@ var ICONS = {
|
|
|
486
486
|
"file-text": import_lucide_react2.FileText,
|
|
487
487
|
"panel-left": import_lucide_react2.PanelLeft,
|
|
488
488
|
"panel-right-open": import_lucide_react2.PanelRightOpen,
|
|
489
|
+
"panel-right-close": import_lucide_react2.PanelRightClose,
|
|
489
490
|
square: import_lucide_react2.Square,
|
|
490
491
|
history: import_lucide_react2.History,
|
|
491
492
|
"rotate-ccw": import_lucide_react2.RotateCcw,
|
|
@@ -3053,6 +3054,7 @@ function ChatInput({
|
|
|
3053
3054
|
toolbarEnd,
|
|
3054
3055
|
header,
|
|
3055
3056
|
footer,
|
|
3057
|
+
field,
|
|
3056
3058
|
onChange,
|
|
3057
3059
|
onSubmit,
|
|
3058
3060
|
className,
|
|
@@ -3063,6 +3065,8 @@ function ChatInput({
|
|
|
3063
3065
|
const [draft, setDraft] = (0, import_react14.useState)("");
|
|
3064
3066
|
const text = controlled ? value : draft;
|
|
3065
3067
|
const canSubmit = !disabled && text.trim() !== "";
|
|
3068
|
+
const customField = field !== void 0 && field !== null;
|
|
3069
|
+
const renderSlot = (slot) => (0, import_react14.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
3066
3070
|
const composingRef = (0, import_react14.useRef)(false);
|
|
3067
3071
|
const handleChange = (next) => {
|
|
3068
3072
|
if (!controlled) {
|
|
@@ -3098,8 +3102,8 @@ function ChatInput({
|
|
|
3098
3102
|
),
|
|
3099
3103
|
style,
|
|
3100
3104
|
children: [
|
|
3101
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children:
|
|
3102
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3105
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "px-3 pt-3", children: renderSlot(header) }) : null,
|
|
3106
|
+
customField ? field : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3103
3107
|
Textarea,
|
|
3104
3108
|
{
|
|
3105
3109
|
value: text,
|
|
@@ -3114,9 +3118,9 @@ function ChatInput({
|
|
|
3114
3118
|
}
|
|
3115
3119
|
),
|
|
3116
3120
|
toolbarStart || toolbarEnd || !hideSend ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1 px-2 pb-2", children: [
|
|
3117
|
-
toolbarStart ?
|
|
3121
|
+
toolbarStart ? renderSlot(toolbarStart) : null,
|
|
3118
3122
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "flex-1" }),
|
|
3119
|
-
toolbarEnd ?
|
|
3123
|
+
toolbarEnd ? renderSlot(toolbarEnd) : null,
|
|
3120
3124
|
hideSend ? null : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
3121
3125
|
Button,
|
|
3122
3126
|
{
|
|
@@ -3130,7 +3134,7 @@ function ChatInput({
|
|
|
3130
3134
|
}
|
|
3131
3135
|
)
|
|
3132
3136
|
] }) : null,
|
|
3133
|
-
footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children:
|
|
3137
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "border-t border-border px-3 py-2", children: renderSlot(footer) }) : null
|
|
3134
3138
|
]
|
|
3135
3139
|
}
|
|
3136
3140
|
);
|
|
@@ -3682,7 +3686,8 @@ function DatePicker(props) {
|
|
|
3682
3686
|
onSelect: handleRangeDaySelect,
|
|
3683
3687
|
modifiers: rangeModifiers,
|
|
3684
3688
|
modifiersClassNames: rangeModifierClassNames,
|
|
3685
|
-
locale: dfLocale
|
|
3689
|
+
locale: dfLocale,
|
|
3690
|
+
showOutsideDays: false
|
|
3686
3691
|
}
|
|
3687
3692
|
)
|
|
3688
3693
|
}
|
|
@@ -3696,7 +3701,8 @@ function DatePicker(props) {
|
|
|
3696
3701
|
onSelect: handleRangeDaySelect,
|
|
3697
3702
|
modifiers: rangeModifiers,
|
|
3698
3703
|
modifiersClassNames: rangeModifierClassNames,
|
|
3699
|
-
locale: dfLocale
|
|
3704
|
+
locale: dfLocale,
|
|
3705
|
+
showOutsideDays: false
|
|
3700
3706
|
}
|
|
3701
3707
|
) })
|
|
3702
3708
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
@@ -11735,7 +11741,14 @@ function ArtifactTreeRow({
|
|
|
11735
11741
|
className: "flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-accent",
|
|
11736
11742
|
onClick: () => setOpen((value) => !value),
|
|
11737
11743
|
children: [
|
|
11738
|
-
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11744
|
+
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11745
|
+
"span",
|
|
11746
|
+
{
|
|
11747
|
+
className: "inline-flex transition-transform data-[open=true]:rotate-90",
|
|
11748
|
+
"data-open": open,
|
|
11749
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "chevron-right", size: 12 })
|
|
11750
|
+
}
|
|
11751
|
+
),
|
|
11739
11752
|
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)(Icon, { name: "folder", size: 13 }),
|
|
11740
11753
|
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("span", { className: "min-w-0 flex-1 truncate", children: node.name })
|
|
11741
11754
|
]
|
|
@@ -11867,6 +11880,7 @@ function ArtifactPanel({
|
|
|
11867
11880
|
icon: "download",
|
|
11868
11881
|
variant: "text",
|
|
11869
11882
|
tooltip: "\u4E0B\u8F7D\u4EA7\u7269",
|
|
11883
|
+
className: "px-2",
|
|
11870
11884
|
onClick: () => onDownload ? onDownload(artifact) : void downloadArtifact(artifact)
|
|
11871
11885
|
}
|
|
11872
11886
|
) : null,
|
|
@@ -11876,11 +11890,12 @@ function ArtifactPanel({
|
|
|
11876
11890
|
icon: "x",
|
|
11877
11891
|
variant: "text",
|
|
11878
11892
|
tooltip: "\u6536\u8D77\u4EA7\u7269\u533A",
|
|
11893
|
+
className: "px-2",
|
|
11879
11894
|
onClick: () => onClose?.()
|
|
11880
11895
|
}
|
|
11881
11896
|
)
|
|
11882
11897
|
] }),
|
|
11883
|
-
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11898
|
+
/* @__PURE__ */ (0, import_jsx_runtime170.jsx)("div", { className: "scrollbar-subtle min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime170.jsx)(
|
|
11884
11899
|
ArtifactListView,
|
|
11885
11900
|
{
|
|
11886
11901
|
nodes: buildArtifactTree(artifacts),
|
|
@@ -12138,7 +12153,7 @@ function Thinking({
|
|
|
12138
12153
|
{
|
|
12139
12154
|
"data-slot": "thinking",
|
|
12140
12155
|
"data-status": status,
|
|
12141
|
-
className: cn("w-full
|
|
12156
|
+
className: cn("w-full", className),
|
|
12142
12157
|
style,
|
|
12143
12158
|
children: [
|
|
12144
12159
|
/* @__PURE__ */ (0, import_jsx_runtime176.jsxs)(
|
|
@@ -12147,12 +12162,12 @@ function Thinking({
|
|
|
12147
12162
|
type: "button",
|
|
12148
12163
|
"data-slot": "thinking-trigger",
|
|
12149
12164
|
"aria-expanded": isExpanded,
|
|
12150
|
-
className: "flex w-full items-center gap-2
|
|
12165
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
12151
12166
|
onClick: toggle,
|
|
12152
12167
|
children: [
|
|
12153
12168
|
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { className: cn("text-muted-foreground", status === "thinking" && "animate-pulse motion-reduce:animate-none"), children: /* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: "brain", size: "sm" }) }),
|
|
12154
|
-
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "
|
|
12155
|
-
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
12169
|
+
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { "data-slot": "thinking-title", className: "text-muted-foreground", children: resolvedTitle }),
|
|
12170
|
+
/* @__PURE__ */ (0, import_jsx_runtime176.jsx)("span", { className: "text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime176.jsx)(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" }) })
|
|
12156
12171
|
]
|
|
12157
12172
|
}
|
|
12158
12173
|
),
|
|
@@ -12160,7 +12175,7 @@ function Thinking({
|
|
|
12160
12175
|
"div",
|
|
12161
12176
|
{
|
|
12162
12177
|
"data-slot": "thinking-content",
|
|
12163
|
-
className: "
|
|
12178
|
+
className: "py-1 pl-6 text-sm whitespace-pre-wrap text-muted-foreground",
|
|
12164
12179
|
children: content
|
|
12165
12180
|
}
|
|
12166
12181
|
) : null
|
|
@@ -12190,42 +12205,51 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
12190
12205
|
const [expanded, setExpanded] = (0, import_react62.useState)(defaultExpanded ?? status === "running");
|
|
12191
12206
|
const meta = statusIcon3[status];
|
|
12192
12207
|
const paramsText = renderValue(params);
|
|
12208
|
+
const hasDetail = Boolean(paramsText) || Boolean(result);
|
|
12209
|
+
const headerInner = /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(import_jsx_runtime177.Fragment, { children: [
|
|
12210
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: "terminal", size: "sm" }) }),
|
|
12211
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { "data-slot": "tool-call-name", className: "min-w-0 truncate font-medium", children: name ?? "\u5DE5\u5177\u8C03\u7528" }),
|
|
12212
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: cn("shrink-0", meta.className, meta.spin && "animate-spin motion-reduce:animate-none"), children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: meta.icon, size: "sm" }) }),
|
|
12213
|
+
durationMs !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
12214
|
+
(durationMs / 1e3).toFixed(1),
|
|
12215
|
+
"s"
|
|
12216
|
+
] }) : null,
|
|
12217
|
+
hasDetail ? /* @__PURE__ */ (0, import_jsx_runtime177.jsx)("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" }) }) : null
|
|
12218
|
+
] });
|
|
12193
12219
|
return /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)(
|
|
12194
12220
|
"div",
|
|
12195
12221
|
{
|
|
12196
12222
|
"data-slot": "tool-call",
|
|
12197
12223
|
"data-status": status,
|
|
12198
|
-
className: cn("w-full
|
|
12224
|
+
className: cn("w-full", className),
|
|
12199
12225
|
style,
|
|
12200
12226
|
children: [
|
|
12201
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.
|
|
12227
|
+
hasDetail ? /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
|
|
12202
12228
|
"button",
|
|
12203
12229
|
{
|
|
12204
12230
|
type: "button",
|
|
12205
12231
|
"data-slot": "tool-call-trigger",
|
|
12206
12232
|
"aria-expanded": expanded,
|
|
12207
|
-
className: "flex w-full items-center gap-2
|
|
12233
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
12208
12234
|
onClick: () => setExpanded((value) => !value),
|
|
12209
|
-
children:
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12217
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
12218
|
-
]
|
|
12235
|
+
children: headerInner
|
|
12236
|
+
}
|
|
12237
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime177.jsx)(
|
|
12238
|
+
"div",
|
|
12239
|
+
{
|
|
12240
|
+
"data-slot": "tool-call-trigger",
|
|
12241
|
+
className: "flex w-full items-center gap-2 py-1 text-left text-sm",
|
|
12242
|
+
children: headerInner
|
|
12219
12243
|
}
|
|
12220
12244
|
),
|
|
12221
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2
|
|
12245
|
+
hasDetail && expanded ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2 py-1 pl-6", children: [
|
|
12222
12246
|
paramsText ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
|
|
12223
12247
|
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u53C2\u6570" }),
|
|
12224
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto
|
|
12248
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: paramsText })
|
|
12225
12249
|
] }) : null,
|
|
12226
12250
|
result ? /* @__PURE__ */ (0, import_jsx_runtime177.jsxs)("div", { children: [
|
|
12227
12251
|
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("div", { className: "text-xs font-medium text-muted-foreground", children: "\u7ED3\u679C" }),
|
|
12228
|
-
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto
|
|
12252
|
+
/* @__PURE__ */ (0, import_jsx_runtime177.jsx)("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: result })
|
|
12229
12253
|
] }) : null
|
|
12230
12254
|
] }) : null
|
|
12231
12255
|
]
|
|
@@ -12235,12 +12259,26 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
12235
12259
|
|
|
12236
12260
|
// src/components/chat/ChatMessage/index.tsx
|
|
12237
12261
|
var import_jsx_runtime178 = require("react/jsx-runtime");
|
|
12238
|
-
function PartView({
|
|
12262
|
+
function PartView({
|
|
12263
|
+
part,
|
|
12264
|
+
role,
|
|
12265
|
+
onOpenArtifacts
|
|
12266
|
+
}) {
|
|
12267
|
+
if (role === "system" && (part.type === "text" || part.type === "markdown")) {
|
|
12268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12269
|
+
"div",
|
|
12270
|
+
{
|
|
12271
|
+
"data-slot": "chat-message-system-part",
|
|
12272
|
+
className: "w-full text-center text-xs text-muted-foreground",
|
|
12273
|
+
children: part.type === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content }) : part.content
|
|
12274
|
+
}
|
|
12275
|
+
);
|
|
12276
|
+
}
|
|
12239
12277
|
switch (part.type) {
|
|
12240
12278
|
case "text":
|
|
12241
12279
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "muted", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("span", { className: "text-sm whitespace-pre-wrap", children: part.content }) });
|
|
12242
12280
|
case "markdown":
|
|
12243
|
-
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content
|
|
12281
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(import_markdown2.MarkdownDslComponent, { content: part.content }) });
|
|
12244
12282
|
case "thinking":
|
|
12245
12283
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Thinking, { content: part.content, status: part.status ?? "done" });
|
|
12246
12284
|
case "tool-call":
|
|
@@ -12248,10 +12286,31 @@ function PartView({ part, role }) {
|
|
|
12248
12286
|
case "tool-result":
|
|
12249
12287
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("pre", { "data-slot": "chat-message-tool-result", className: "overflow-x-auto rounded-md bg-muted p-2 text-xs whitespace-pre-wrap", children: part.content });
|
|
12250
12288
|
case "status":
|
|
12251
|
-
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-status", className: "flex items-center gap-1.5 text-
|
|
12289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-status", className: "flex w-fit items-center gap-1.5 text-muted-foreground", children: [
|
|
12252
12290
|
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "clock", size: "sm" }),
|
|
12253
12291
|
part.text
|
|
12254
12292
|
] });
|
|
12293
|
+
case "artifacts": {
|
|
12294
|
+
const artifactsClass = "flex w-fit items-center gap-1.5 text-muted-foreground";
|
|
12295
|
+
const label = `\u5DF2\u751F\u6210 ${part.count} \u4E2A\u4EA7\u7269`;
|
|
12296
|
+
return onOpenArtifacts ? /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
|
|
12297
|
+
"button",
|
|
12298
|
+
{
|
|
12299
|
+
type: "button",
|
|
12300
|
+
"data-slot": "chat-message-artifacts",
|
|
12301
|
+
className: cn(artifactsClass, "cursor-pointer hover:text-foreground"),
|
|
12302
|
+
onClick: onOpenArtifacts,
|
|
12303
|
+
children: [
|
|
12304
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
|
|
12305
|
+
label,
|
|
12306
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "chevron-right", size: 12 })
|
|
12307
|
+
]
|
|
12308
|
+
}
|
|
12309
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-artifacts", className: artifactsClass, children: [
|
|
12310
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "package", size: "sm" }),
|
|
12311
|
+
label
|
|
12312
|
+
] });
|
|
12313
|
+
}
|
|
12255
12314
|
case "error":
|
|
12256
12315
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { "data-slot": "chat-message-error", className: "flex items-center gap-1.5 text-sm text-destructive", children: [
|
|
12257
12316
|
/* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: "circle-alert", size: "sm" }),
|
|
@@ -12261,19 +12320,31 @@ function PartView({ part, role }) {
|
|
|
12261
12320
|
return null;
|
|
12262
12321
|
}
|
|
12263
12322
|
}
|
|
12323
|
+
var ACTION_ICON_BY_NAME = {
|
|
12324
|
+
copy: "copy",
|
|
12325
|
+
retry: "rotate-ccw",
|
|
12326
|
+
regenerate: "refresh-ccw",
|
|
12327
|
+
edit: "pencil",
|
|
12328
|
+
like: "thumbs-up",
|
|
12329
|
+
dislike: "thumbs-down",
|
|
12330
|
+
share: "share",
|
|
12331
|
+
delete: "trash"
|
|
12332
|
+
};
|
|
12264
12333
|
function ChatMessage({
|
|
12265
12334
|
role = "assistant",
|
|
12266
12335
|
parts = [],
|
|
12267
12336
|
status = "completed",
|
|
12268
12337
|
agent,
|
|
12269
12338
|
time,
|
|
12270
|
-
showSender =
|
|
12339
|
+
showSender = false,
|
|
12271
12340
|
actions = [],
|
|
12272
12341
|
onAction,
|
|
12342
|
+
onOpenArtifacts,
|
|
12273
12343
|
className,
|
|
12274
12344
|
style
|
|
12275
12345
|
}) {
|
|
12276
12346
|
const isUser = role === "user";
|
|
12347
|
+
const isSystem = role === "system";
|
|
12277
12348
|
const senderName = isUser ? "\u6211" : agent?.name ?? "\u52A9\u624B";
|
|
12278
12349
|
return /* @__PURE__ */ (0, import_jsx_runtime178.jsxs)(
|
|
12279
12350
|
"div",
|
|
@@ -12281,10 +12352,16 @@ function ChatMessage({
|
|
|
12281
12352
|
"data-slot": "chat-message",
|
|
12282
12353
|
"data-role": role,
|
|
12283
12354
|
"data-status": status,
|
|
12284
|
-
className: cn(
|
|
12355
|
+
className: cn(
|
|
12356
|
+
"flex w-full flex-col gap-1.5",
|
|
12357
|
+
isUser && "items-end",
|
|
12358
|
+
// system 居中弱提示(参考 @pactor-app/chat MessageBubble)
|
|
12359
|
+
isSystem && "items-center text-muted-foreground",
|
|
12360
|
+
className
|
|
12361
|
+
),
|
|
12285
12362
|
style,
|
|
12286
12363
|
children: [
|
|
12287
|
-
showSender
|
|
12364
|
+
showSender ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12288
12365
|
Sender,
|
|
12289
12366
|
{
|
|
12290
12367
|
name: senderName,
|
|
@@ -12293,35 +12370,445 @@ function ChatMessage({
|
|
|
12293
12370
|
align: isUser ? "end" : "start"
|
|
12294
12371
|
}
|
|
12295
12372
|
) : null,
|
|
12296
|
-
/* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end"), children: [
|
|
12297
|
-
parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role }, index)),
|
|
12373
|
+
/* @__PURE__ */ (0, import_jsx_runtime178.jsxs)("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end", isSystem && "items-center"), children: [
|
|
12374
|
+
parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(PartView, { part, role, onOpenArtifacts }, index)),
|
|
12298
12375
|
status === "streaming" ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(StreamingText, { content: "", streaming: true }) : null
|
|
12299
12376
|
] }),
|
|
12300
|
-
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1", children: actions.map((action) =>
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
|
|
12305
|
-
|
|
12306
|
-
|
|
12307
|
-
|
|
12308
|
-
|
|
12309
|
-
|
|
12310
|
-
|
|
12311
|
-
|
|
12312
|
-
|
|
12313
|
-
|
|
12314
|
-
|
|
12377
|
+
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ (0, import_jsx_runtime178.jsx)("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1 mt-2", children: actions.map((action) => {
|
|
12378
|
+
const label = action.label ?? action.name;
|
|
12379
|
+
const iconName = action.icon ?? ACTION_ICON_BY_NAME[action.name];
|
|
12380
|
+
if (iconName) {
|
|
12381
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Tooltip2, { content: label, side: "top", children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12382
|
+
"button",
|
|
12383
|
+
{
|
|
12384
|
+
type: "button",
|
|
12385
|
+
"data-slot": "chat-message-action",
|
|
12386
|
+
"data-action": action.name,
|
|
12387
|
+
"aria-label": label,
|
|
12388
|
+
className: "flex cursor-pointer items-center rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12389
|
+
onClick: () => onAction?.(action.name),
|
|
12390
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(Icon, { name: iconName, size: "sm" })
|
|
12391
|
+
}
|
|
12392
|
+
) }, action.name);
|
|
12393
|
+
}
|
|
12394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime178.jsx)(
|
|
12395
|
+
"button",
|
|
12396
|
+
{
|
|
12397
|
+
type: "button",
|
|
12398
|
+
"data-slot": "chat-message-action",
|
|
12399
|
+
"data-action": action.name,
|
|
12400
|
+
className: "flex items-center cursor-pointer gap-1 rounded-sm px-1.5 py-0.5 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12401
|
+
onClick: () => onAction?.(action.name),
|
|
12402
|
+
children: label
|
|
12403
|
+
},
|
|
12404
|
+
action.name
|
|
12405
|
+
);
|
|
12406
|
+
}) }) : null
|
|
12315
12407
|
]
|
|
12316
12408
|
}
|
|
12317
12409
|
);
|
|
12318
12410
|
}
|
|
12319
12411
|
|
|
12320
12412
|
// src/components/chat/ChatPage/index.tsx
|
|
12321
|
-
var
|
|
12413
|
+
var import_runtime26 = require("@pactor-app/runtime");
|
|
12414
|
+
var import_react67 = require("react");
|
|
12322
12415
|
|
|
12323
12416
|
// src/components/chat/Composer/index.tsx
|
|
12417
|
+
var import_react64 = require("react");
|
|
12418
|
+
|
|
12419
|
+
// src/components/chat/Composer/mention-input.tsx
|
|
12420
|
+
var import_react63 = require("react");
|
|
12421
|
+
var import_server = require("react-dom/server");
|
|
12324
12422
|
var import_jsx_runtime179 = require("react/jsx-runtime");
|
|
12423
|
+
var NBSP = "\xA0";
|
|
12424
|
+
var CHIP_ATTR = "data-mention-chip";
|
|
12425
|
+
function escapeRegExp(text) {
|
|
12426
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12427
|
+
}
|
|
12428
|
+
function isChipElement(node) {
|
|
12429
|
+
return node instanceof HTMLElement && node.hasAttribute(CHIP_ATTR);
|
|
12430
|
+
}
|
|
12431
|
+
function serializeNode(node) {
|
|
12432
|
+
let out = "";
|
|
12433
|
+
node.childNodes.forEach((child) => {
|
|
12434
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
12435
|
+
out += (child.textContent ?? "").replace(/\u00A0/g, " ");
|
|
12436
|
+
} else if (isChipElement(child)) {
|
|
12437
|
+
out += `${child.dataset["trigger"] ?? ""}${child.dataset["label"] ?? ""}`;
|
|
12438
|
+
} else if (child instanceof HTMLBRElement) {
|
|
12439
|
+
out += "\n";
|
|
12440
|
+
} else if (child instanceof HTMLElement) {
|
|
12441
|
+
const inner = serializeNode(child).replace(/\n$/, "");
|
|
12442
|
+
out += (out === "" || out.endsWith("\n") ? "" : "\n") + inner + "\n";
|
|
12443
|
+
}
|
|
12444
|
+
});
|
|
12445
|
+
return out;
|
|
12446
|
+
}
|
|
12447
|
+
function collectChips(field) {
|
|
12448
|
+
return Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).map((el) => ({
|
|
12449
|
+
id: el.dataset["id"] ?? "",
|
|
12450
|
+
label: el.dataset["label"] ?? "",
|
|
12451
|
+
trigger: el.dataset["trigger"] ?? ""
|
|
12452
|
+
}));
|
|
12453
|
+
}
|
|
12454
|
+
function detectActiveMention(field, sources) {
|
|
12455
|
+
const selection = window.getSelection();
|
|
12456
|
+
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
|
|
12457
|
+
return null;
|
|
12458
|
+
}
|
|
12459
|
+
const anchor = selection.anchorNode;
|
|
12460
|
+
if (!anchor || anchor.nodeType !== Node.TEXT_NODE || !field.contains(anchor)) {
|
|
12461
|
+
return null;
|
|
12462
|
+
}
|
|
12463
|
+
const caretOffset = selection.anchorOffset;
|
|
12464
|
+
const beforeCaret = (anchor.textContent ?? "").slice(0, caretOffset);
|
|
12465
|
+
for (const source of sources) {
|
|
12466
|
+
const trigger = source.trigger;
|
|
12467
|
+
const match = new RegExp(
|
|
12468
|
+
`(?:^|\\s)${escapeRegExp(trigger)}([^\\s${escapeRegExp(trigger)}]*)$`
|
|
12469
|
+
).exec(beforeCaret);
|
|
12470
|
+
if (match) {
|
|
12471
|
+
const query = match[1] ?? "";
|
|
12472
|
+
return {
|
|
12473
|
+
source,
|
|
12474
|
+
query,
|
|
12475
|
+
node: anchor,
|
|
12476
|
+
triggerStart: caretOffset - query.length - trigger.length,
|
|
12477
|
+
caretOffset
|
|
12478
|
+
};
|
|
12479
|
+
}
|
|
12480
|
+
}
|
|
12481
|
+
return null;
|
|
12482
|
+
}
|
|
12483
|
+
function chipIcon(item, source) {
|
|
12484
|
+
return item.icon ?? source.icon ?? (source.trigger === "@" ? "user" : "file-text");
|
|
12485
|
+
}
|
|
12486
|
+
var MentionInput = (0, import_react63.forwardRef)(
|
|
12487
|
+
function MentionInput2({
|
|
12488
|
+
value,
|
|
12489
|
+
placeholder,
|
|
12490
|
+
disabled,
|
|
12491
|
+
sources,
|
|
12492
|
+
chips,
|
|
12493
|
+
onChipsChange,
|
|
12494
|
+
onChange,
|
|
12495
|
+
onSubmit,
|
|
12496
|
+
className,
|
|
12497
|
+
style
|
|
12498
|
+
}, ref) {
|
|
12499
|
+
const fieldRef = (0, import_react63.useRef)(null);
|
|
12500
|
+
const [menu, setMenu] = (0, import_react63.useState)(null);
|
|
12501
|
+
const [empty, setEmpty] = (0, import_react63.useState)(true);
|
|
12502
|
+
const suppressSyncRef = (0, import_react63.useRef)(false);
|
|
12503
|
+
const composingRef = (0, import_react63.useRef)(false);
|
|
12504
|
+
const emitChips = () => {
|
|
12505
|
+
if (suppressSyncRef.current || !fieldRef.current) {
|
|
12506
|
+
return;
|
|
12507
|
+
}
|
|
12508
|
+
onChipsChange?.(collectChips(fieldRef.current));
|
|
12509
|
+
};
|
|
12510
|
+
const serialize = () => fieldRef.current ? serializeNode(fieldRef.current).replace(/\n$/, "") : "";
|
|
12511
|
+
const buildChipElement = (item, source) => {
|
|
12512
|
+
const chip = document.createElement("span");
|
|
12513
|
+
chip.setAttribute(CHIP_ATTR, "");
|
|
12514
|
+
chip.dataset["id"] = item.id;
|
|
12515
|
+
chip.dataset["label"] = item.label;
|
|
12516
|
+
chip.dataset["trigger"] = item.trigger ?? source.trigger;
|
|
12517
|
+
chip.contentEditable = "false";
|
|
12518
|
+
chip.className = "mx-0.5 inline-flex items-center gap-1 rounded-md bg-muted px-1.5 py-0.5 align-middle text-xs text-foreground";
|
|
12519
|
+
const iconMarkup = (0, import_server.renderToStaticMarkup)(
|
|
12520
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, source), size: 12 })
|
|
12521
|
+
);
|
|
12522
|
+
const label = document.createElement("span");
|
|
12523
|
+
label.textContent = item.label;
|
|
12524
|
+
chip.innerHTML = iconMarkup;
|
|
12525
|
+
chip.appendChild(label);
|
|
12526
|
+
return chip;
|
|
12527
|
+
};
|
|
12528
|
+
const insertChipElement = (item, source, replace) => {
|
|
12529
|
+
const field = fieldRef.current;
|
|
12530
|
+
if (!field) {
|
|
12531
|
+
return;
|
|
12532
|
+
}
|
|
12533
|
+
const chip = buildChipElement(item, source);
|
|
12534
|
+
let caretNode;
|
|
12535
|
+
if (replace) {
|
|
12536
|
+
const { node, start, end } = replace;
|
|
12537
|
+
const text = node.textContent ?? "";
|
|
12538
|
+
node.textContent = text.slice(0, start);
|
|
12539
|
+
caretNode = document.createTextNode(`${NBSP}${text.slice(end)}`);
|
|
12540
|
+
node.after(chip, caretNode);
|
|
12541
|
+
} else {
|
|
12542
|
+
caretNode = document.createTextNode(NBSP);
|
|
12543
|
+
const selection2 = window.getSelection();
|
|
12544
|
+
if (selection2 && selection2.rangeCount > 0 && selection2.anchorNode !== null && field.contains(selection2.anchorNode)) {
|
|
12545
|
+
const range = selection2.getRangeAt(0);
|
|
12546
|
+
range.deleteContents();
|
|
12547
|
+
range.insertNode(caretNode);
|
|
12548
|
+
range.insertNode(chip);
|
|
12549
|
+
} else {
|
|
12550
|
+
field.append(chip, caretNode);
|
|
12551
|
+
}
|
|
12552
|
+
}
|
|
12553
|
+
const selection = window.getSelection();
|
|
12554
|
+
if (selection) {
|
|
12555
|
+
const range = document.createRange();
|
|
12556
|
+
range.setStart(caretNode, 1);
|
|
12557
|
+
range.collapse(true);
|
|
12558
|
+
selection.removeAllRanges();
|
|
12559
|
+
selection.addRange(range);
|
|
12560
|
+
}
|
|
12561
|
+
setEmpty(false);
|
|
12562
|
+
onChange?.(serialize());
|
|
12563
|
+
emitChips();
|
|
12564
|
+
};
|
|
12565
|
+
(0, import_react63.useImperativeHandle)(ref, () => ({
|
|
12566
|
+
insertChip: (item, source) => {
|
|
12567
|
+
fieldRef.current?.focus();
|
|
12568
|
+
insertChipElement(item, source);
|
|
12569
|
+
},
|
|
12570
|
+
focus: () => fieldRef.current?.focus()
|
|
12571
|
+
}));
|
|
12572
|
+
(0, import_react63.useEffect)(() => {
|
|
12573
|
+
const field = fieldRef.current;
|
|
12574
|
+
if (field && value === "" && serializeNode(field).trim() !== "") {
|
|
12575
|
+
suppressSyncRef.current = true;
|
|
12576
|
+
field.innerHTML = "";
|
|
12577
|
+
setEmpty(true);
|
|
12578
|
+
setMenu(null);
|
|
12579
|
+
suppressSyncRef.current = false;
|
|
12580
|
+
}
|
|
12581
|
+
}, [value]);
|
|
12582
|
+
(0, import_react63.useEffect)(() => {
|
|
12583
|
+
const field = fieldRef.current;
|
|
12584
|
+
if (!field) {
|
|
12585
|
+
return;
|
|
12586
|
+
}
|
|
12587
|
+
const keep = new Set(chips.map((chip) => `${chip.trigger}:${chip.id}`));
|
|
12588
|
+
const stale = Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).filter(
|
|
12589
|
+
(el) => !keep.has(
|
|
12590
|
+
`${el.dataset["trigger"]}:${el.dataset["id"]}`
|
|
12591
|
+
)
|
|
12592
|
+
);
|
|
12593
|
+
if (stale.length > 0) {
|
|
12594
|
+
suppressSyncRef.current = true;
|
|
12595
|
+
stale.forEach((el) => el.remove());
|
|
12596
|
+
suppressSyncRef.current = false;
|
|
12597
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12598
|
+
}
|
|
12599
|
+
}, [chips]);
|
|
12600
|
+
const closeMenu = () => setMenu(null);
|
|
12601
|
+
const filteredItems = (state) => state.query ? state.source.items.filter((item) => item.label.includes(state.query)) : state.source.items;
|
|
12602
|
+
const refreshMenu = () => {
|
|
12603
|
+
const field = fieldRef.current;
|
|
12604
|
+
if (!field) {
|
|
12605
|
+
return;
|
|
12606
|
+
}
|
|
12607
|
+
const active = detectActiveMention(field, sources);
|
|
12608
|
+
if (!active) {
|
|
12609
|
+
setMenu(null);
|
|
12610
|
+
return;
|
|
12611
|
+
}
|
|
12612
|
+
const range = document.createRange();
|
|
12613
|
+
range.setStart(active.node, active.triggerStart);
|
|
12614
|
+
range.setEnd(active.node, active.caretOffset);
|
|
12615
|
+
const rect = typeof range.getBoundingClientRect === "function" ? range.getBoundingClientRect() : field.getBoundingClientRect();
|
|
12616
|
+
setMenu((prev) => ({
|
|
12617
|
+
source: active.source,
|
|
12618
|
+
query: active.query,
|
|
12619
|
+
left: rect.left,
|
|
12620
|
+
top: rect.top,
|
|
12621
|
+
// 过滤结果变化后候选下标钳制在有效范围内(DSL 每次渲染产出新
|
|
12622
|
+
// props 对象,source 按 trigger 比较而非引用)
|
|
12623
|
+
activeIndex: Math.min(
|
|
12624
|
+
prev?.source.trigger === active.source.trigger ? prev.activeIndex : 0,
|
|
12625
|
+
Math.max(filteredItems({ source: active.source, query: active.query, left: 0, top: 0, activeIndex: 0 }).length - 1, 0)
|
|
12626
|
+
)
|
|
12627
|
+
}));
|
|
12628
|
+
};
|
|
12629
|
+
const selectMenuItem = (item) => {
|
|
12630
|
+
const field = fieldRef.current;
|
|
12631
|
+
if (!field || !menu) {
|
|
12632
|
+
return;
|
|
12633
|
+
}
|
|
12634
|
+
const active = detectActiveMention(field, sources);
|
|
12635
|
+
insertChipElement(
|
|
12636
|
+
{ ...item, trigger: item.trigger ?? menu.source.trigger },
|
|
12637
|
+
menu.source,
|
|
12638
|
+
active && active.source.trigger === menu.source.trigger ? { node: active.node, start: active.triggerStart, end: active.caretOffset } : void 0
|
|
12639
|
+
);
|
|
12640
|
+
setMenu(null);
|
|
12641
|
+
};
|
|
12642
|
+
const handleInput = () => {
|
|
12643
|
+
const field = fieldRef.current;
|
|
12644
|
+
if (!field) {
|
|
12645
|
+
return;
|
|
12646
|
+
}
|
|
12647
|
+
if ((field.textContent ?? "") === "" && field.querySelector(`[${CHIP_ATTR}]`) === null) {
|
|
12648
|
+
field.innerHTML = "";
|
|
12649
|
+
}
|
|
12650
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12651
|
+
onChange?.(serialize());
|
|
12652
|
+
refreshMenu();
|
|
12653
|
+
};
|
|
12654
|
+
const handleKeyDown = (event) => {
|
|
12655
|
+
if (menu) {
|
|
12656
|
+
const items = filteredItems(menu);
|
|
12657
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
12658
|
+
event.preventDefault();
|
|
12659
|
+
if (items.length > 0) {
|
|
12660
|
+
const delta = event.key === "ArrowDown" ? 1 : -1;
|
|
12661
|
+
setMenu({
|
|
12662
|
+
...menu,
|
|
12663
|
+
activeIndex: (menu.activeIndex + delta + items.length) % items.length
|
|
12664
|
+
});
|
|
12665
|
+
}
|
|
12666
|
+
return;
|
|
12667
|
+
}
|
|
12668
|
+
if (event.key === "Enter" && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
12669
|
+
event.preventDefault();
|
|
12670
|
+
const item = items[Math.min(menu.activeIndex, items.length - 1)];
|
|
12671
|
+
if (item) {
|
|
12672
|
+
selectMenuItem(item);
|
|
12673
|
+
} else {
|
|
12674
|
+
closeMenu();
|
|
12675
|
+
}
|
|
12676
|
+
return;
|
|
12677
|
+
}
|
|
12678
|
+
if (event.key === "Escape") {
|
|
12679
|
+
event.preventDefault();
|
|
12680
|
+
closeMenu();
|
|
12681
|
+
return;
|
|
12682
|
+
}
|
|
12683
|
+
}
|
|
12684
|
+
if (event.key === "Enter" && !event.shiftKey && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
12685
|
+
event.preventDefault();
|
|
12686
|
+
const text = serialize();
|
|
12687
|
+
if (text.trim() !== "" && !disabled) {
|
|
12688
|
+
onSubmit?.(text);
|
|
12689
|
+
}
|
|
12690
|
+
return;
|
|
12691
|
+
}
|
|
12692
|
+
if (event.key === "Backspace") {
|
|
12693
|
+
const selection = window.getSelection();
|
|
12694
|
+
const field = fieldRef.current;
|
|
12695
|
+
if (!selection || !selection.isCollapsed || !field) {
|
|
12696
|
+
return;
|
|
12697
|
+
}
|
|
12698
|
+
let chip = null;
|
|
12699
|
+
const anchor = selection.anchorNode;
|
|
12700
|
+
if (anchor === field && selection.anchorOffset > 0) {
|
|
12701
|
+
const before = field.childNodes[selection.anchorOffset - 1];
|
|
12702
|
+
if (isChipElement(before)) {
|
|
12703
|
+
chip = before;
|
|
12704
|
+
}
|
|
12705
|
+
} else if (anchor?.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
|
|
12706
|
+
if (isChipElement(anchor.previousSibling)) {
|
|
12707
|
+
chip = anchor.previousSibling;
|
|
12708
|
+
}
|
|
12709
|
+
}
|
|
12710
|
+
if (chip) {
|
|
12711
|
+
event.preventDefault();
|
|
12712
|
+
chip.remove();
|
|
12713
|
+
onChange?.(serialize());
|
|
12714
|
+
emitChips();
|
|
12715
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
12716
|
+
}
|
|
12717
|
+
}
|
|
12718
|
+
};
|
|
12719
|
+
const menuItems = menu ? filteredItems(menu) : [];
|
|
12720
|
+
const activeIndex = Math.min(menu?.activeIndex ?? 0, Math.max(menuItems.length - 1, 0));
|
|
12721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)("div", { className: "relative", children: [
|
|
12722
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
|
|
12723
|
+
"div",
|
|
12724
|
+
{
|
|
12725
|
+
ref: fieldRef,
|
|
12726
|
+
"data-slot": "mention-input",
|
|
12727
|
+
role: "textbox",
|
|
12728
|
+
"aria-multiline": "true",
|
|
12729
|
+
"aria-placeholder": placeholder,
|
|
12730
|
+
contentEditable: !disabled,
|
|
12731
|
+
suppressContentEditableWarning: true,
|
|
12732
|
+
className: cn(
|
|
12733
|
+
"min-h-[60px] w-full px-4 pt-3 pb-1 text-sm whitespace-pre-wrap break-words outline-none",
|
|
12734
|
+
className
|
|
12735
|
+
),
|
|
12736
|
+
style,
|
|
12737
|
+
onInput: handleInput,
|
|
12738
|
+
onKeyDown: handleKeyDown,
|
|
12739
|
+
onCompositionStart: () => {
|
|
12740
|
+
composingRef.current = true;
|
|
12741
|
+
},
|
|
12742
|
+
onCompositionEnd: () => {
|
|
12743
|
+
composingRef.current = false;
|
|
12744
|
+
},
|
|
12745
|
+
onPaste: (event) => {
|
|
12746
|
+
event.preventDefault();
|
|
12747
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
12748
|
+
if (text) {
|
|
12749
|
+
document.execCommand("insertText", false, text);
|
|
12750
|
+
}
|
|
12751
|
+
}
|
|
12752
|
+
}
|
|
12753
|
+
),
|
|
12754
|
+
empty && placeholder !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("span", { className: "pointer-events-none absolute top-3 left-4 text-sm text-muted-foreground", children: placeholder }) : null,
|
|
12755
|
+
menu ? /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(import_jsx_runtime179.Fragment, { children: [
|
|
12756
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(
|
|
12757
|
+
"div",
|
|
12758
|
+
{
|
|
12759
|
+
className: "fixed inset-0 z-40",
|
|
12760
|
+
onMouseDown: (event) => {
|
|
12761
|
+
event.preventDefault();
|
|
12762
|
+
closeMenu();
|
|
12763
|
+
}
|
|
12764
|
+
}
|
|
12765
|
+
),
|
|
12766
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(
|
|
12767
|
+
"div",
|
|
12768
|
+
{
|
|
12769
|
+
"data-slot": "mention-menu",
|
|
12770
|
+
role: "listbox",
|
|
12771
|
+
className: "scrollbar-subtle fixed z-50 max-h-72 w-64 overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
|
|
12772
|
+
style: {
|
|
12773
|
+
left: menu.left,
|
|
12774
|
+
bottom: typeof window === "undefined" ? void 0 : window.innerHeight - menu.top + 6
|
|
12775
|
+
},
|
|
12776
|
+
children: [
|
|
12777
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: menu.source.label }),
|
|
12778
|
+
menuItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime179.jsx)("div", { className: "px-2 py-2 text-xs text-muted-foreground", children: "\u65E0\u5339\u914D\u9879" }) : menuItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime179.jsxs)(
|
|
12779
|
+
"button",
|
|
12780
|
+
{
|
|
12781
|
+
type: "button",
|
|
12782
|
+
role: "option",
|
|
12783
|
+
"aria-selected": index === activeIndex,
|
|
12784
|
+
className: cn(
|
|
12785
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm",
|
|
12786
|
+
index === activeIndex ? "bg-accent" : "hover:bg-accent"
|
|
12787
|
+
),
|
|
12788
|
+
onMouseDown: (event) => {
|
|
12789
|
+
event.preventDefault();
|
|
12790
|
+
selectMenuItem(item);
|
|
12791
|
+
},
|
|
12792
|
+
children: [
|
|
12793
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)(Icon, { name: chipIcon(item, menu.source), size: "sm" }),
|
|
12794
|
+
/* @__PURE__ */ (0, import_jsx_runtime179.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
12795
|
+
]
|
|
12796
|
+
},
|
|
12797
|
+
item.id
|
|
12798
|
+
))
|
|
12799
|
+
]
|
|
12800
|
+
}
|
|
12801
|
+
)
|
|
12802
|
+
] }) : null
|
|
12803
|
+
] });
|
|
12804
|
+
}
|
|
12805
|
+
);
|
|
12806
|
+
|
|
12807
|
+
// src/components/chat/Composer/index.tsx
|
|
12808
|
+
var import_jsx_runtime180 = require("react/jsx-runtime");
|
|
12809
|
+
var toolButtonClass3 = "flex cursor-pointer items-center rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground";
|
|
12810
|
+
var popoverPanelClass = "absolute bottom-full left-0 z-50 mb-2 max-h-72 w-64 overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md";
|
|
12811
|
+
var popoverItemClass = "flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm hover:bg-accent";
|
|
12325
12812
|
function Composer({
|
|
12326
12813
|
value,
|
|
12327
12814
|
placeholder,
|
|
@@ -12331,35 +12818,238 @@ function Composer({
|
|
|
12331
12818
|
attachments = [],
|
|
12332
12819
|
onRemoveAttachment,
|
|
12333
12820
|
onRetryAttachment,
|
|
12821
|
+
onAttachFiles,
|
|
12334
12822
|
onChange,
|
|
12335
12823
|
onSubmit,
|
|
12824
|
+
models,
|
|
12825
|
+
model,
|
|
12826
|
+
onModelChange,
|
|
12827
|
+
contexts,
|
|
12828
|
+
contextItems,
|
|
12829
|
+
onContextItemsChange,
|
|
12830
|
+
footer,
|
|
12336
12831
|
className,
|
|
12337
12832
|
style
|
|
12338
12833
|
}) {
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12834
|
+
const textControlled = value !== void 0;
|
|
12835
|
+
const [innerText, setInnerText] = (0, import_react64.useState)("");
|
|
12836
|
+
const text = textControlled ? value : innerText;
|
|
12837
|
+
const [dragOver, setDragOver] = (0, import_react64.useState)(false);
|
|
12838
|
+
const [plusOpen, setPlusOpen] = (0, import_react64.useState)(false);
|
|
12839
|
+
const [modelOpen, setModelOpen] = (0, import_react64.useState)(false);
|
|
12840
|
+
const fileInputRef = (0, import_react64.useRef)(null);
|
|
12841
|
+
const mentionRef = (0, import_react64.useRef)(null);
|
|
12842
|
+
const sources = contexts ?? [];
|
|
12843
|
+
const rich = sources.length > 0;
|
|
12844
|
+
const plusSources = sources.filter((s) => s.trigger === "+");
|
|
12845
|
+
const plusEnabled = plusSources.length > 0;
|
|
12846
|
+
const modelEnabled = models !== void 0 && models.length > 0;
|
|
12847
|
+
const currentModel = models?.find((m) => m.value === model) ?? models?.[0];
|
|
12848
|
+
const chips = contextItems ?? [];
|
|
12849
|
+
const closePopovers = () => {
|
|
12850
|
+
setPlusOpen(false);
|
|
12851
|
+
setModelOpen(false);
|
|
12852
|
+
};
|
|
12853
|
+
const handleChange = (next) => {
|
|
12854
|
+
if (!textControlled) {
|
|
12855
|
+
setInnerText(next);
|
|
12856
|
+
}
|
|
12857
|
+
onChange?.(next);
|
|
12858
|
+
};
|
|
12859
|
+
const handleSubmit = (submitted) => {
|
|
12860
|
+
onSubmit?.(submitted);
|
|
12861
|
+
if (!textControlled) {
|
|
12862
|
+
setInnerText("");
|
|
12863
|
+
}
|
|
12864
|
+
closePopovers();
|
|
12865
|
+
};
|
|
12866
|
+
const selectContext = (item, source) => {
|
|
12867
|
+
if (rich) {
|
|
12868
|
+
mentionRef.current?.insertChip(item, source);
|
|
12869
|
+
} else {
|
|
12870
|
+
const chip = { ...item, trigger: item.trigger ?? source.trigger };
|
|
12871
|
+
const duplicated = chips.some(
|
|
12872
|
+
(existing) => existing.id === chip.id && existing.trigger === chip.trigger
|
|
12873
|
+
);
|
|
12874
|
+
if (!duplicated) {
|
|
12875
|
+
onContextItemsChange?.([...chips, chip]);
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
closePopovers();
|
|
12879
|
+
};
|
|
12880
|
+
const emitFiles = (files) => {
|
|
12881
|
+
if (files.length > 0 && onAttachFiles) {
|
|
12882
|
+
onAttachFiles(files);
|
|
12883
|
+
}
|
|
12884
|
+
};
|
|
12885
|
+
const handleDrop = (event) => {
|
|
12886
|
+
if (!onAttachFiles) {
|
|
12887
|
+
return;
|
|
12888
|
+
}
|
|
12889
|
+
event.preventDefault();
|
|
12890
|
+
setDragOver(false);
|
|
12891
|
+
emitFiles(Array.from(event.dataTransfer?.files ?? []));
|
|
12892
|
+
};
|
|
12893
|
+
const toolbarStart = plusEnabled || onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
|
|
12894
|
+
plusEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12895
|
+
"button",
|
|
12343
12896
|
{
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12897
|
+
type: "button",
|
|
12898
|
+
"aria-label": "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
12899
|
+
title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
12900
|
+
className: toolButtonClass3,
|
|
12901
|
+
onClick: () => {
|
|
12902
|
+
setPlusOpen((prev) => !prev);
|
|
12903
|
+
setModelOpen(false);
|
|
12904
|
+
},
|
|
12905
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "plus", size: "sm" })
|
|
12350
12906
|
}
|
|
12351
|
-
)
|
|
12352
|
-
|
|
12907
|
+
) : null,
|
|
12908
|
+
onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12909
|
+
"button",
|
|
12910
|
+
{
|
|
12911
|
+
type: "button",
|
|
12912
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
12913
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
12914
|
+
className: toolButtonClass3,
|
|
12915
|
+
onClick: () => fileInputRef.current?.click(),
|
|
12916
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "paperclip", size: "sm" })
|
|
12917
|
+
}
|
|
12918
|
+
) : null
|
|
12919
|
+
] }) : void 0;
|
|
12920
|
+
const toolbarEnd = modelEnabled ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
12921
|
+
"button",
|
|
12922
|
+
{
|
|
12923
|
+
type: "button",
|
|
12924
|
+
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
12925
|
+
title: "\u9009\u62E9\u6A21\u578B",
|
|
12926
|
+
className: "flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
12927
|
+
onClick: () => {
|
|
12928
|
+
setModelOpen((prev) => !prev);
|
|
12929
|
+
setPlusOpen(false);
|
|
12930
|
+
},
|
|
12931
|
+
children: [
|
|
12932
|
+
currentModel?.label,
|
|
12933
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "chevrons-up-down", size: 12 })
|
|
12934
|
+
]
|
|
12935
|
+
}
|
|
12936
|
+
) : void 0;
|
|
12937
|
+
const activePopover = plusOpen ? "plus" : modelOpen ? "model" : null;
|
|
12938
|
+
return /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
12939
|
+
"div",
|
|
12940
|
+
{
|
|
12941
|
+
"data-slot": "composer",
|
|
12942
|
+
className: cn("relative flex w-full flex-col gap-2", className),
|
|
12943
|
+
style,
|
|
12944
|
+
onDragOver: (event) => {
|
|
12945
|
+
if (onAttachFiles) {
|
|
12946
|
+
event.preventDefault();
|
|
12947
|
+
setDragOver(true);
|
|
12948
|
+
}
|
|
12949
|
+
},
|
|
12950
|
+
onDragLeave: () => setDragOver(false),
|
|
12951
|
+
onDrop: handleDrop,
|
|
12952
|
+
onPaste: (event) => {
|
|
12953
|
+
const files = Array.from(event.clipboardData?.files ?? []);
|
|
12954
|
+
if (files.length > 0 && onAttachFiles) {
|
|
12955
|
+
event.preventDefault();
|
|
12956
|
+
emitFiles(files);
|
|
12957
|
+
}
|
|
12958
|
+
},
|
|
12959
|
+
children: [
|
|
12960
|
+
attachments.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
|
|
12961
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: cn(dragOver && "rounded-xl ring-2 ring-ring/50"), children: /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12962
|
+
ChatInput,
|
|
12963
|
+
{
|
|
12964
|
+
value: text,
|
|
12965
|
+
placeholder,
|
|
12966
|
+
disabled: disabled || loading,
|
|
12967
|
+
rows,
|
|
12968
|
+
toolbarStart,
|
|
12969
|
+
toolbarEnd,
|
|
12970
|
+
footer,
|
|
12971
|
+
field: rich ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12972
|
+
MentionInput,
|
|
12973
|
+
{
|
|
12974
|
+
ref: mentionRef,
|
|
12975
|
+
value: text,
|
|
12976
|
+
placeholder,
|
|
12977
|
+
disabled: disabled || loading,
|
|
12978
|
+
sources,
|
|
12979
|
+
chips,
|
|
12980
|
+
onChipsChange: onContextItemsChange,
|
|
12981
|
+
onChange: handleChange,
|
|
12982
|
+
onSubmit: handleSubmit
|
|
12983
|
+
}
|
|
12984
|
+
) : void 0,
|
|
12985
|
+
onChange: handleChange,
|
|
12986
|
+
onSubmit: handleSubmit
|
|
12987
|
+
}
|
|
12988
|
+
) }),
|
|
12989
|
+
onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(
|
|
12990
|
+
"input",
|
|
12991
|
+
{
|
|
12992
|
+
ref: fileInputRef,
|
|
12993
|
+
type: "file",
|
|
12994
|
+
multiple: true,
|
|
12995
|
+
hidden: true,
|
|
12996
|
+
onChange: (event) => {
|
|
12997
|
+
emitFiles(Array.from(event.target.files ?? []));
|
|
12998
|
+
event.target.value = "";
|
|
12999
|
+
}
|
|
13000
|
+
}
|
|
13001
|
+
) : null,
|
|
13002
|
+
activePopover !== null ? /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(import_jsx_runtime180.Fragment, { children: [
|
|
13003
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "fixed inset-0 z-40", onClick: closePopovers }),
|
|
13004
|
+
activePopover === "model" ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { "data-slot": "composer-model-popover", className: cn(popoverPanelClass, "right-0 left-auto w-48"), role: "listbox", children: models.map((option) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
13005
|
+
"button",
|
|
13006
|
+
{
|
|
13007
|
+
type: "button",
|
|
13008
|
+
role: "option",
|
|
13009
|
+
"aria-selected": option.value === currentModel?.value,
|
|
13010
|
+
className: popoverItemClass,
|
|
13011
|
+
onClick: () => {
|
|
13012
|
+
onModelChange?.(option.value);
|
|
13013
|
+
closePopovers();
|
|
13014
|
+
},
|
|
13015
|
+
children: [
|
|
13016
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
13017
|
+
option.value === currentModel?.value ? /* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: "check", size: 14 }) : null
|
|
13018
|
+
]
|
|
13019
|
+
},
|
|
13020
|
+
option.value
|
|
13021
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { "data-slot": "composer-context-popover", className: popoverPanelClass, role: "listbox", children: plusSources.map(
|
|
13022
|
+
(source) => source.items.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)("div", { children: [
|
|
13023
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: source.label }),
|
|
13024
|
+
source.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime180.jsxs)(
|
|
13025
|
+
"button",
|
|
13026
|
+
{
|
|
13027
|
+
type: "button",
|
|
13028
|
+
className: popoverItemClass,
|
|
13029
|
+
onClick: () => selectContext(item, source),
|
|
13030
|
+
children: [
|
|
13031
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)(Icon, { name: item.icon ?? source.icon ?? "file-text", size: "sm" }),
|
|
13032
|
+
/* @__PURE__ */ (0, import_jsx_runtime180.jsx)("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
13033
|
+
]
|
|
13034
|
+
},
|
|
13035
|
+
item.id
|
|
13036
|
+
))
|
|
13037
|
+
] }, source.trigger)
|
|
13038
|
+
) })
|
|
13039
|
+
] }) : null
|
|
13040
|
+
]
|
|
13041
|
+
}
|
|
13042
|
+
);
|
|
12353
13043
|
}
|
|
12354
13044
|
|
|
12355
13045
|
// src/components/chat/ConversationList/index.tsx
|
|
12356
|
-
var
|
|
12357
|
-
var
|
|
13046
|
+
var import_react65 = require("react");
|
|
13047
|
+
var import_jsx_runtime181 = require("react/jsx-runtime");
|
|
12358
13048
|
function ConversationList({ items = [], activeId, searchable, onSelect, onDelete, className, style }) {
|
|
12359
|
-
const [innerActive, setInnerActive] = (0,
|
|
12360
|
-
const [keyword, setKeyword] = (0,
|
|
13049
|
+
const [innerActive, setInnerActive] = (0, import_react65.useState)();
|
|
13050
|
+
const [keyword, setKeyword] = (0, import_react65.useState)("");
|
|
12361
13051
|
const active = activeId ?? innerActive;
|
|
12362
|
-
const filtered = (0,
|
|
13052
|
+
const filtered = (0, import_react65.useMemo)(() => {
|
|
12363
13053
|
const query = keyword.trim().toLowerCase();
|
|
12364
13054
|
if (!query) return items;
|
|
12365
13055
|
return items.filter(
|
|
@@ -12372,10 +13062,10 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12372
13062
|
}
|
|
12373
13063
|
onSelect?.(id);
|
|
12374
13064
|
};
|
|
12375
|
-
return /* @__PURE__ */ (0,
|
|
12376
|
-
searchable ? /* @__PURE__ */ (0,
|
|
12377
|
-
/* @__PURE__ */ (0,
|
|
12378
|
-
/* @__PURE__ */ (0,
|
|
13065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
|
|
13066
|
+
searchable ? /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "relative mb-1", children: [
|
|
13067
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)("span", { className: "absolute top-1/2 left-2 -translate-y-1/2 text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(Icon, { name: "search", size: "sm" }) }),
|
|
13068
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
|
|
12379
13069
|
"input",
|
|
12380
13070
|
{
|
|
12381
13071
|
"data-slot": "conversation-list-search",
|
|
@@ -12386,7 +13076,7 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12386
13076
|
}
|
|
12387
13077
|
)
|
|
12388
13078
|
] }) : null,
|
|
12389
|
-
filtered.map((item) => /* @__PURE__ */ (0,
|
|
13079
|
+
filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime181.jsxs)(
|
|
12390
13080
|
"div",
|
|
12391
13081
|
{
|
|
12392
13082
|
"data-slot": "conversation-list-item",
|
|
@@ -12397,12 +13087,12 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12397
13087
|
),
|
|
12398
13088
|
onClick: () => select(item.id),
|
|
12399
13089
|
children: [
|
|
12400
|
-
/* @__PURE__ */ (0,
|
|
12401
|
-
/* @__PURE__ */ (0,
|
|
12402
|
-
item.description ? /* @__PURE__ */ (0,
|
|
13090
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
13091
|
+
/* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
|
|
13092
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
12403
13093
|
] }),
|
|
12404
|
-
item.time ? /* @__PURE__ */ (0,
|
|
12405
|
-
onDelete ? /* @__PURE__ */ (0,
|
|
13094
|
+
item.time ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
|
|
13095
|
+
onDelete ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(
|
|
12406
13096
|
"button",
|
|
12407
13097
|
{
|
|
12408
13098
|
type: "button",
|
|
@@ -12413,41 +13103,42 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
12413
13103
|
event.stopPropagation();
|
|
12414
13104
|
onDelete(item.id);
|
|
12415
13105
|
},
|
|
12416
|
-
children: /* @__PURE__ */ (0,
|
|
13106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime181.jsx)(Icon, { name: "trash-2", size: "sm" })
|
|
12417
13107
|
}
|
|
12418
13108
|
) : null
|
|
12419
13109
|
]
|
|
12420
13110
|
},
|
|
12421
13111
|
item.id
|
|
12422
13112
|
)),
|
|
12423
|
-
filtered.length === 0 ? /* @__PURE__ */ (0,
|
|
13113
|
+
filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime181.jsx)("div", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: "\u65E0\u5339\u914D\u4F1A\u8BDD" }) : null
|
|
12424
13114
|
] });
|
|
12425
13115
|
}
|
|
12426
13116
|
|
|
12427
13117
|
// src/components/chat/MessageList/index.tsx
|
|
12428
|
-
var
|
|
12429
|
-
var
|
|
12430
|
-
function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
|
|
12431
|
-
const listRef = (0,
|
|
12432
|
-
(0,
|
|
13118
|
+
var import_react66 = require("react");
|
|
13119
|
+
var import_jsx_runtime182 = require("react/jsx-runtime");
|
|
13120
|
+
function MessageList({ messages = [], autoScroll = true, onAction, onOpenArtifacts, className, style }) {
|
|
13121
|
+
const listRef = (0, import_react66.useRef)(null);
|
|
13122
|
+
(0, import_react66.useEffect)(() => {
|
|
12433
13123
|
if (!autoScroll) return;
|
|
12434
13124
|
const el = listRef.current;
|
|
12435
13125
|
if (el) {
|
|
12436
13126
|
el.scrollTop = el.scrollHeight;
|
|
12437
13127
|
}
|
|
12438
13128
|
}, [messages, autoScroll]);
|
|
12439
|
-
return /* @__PURE__ */ (0,
|
|
13129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
|
|
12440
13130
|
"div",
|
|
12441
13131
|
{
|
|
12442
13132
|
ref: listRef,
|
|
12443
13133
|
"data-slot": "message-list",
|
|
12444
13134
|
className: cn("flex w-full flex-col gap-4 overflow-y-auto", className),
|
|
12445
13135
|
style,
|
|
12446
|
-
children: messages.map((message, index) => /* @__PURE__ */ (0,
|
|
13136
|
+
children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime182.jsx)(
|
|
12447
13137
|
ChatMessage,
|
|
12448
13138
|
{
|
|
12449
13139
|
...message,
|
|
12450
|
-
onAction: (action) => onAction?.({ id: message.id, action })
|
|
13140
|
+
onAction: (action) => onAction?.({ id: message.id, action }),
|
|
13141
|
+
onOpenArtifacts: onOpenArtifacts ? () => onOpenArtifacts({ id: message.id }) : void 0
|
|
12451
13142
|
},
|
|
12452
13143
|
message.id ?? index
|
|
12453
13144
|
))
|
|
@@ -12456,9 +13147,9 @@ function MessageList({ messages = [], autoScroll = true, onAction, className, st
|
|
|
12456
13147
|
}
|
|
12457
13148
|
|
|
12458
13149
|
// src/components/chat/Prompt/index.tsx
|
|
12459
|
-
var
|
|
13150
|
+
var import_jsx_runtime183 = require("react/jsx-runtime");
|
|
12460
13151
|
function Prompt({ title, description, icon, value, disabled, onSelect, className, style }) {
|
|
12461
|
-
return /* @__PURE__ */ (0,
|
|
13152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime183.jsxs)(
|
|
12462
13153
|
"button",
|
|
12463
13154
|
{
|
|
12464
13155
|
type: "button",
|
|
@@ -12471,10 +13162,10 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
12471
13162
|
style,
|
|
12472
13163
|
onClick: () => onSelect?.(value ?? title ?? ""),
|
|
12473
13164
|
children: [
|
|
12474
|
-
icon ? /* @__PURE__ */ (0,
|
|
12475
|
-
/* @__PURE__ */ (0,
|
|
12476
|
-
/* @__PURE__ */ (0,
|
|
12477
|
-
description ? /* @__PURE__ */ (0,
|
|
13165
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { className: "mt-0.5 shrink-0 text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime183.jsx)(Icon, { name: icon, size: "sm" }) }) : null,
|
|
13166
|
+
/* @__PURE__ */ (0, import_jsx_runtime183.jsxs)("span", { className: "min-w-0", children: [
|
|
13167
|
+
/* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
|
|
13168
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime183.jsx)("span", { "data-slot": "prompt-description", className: "mt-0.5 block text-xs text-muted-foreground", children: description }) : null
|
|
12478
13169
|
] })
|
|
12479
13170
|
]
|
|
12480
13171
|
}
|
|
@@ -12482,7 +13173,7 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
12482
13173
|
}
|
|
12483
13174
|
|
|
12484
13175
|
// src/components/chat/Welcome/index.tsx
|
|
12485
|
-
var
|
|
13176
|
+
var import_jsx_runtime184 = require("react/jsx-runtime");
|
|
12486
13177
|
function Welcome({
|
|
12487
13178
|
title = "\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F",
|
|
12488
13179
|
description,
|
|
@@ -12492,19 +13183,19 @@ function Welcome({
|
|
|
12492
13183
|
className,
|
|
12493
13184
|
style
|
|
12494
13185
|
}) {
|
|
12495
|
-
return /* @__PURE__ */ (0,
|
|
13186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime184.jsxs)(
|
|
12496
13187
|
"div",
|
|
12497
13188
|
{
|
|
12498
13189
|
"data-slot": "welcome",
|
|
12499
13190
|
className: cn("flex w-full flex-col items-center gap-4 py-10 text-center", className),
|
|
12500
13191
|
style,
|
|
12501
13192
|
children: [
|
|
12502
|
-
/* @__PURE__ */ (0,
|
|
12503
|
-
/* @__PURE__ */ (0,
|
|
12504
|
-
/* @__PURE__ */ (0,
|
|
12505
|
-
description ? /* @__PURE__ */ (0,
|
|
13193
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)("span", { "data-slot": "welcome-icon", className: "text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(Icon, { name: icon, size: "lg" }) }),
|
|
13194
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsxs)("div", { children: [
|
|
13195
|
+
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
|
|
13196
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
12506
13197
|
] }),
|
|
12507
|
-
prompts.length > 0 ? /* @__PURE__ */ (0,
|
|
13198
|
+
prompts.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime184.jsx)("div", { "data-slot": "welcome-prompts", className: "grid w-full max-w-xl grid-cols-1 gap-3 text-left sm:grid-cols-2", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12508
13199
|
Prompt,
|
|
12509
13200
|
{
|
|
12510
13201
|
title: item.title,
|
|
@@ -12521,7 +13212,7 @@ function Welcome({
|
|
|
12521
13212
|
}
|
|
12522
13213
|
|
|
12523
13214
|
// src/components/chat/ChatPage/index.tsx
|
|
12524
|
-
var
|
|
13215
|
+
var import_jsx_runtime185 = require("react/jsx-runtime");
|
|
12525
13216
|
function ChatPage({
|
|
12526
13217
|
brand,
|
|
12527
13218
|
menuItems = [],
|
|
@@ -12547,12 +13238,26 @@ function ChatPage({
|
|
|
12547
13238
|
defaultFooterSectionCollapsed = false,
|
|
12548
13239
|
onFooterSectionToggle,
|
|
12549
13240
|
conversationTitle,
|
|
13241
|
+
conversationHeaderAction,
|
|
13242
|
+
onConversationHeaderAction,
|
|
12550
13243
|
messages = [],
|
|
12551
13244
|
sending,
|
|
12552
13245
|
composerPlaceholder,
|
|
12553
13246
|
welcome,
|
|
12554
13247
|
onSend,
|
|
12555
13248
|
onMessageAction,
|
|
13249
|
+
models,
|
|
13250
|
+
model,
|
|
13251
|
+
onModelChange,
|
|
13252
|
+
contexts,
|
|
13253
|
+
contextItems,
|
|
13254
|
+
onContextItemsChange,
|
|
13255
|
+
attachments,
|
|
13256
|
+
onAttachFiles,
|
|
13257
|
+
onRemoveAttachment,
|
|
13258
|
+
onRetryAttachment,
|
|
13259
|
+
composerFooter,
|
|
13260
|
+
composerBottom,
|
|
12556
13261
|
artifactTitle = "\u4EA7\u7269",
|
|
12557
13262
|
artifacts = [],
|
|
12558
13263
|
activeArtifactId,
|
|
@@ -12563,20 +13268,22 @@ function ChatPage({
|
|
|
12563
13268
|
artifactViewers,
|
|
12564
13269
|
onDownloadArtifact,
|
|
12565
13270
|
artifactOpen,
|
|
12566
|
-
defaultArtifactOpen =
|
|
13271
|
+
defaultArtifactOpen = false,
|
|
12567
13272
|
onArtifactOpenChange,
|
|
12568
13273
|
className,
|
|
12569
13274
|
style
|
|
12570
13275
|
}) {
|
|
12571
13276
|
const controlled = artifactOpen !== void 0;
|
|
12572
|
-
const [innerOpen, setInnerOpen] = (0,
|
|
13277
|
+
const [innerOpen, setInnerOpen] = (0, import_react67.useState)(defaultArtifactOpen);
|
|
12573
13278
|
const open = controlled ? artifactOpen === true : innerOpen;
|
|
12574
13279
|
const setOpen = (next) => {
|
|
12575
13280
|
if (!controlled) setInnerOpen(next);
|
|
12576
13281
|
onArtifactOpenChange?.(next);
|
|
12577
13282
|
};
|
|
13283
|
+
const { renderChildren } = (0, import_runtime26.useRenderer)();
|
|
13284
|
+
const renderSlot = (slot) => (0, import_react67.isValidElement)(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
12578
13285
|
const convCollControlled = conversationSectionCollapsed !== void 0;
|
|
12579
|
-
const [convCollapsedInner, setConvCollapsedInner] = (0,
|
|
13286
|
+
const [convCollapsedInner, setConvCollapsedInner] = (0, import_react67.useState)(
|
|
12580
13287
|
defaultConversationSectionCollapsed
|
|
12581
13288
|
);
|
|
12582
13289
|
const convCollapsed = convCollControlled ? conversationSectionCollapsed === true : convCollapsedInner;
|
|
@@ -12586,7 +13293,7 @@ function ChatPage({
|
|
|
12586
13293
|
onConversationSectionToggle?.(next);
|
|
12587
13294
|
};
|
|
12588
13295
|
const footerCollControlled = footerSectionCollapsed !== void 0;
|
|
12589
|
-
const [footerCollapsedInner, setFooterCollapsedInner] = (0,
|
|
13296
|
+
const [footerCollapsedInner, setFooterCollapsedInner] = (0, import_react67.useState)(
|
|
12590
13297
|
defaultFooterSectionCollapsed
|
|
12591
13298
|
);
|
|
12592
13299
|
const footerCollapsed = footerCollControlled ? footerSectionCollapsed === true : footerCollapsedInner;
|
|
@@ -12596,7 +13303,7 @@ function ChatPage({
|
|
|
12596
13303
|
onFooterSectionToggle?.(next);
|
|
12597
13304
|
};
|
|
12598
13305
|
const railVisible = railItems.length > 0 || railFooterItems.length > 0;
|
|
12599
|
-
const railButton = (item) => /* @__PURE__ */ (0,
|
|
13306
|
+
const railButton = (item) => /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12600
13307
|
Button2,
|
|
12601
13308
|
{
|
|
12602
13309
|
icon: item.icon,
|
|
@@ -12604,17 +13311,25 @@ function ChatPage({
|
|
|
12604
13311
|
onClick: () => onMenuSelect?.(item.key)
|
|
12605
13312
|
}
|
|
12606
13313
|
) }, item.key);
|
|
12607
|
-
const chatArea = /* @__PURE__ */ (0,
|
|
12608
|
-
/* @__PURE__ */ (0,
|
|
13314
|
+
const chatArea = /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { "data-slot": "chat-page-conversation", className: "flex h-full min-w-0 flex-1 flex-col", children: [
|
|
13315
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12609
13316
|
"div",
|
|
12610
13317
|
{
|
|
12611
13318
|
className: "flex shrink-0 items-center justify-between border-b border-border px-4 py-2.5",
|
|
12612
13319
|
children: [
|
|
12613
|
-
/* @__PURE__ */ (0,
|
|
12614
|
-
/* @__PURE__ */ (0,
|
|
13320
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: conversationTitle, strong: true }),
|
|
13321
|
+
conversationHeaderAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: conversationHeaderAction.tooltip ?? conversationHeaderAction.label, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13322
|
+
Button2,
|
|
13323
|
+
{
|
|
13324
|
+
text: conversationHeaderAction.label,
|
|
13325
|
+
icon: conversationHeaderAction.icon,
|
|
13326
|
+
variant: "text",
|
|
13327
|
+
onClick: () => onConversationHeaderAction?.()
|
|
13328
|
+
}
|
|
13329
|
+
) }) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Tooltip2, { content: open ? "\u6536\u8D77\u4EA7\u7269\u533A" : artifactTitle, side: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12615
13330
|
Button2,
|
|
12616
13331
|
{
|
|
12617
|
-
icon: "panel-right-open",
|
|
13332
|
+
icon: open ? "panel-right-close" : "panel-right-open",
|
|
12618
13333
|
variant: "text",
|
|
12619
13334
|
onClick: () => setOpen(!open)
|
|
12620
13335
|
}
|
|
@@ -12622,40 +13337,63 @@ function ChatPage({
|
|
|
12622
13337
|
]
|
|
12623
13338
|
}
|
|
12624
13339
|
),
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
{
|
|
12628
|
-
title: welcome?.title,
|
|
12629
|
-
description: welcome?.description,
|
|
12630
|
-
prompts: welcome?.prompts,
|
|
12631
|
-
style: { flex: 1 },
|
|
12632
|
-
onSelect: (value) => onSend?.(value)
|
|
12633
|
-
}
|
|
12634
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12635
|
-
MessageList,
|
|
12636
|
-
{
|
|
12637
|
-
messages,
|
|
12638
|
-
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
12639
|
-
onAction: onMessageAction
|
|
12640
|
-
}
|
|
12641
|
-
),
|
|
12642
|
-
/* @__PURE__ */ (0, import_jsx_runtime184.jsx)(
|
|
12643
|
-
Composer,
|
|
13340
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
13341
|
+
"div",
|
|
12644
13342
|
{
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
13343
|
+
"data-slot": "chat-page-conversation-body",
|
|
13344
|
+
className: "mx-auto flex min-h-0 w-[61.8cqw] max-w-full flex-1 flex-col",
|
|
13345
|
+
children: [
|
|
13346
|
+
messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13347
|
+
Welcome,
|
|
13348
|
+
{
|
|
13349
|
+
title: welcome?.title,
|
|
13350
|
+
description: welcome?.description,
|
|
13351
|
+
prompts: welcome?.prompts,
|
|
13352
|
+
style: { flex: 1 },
|
|
13353
|
+
onSelect: (value) => onSend?.(value)
|
|
13354
|
+
}
|
|
13355
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13356
|
+
MessageList,
|
|
13357
|
+
{
|
|
13358
|
+
messages,
|
|
13359
|
+
className: "scrollbar-subtle",
|
|
13360
|
+
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
13361
|
+
onAction: onMessageAction,
|
|
13362
|
+
onOpenArtifacts: () => setOpen(true)
|
|
13363
|
+
}
|
|
13364
|
+
),
|
|
13365
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13366
|
+
Composer,
|
|
13367
|
+
{
|
|
13368
|
+
placeholder: composerPlaceholder,
|
|
13369
|
+
loading: sending,
|
|
13370
|
+
models,
|
|
13371
|
+
model,
|
|
13372
|
+
contexts,
|
|
13373
|
+
contextItems,
|
|
13374
|
+
attachments,
|
|
13375
|
+
footer: composerFooter,
|
|
13376
|
+
style: { padding: 16, paddingBottom: composerBottom ? 8 : 16, flexShrink: 0 },
|
|
13377
|
+
onModelChange,
|
|
13378
|
+
onContextItemsChange,
|
|
13379
|
+
onAttachFiles,
|
|
13380
|
+
onRemoveAttachment,
|
|
13381
|
+
onRetryAttachment,
|
|
13382
|
+
onSubmit: (text) => onSend?.(text)
|
|
13383
|
+
}
|
|
13384
|
+
),
|
|
13385
|
+
composerBottom ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { "data-slot": "chat-page-composer-bottom", className: "shrink-0 px-4 pb-2 text-center", children: renderSlot(composerBottom) }) : null
|
|
13386
|
+
]
|
|
12649
13387
|
}
|
|
12650
13388
|
)
|
|
12651
13389
|
] });
|
|
12652
13390
|
const activeArtifact = artifacts.find((item) => item.id === activeArtifactId) ?? (activeArtifactId === void 0 || activeArtifactId === "" ? artifacts[artifacts.length - 1] : void 0);
|
|
12653
|
-
const artifactPanel = /* @__PURE__ */ (0,
|
|
13391
|
+
const artifactPanel = /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12654
13392
|
"div",
|
|
12655
13393
|
{
|
|
12656
13394
|
"data-slot": "chat-page-artifact",
|
|
12657
13395
|
className: "flex h-full min-w-0 flex-col border-l border-border bg-muted",
|
|
12658
|
-
children: /* @__PURE__ */ (0,
|
|
13396
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12659
13397
|
ArtifactPanel,
|
|
12660
13398
|
{
|
|
12661
13399
|
artifact: activeArtifact,
|
|
@@ -12673,37 +13411,37 @@ function ChatPage({
|
|
|
12673
13411
|
)
|
|
12674
13412
|
}
|
|
12675
13413
|
);
|
|
12676
|
-
return /* @__PURE__ */ (0,
|
|
13414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12677
13415
|
"div",
|
|
12678
13416
|
{
|
|
12679
13417
|
"data-slot": "chat-page",
|
|
12680
13418
|
className: cn("flex w-full overflow-hidden", className),
|
|
12681
13419
|
style: { height: "100vh", ...style },
|
|
12682
13420
|
children: [
|
|
12683
|
-
railVisible ? /* @__PURE__ */ (0,
|
|
13421
|
+
railVisible ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12684
13422
|
"div",
|
|
12685
13423
|
{
|
|
12686
13424
|
"data-slot": "chat-page-rail",
|
|
12687
13425
|
className: "flex h-full w-[52px] shrink-0 flex-col items-center gap-1 border-r border-border py-2.5",
|
|
12688
13426
|
children: [
|
|
12689
13427
|
railItems.map(railButton),
|
|
12690
|
-
/* @__PURE__ */ (0,
|
|
13428
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "flex-1" }),
|
|
12691
13429
|
railFooterItems.map(railButton)
|
|
12692
13430
|
]
|
|
12693
13431
|
}
|
|
12694
13432
|
) : null,
|
|
12695
|
-
/* @__PURE__ */ (0,
|
|
13433
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12696
13434
|
"div",
|
|
12697
13435
|
{
|
|
12698
13436
|
"data-slot": "chat-page-menu",
|
|
12699
|
-
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-
|
|
13437
|
+
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
|
|
12700
13438
|
children: [
|
|
12701
|
-
brand ? /* @__PURE__ */ (0,
|
|
12702
|
-
/* @__PURE__ */ (0,
|
|
12703
|
-
/* @__PURE__ */ (0,
|
|
12704
|
-
brand.version !== void 0 ? /* @__PURE__ */ (0,
|
|
13439
|
+
brand ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
|
|
13440
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
13441
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.title, strong: true, size: "large" }),
|
|
13442
|
+
brand.version !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: brand.version, type: "secondary", size: "small" }) : null
|
|
12705
13443
|
] }),
|
|
12706
|
-
menuAction ? /* @__PURE__ */ (0,
|
|
13444
|
+
menuAction ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12707
13445
|
Button2,
|
|
12708
13446
|
{
|
|
12709
13447
|
text: menuAction.label,
|
|
@@ -12713,24 +13451,24 @@ function ChatPage({
|
|
|
12713
13451
|
}
|
|
12714
13452
|
) : null
|
|
12715
13453
|
] }) : null,
|
|
12716
|
-
/* @__PURE__ */ (0,
|
|
13454
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "scrollbar-subtle max-h-[40%] min-h-0 shrink-0 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12717
13455
|
Menu2,
|
|
12718
13456
|
{
|
|
12719
13457
|
items: menuItems,
|
|
12720
13458
|
selectedKey: activeMenuKey,
|
|
12721
13459
|
onSelect: (key) => onMenuSelect?.(key)
|
|
12722
13460
|
}
|
|
12723
|
-
),
|
|
12724
|
-
conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0,
|
|
13461
|
+
) }),
|
|
13462
|
+
conversationSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12725
13463
|
"button",
|
|
12726
13464
|
{
|
|
12727
13465
|
type: "button",
|
|
12728
13466
|
"data-slot": "chat-page-section-toggle",
|
|
12729
13467
|
"aria-expanded": !convCollapsed,
|
|
12730
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
13468
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
12731
13469
|
onClick: toggleConvSection,
|
|
12732
13470
|
children: [
|
|
12733
|
-
/* @__PURE__ */ (0,
|
|
13471
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12734
13472
|
Text,
|
|
12735
13473
|
{
|
|
12736
13474
|
text: `${conversationSectionTitle} (${conversations.length})`,
|
|
@@ -12739,48 +13477,50 @@ function ChatPage({
|
|
|
12739
13477
|
strong: true
|
|
12740
13478
|
}
|
|
12741
13479
|
),
|
|
12742
|
-
/* @__PURE__ */ (0,
|
|
13480
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
12743
13481
|
]
|
|
12744
13482
|
}
|
|
12745
13483
|
) : null,
|
|
12746
|
-
!convCollapsed ? /* @__PURE__ */ (0,
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
13484
|
+
!convCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle flex min-h-0 flex-1 flex-col overflow-y-auto", children: [
|
|
13485
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
13486
|
+
ConversationList,
|
|
13487
|
+
{
|
|
13488
|
+
items: conversations,
|
|
13489
|
+
activeId: activeConversationId,
|
|
13490
|
+
onSelect: (id) => onSelectConversation?.(id),
|
|
13491
|
+
onDelete: (id) => onDeleteConversation?.(id)
|
|
13492
|
+
}
|
|
13493
|
+
),
|
|
13494
|
+
moreLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Button2, { text: `${moreLabel} >>`, variant: "link", size: "small", onClick: () => onMore?.() }) }) : null
|
|
13495
|
+
] }) : null,
|
|
13496
|
+
footerSectionTitle !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(
|
|
12757
13497
|
"button",
|
|
12758
13498
|
{
|
|
12759
13499
|
type: "button",
|
|
12760
13500
|
"data-slot": "chat-page-section-toggle",
|
|
12761
13501
|
"aria-expanded": !footerCollapsed,
|
|
12762
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
13502
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
12763
13503
|
onClick: toggleFooterSection,
|
|
12764
13504
|
children: [
|
|
12765
|
-
/* @__PURE__ */ (0,
|
|
12766
|
-
/* @__PURE__ */ (0,
|
|
13505
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
|
|
13506
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
12767
13507
|
]
|
|
12768
13508
|
}
|
|
12769
13509
|
) : null,
|
|
12770
|
-
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ (0,
|
|
13510
|
+
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime185.jsx)(
|
|
12771
13511
|
Menu2,
|
|
12772
13512
|
{
|
|
12773
13513
|
items: footerItems,
|
|
12774
13514
|
onSelect: (key) => onMenuSelect?.(key)
|
|
12775
13515
|
}
|
|
12776
|
-
) : null
|
|
13516
|
+
) }) : null
|
|
12777
13517
|
]
|
|
12778
13518
|
}
|
|
12779
13519
|
),
|
|
12780
|
-
/* @__PURE__ */ (0,
|
|
12781
|
-
/* @__PURE__ */ (0,
|
|
12782
|
-
/* @__PURE__ */ (0,
|
|
12783
|
-
/* @__PURE__ */ (0,
|
|
13520
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)("div", { className: "@container h-full min-w-0 flex-1", children: open ? /* @__PURE__ */ (0, import_jsx_runtime185.jsxs)(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
|
|
13521
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "62%", children: chatArea }),
|
|
13522
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(ResizableHandle, { withHandle: true }),
|
|
13523
|
+
/* @__PURE__ */ (0, import_jsx_runtime185.jsx)(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: artifactPanel })
|
|
12784
13524
|
] }) : chatArea })
|
|
12785
13525
|
]
|
|
12786
13526
|
}
|
|
@@ -12788,10 +13528,10 @@ function ChatPage({
|
|
|
12788
13528
|
}
|
|
12789
13529
|
|
|
12790
13530
|
// src/components/chat/Citation/index.tsx
|
|
12791
|
-
var
|
|
13531
|
+
var import_jsx_runtime186 = require("react/jsx-runtime");
|
|
12792
13532
|
function Citation({ items = [], start = 1, className, style }) {
|
|
12793
|
-
return /* @__PURE__ */ (0,
|
|
12794
|
-
/* @__PURE__ */ (0,
|
|
13533
|
+
return /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("span", { "data-slot": "citation", className: cn("inline-flex gap-1 align-super", className), style, children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(HoverCard, { children: [
|
|
13534
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(
|
|
12795
13535
|
HoverCardTrigger,
|
|
12796
13536
|
{
|
|
12797
13537
|
"data-slot": "citation-marker",
|
|
@@ -12803,10 +13543,10 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
12803
13543
|
]
|
|
12804
13544
|
}
|
|
12805
13545
|
),
|
|
12806
|
-
/* @__PURE__ */ (0,
|
|
12807
|
-
/* @__PURE__ */ (0,
|
|
12808
|
-
item.snippet ? /* @__PURE__ */ (0,
|
|
12809
|
-
item.url ? /* @__PURE__ */ (0,
|
|
13546
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsxs)(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
|
|
13547
|
+
/* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "text-sm font-medium", children: item.title }),
|
|
13548
|
+
item.snippet ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
|
|
13549
|
+
item.url ? /* @__PURE__ */ (0, import_jsx_runtime186.jsx)(
|
|
12810
13550
|
"a",
|
|
12811
13551
|
{
|
|
12812
13552
|
href: item.url,
|
|
@@ -12821,13 +13561,13 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
12821
13561
|
}
|
|
12822
13562
|
|
|
12823
13563
|
// src/components/chat/Suggestion/index.tsx
|
|
12824
|
-
var
|
|
13564
|
+
var import_jsx_runtime187 = require("react/jsx-runtime");
|
|
12825
13565
|
function normalize(item) {
|
|
12826
13566
|
if (typeof item === "string") return { label: item, value: item };
|
|
12827
13567
|
return { label: item.label, value: item.value ?? item.label, icon: item.icon };
|
|
12828
13568
|
}
|
|
12829
13569
|
function Suggestion({ items = [], justify = "start", onSelect, className, style }) {
|
|
12830
|
-
return /* @__PURE__ */ (0,
|
|
13570
|
+
return /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(
|
|
12831
13571
|
"div",
|
|
12832
13572
|
{
|
|
12833
13573
|
"data-slot": "suggestion",
|
|
@@ -12835,7 +13575,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12835
13575
|
style,
|
|
12836
13576
|
children: items.map((item, index) => {
|
|
12837
13577
|
const { label, value, icon } = normalize(item);
|
|
12838
|
-
return /* @__PURE__ */ (0,
|
|
13578
|
+
return /* @__PURE__ */ (0, import_jsx_runtime187.jsxs)(
|
|
12839
13579
|
"button",
|
|
12840
13580
|
{
|
|
12841
13581
|
type: "button",
|
|
@@ -12844,7 +13584,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12844
13584
|
className: "flex items-center gap-1.5 rounded-full border border-border px-3 py-1 text-sm transition-colors hover:bg-accent",
|
|
12845
13585
|
onClick: () => onSelect?.(value),
|
|
12846
13586
|
children: [
|
|
12847
|
-
icon ? /* @__PURE__ */ (0,
|
|
13587
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime187.jsx)(Icon, { name: icon, size: "sm" }) : null,
|
|
12848
13588
|
label
|
|
12849
13589
|
]
|
|
12850
13590
|
},
|
|
@@ -12856,7 +13596,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
12856
13596
|
}
|
|
12857
13597
|
|
|
12858
13598
|
// src/components/chart/EChartBase/index.tsx
|
|
12859
|
-
var
|
|
13599
|
+
var import_react68 = require("react");
|
|
12860
13600
|
|
|
12861
13601
|
// src/components/chart/echarts-modules.ts
|
|
12862
13602
|
var echarts = __toESM(require("echarts/core"), 1);
|
|
@@ -12887,7 +13627,7 @@ echarts.use([
|
|
|
12887
13627
|
]);
|
|
12888
13628
|
|
|
12889
13629
|
// src/components/chart/EChartBase/index.tsx
|
|
12890
|
-
var
|
|
13630
|
+
var import_jsx_runtime188 = require("react/jsx-runtime");
|
|
12891
13631
|
function EChartBase({
|
|
12892
13632
|
option,
|
|
12893
13633
|
height = 256,
|
|
@@ -12896,12 +13636,12 @@ function EChartBase({
|
|
|
12896
13636
|
style,
|
|
12897
13637
|
slot
|
|
12898
13638
|
}) {
|
|
12899
|
-
const hostRef = (0,
|
|
12900
|
-
const chartRef = (0,
|
|
12901
|
-
const onSelectRef = (0,
|
|
13639
|
+
const hostRef = (0, import_react68.useRef)(null);
|
|
13640
|
+
const chartRef = (0, import_react68.useRef)(null);
|
|
13641
|
+
const onSelectRef = (0, import_react68.useRef)(onSelect);
|
|
12902
13642
|
onSelectRef.current = onSelect;
|
|
12903
|
-
const [failed, setFailed] = (0,
|
|
12904
|
-
(0,
|
|
13643
|
+
const [failed, setFailed] = (0, import_react68.useState)(false);
|
|
13644
|
+
(0, import_react68.useEffect)(() => {
|
|
12905
13645
|
const host = hostRef.current;
|
|
12906
13646
|
if (!host) return;
|
|
12907
13647
|
let chart = null;
|
|
@@ -12928,14 +13668,14 @@ function EChartBase({
|
|
|
12928
13668
|
chartRef.current = null;
|
|
12929
13669
|
};
|
|
12930
13670
|
}, []);
|
|
12931
|
-
(0,
|
|
13671
|
+
(0, import_react68.useEffect)(() => {
|
|
12932
13672
|
try {
|
|
12933
13673
|
chartRef.current?.setOption(option, { notMerge: true });
|
|
12934
13674
|
} catch {
|
|
12935
13675
|
}
|
|
12936
13676
|
}, [option]);
|
|
12937
13677
|
if (failed) {
|
|
12938
|
-
return /* @__PURE__ */ (0,
|
|
13678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
|
|
12939
13679
|
"div",
|
|
12940
13680
|
{
|
|
12941
13681
|
"data-slot": "chart-fallback",
|
|
@@ -12948,7 +13688,7 @@ function EChartBase({
|
|
|
12948
13688
|
}
|
|
12949
13689
|
);
|
|
12950
13690
|
}
|
|
12951
|
-
return /* @__PURE__ */ (0,
|
|
13691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime188.jsx)(
|
|
12952
13692
|
"div",
|
|
12953
13693
|
{
|
|
12954
13694
|
ref: hostRef,
|
|
@@ -13482,7 +14222,7 @@ function getChartTheme() {
|
|
|
13482
14222
|
}
|
|
13483
14223
|
|
|
13484
14224
|
// src/components/chart/AreaChart/index.tsx
|
|
13485
|
-
var
|
|
14225
|
+
var import_jsx_runtime189 = require("react/jsx-runtime");
|
|
13486
14226
|
function AreaChart({
|
|
13487
14227
|
data = [],
|
|
13488
14228
|
xKey,
|
|
@@ -13500,7 +14240,7 @@ function AreaChart({
|
|
|
13500
14240
|
{ data, xKey, yKeys, stacked, fillOpacity, colors, title },
|
|
13501
14241
|
getChartTheme()
|
|
13502
14242
|
);
|
|
13503
|
-
return /* @__PURE__ */ (0,
|
|
14243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime189.jsx)(
|
|
13504
14244
|
EChartBase,
|
|
13505
14245
|
{
|
|
13506
14246
|
slot: "area-chart",
|
|
@@ -13514,7 +14254,7 @@ function AreaChart({
|
|
|
13514
14254
|
}
|
|
13515
14255
|
|
|
13516
14256
|
// src/components/chart/BarChart/index.tsx
|
|
13517
|
-
var
|
|
14257
|
+
var import_jsx_runtime190 = require("react/jsx-runtime");
|
|
13518
14258
|
function BarChart2({
|
|
13519
14259
|
data = [],
|
|
13520
14260
|
yKey,
|
|
@@ -13531,7 +14271,7 @@ function BarChart2({
|
|
|
13531
14271
|
{ data, yKey, yKeys: xKeys, stacked, colors, title },
|
|
13532
14272
|
getChartTheme()
|
|
13533
14273
|
);
|
|
13534
|
-
return /* @__PURE__ */ (0,
|
|
14274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime190.jsx)(
|
|
13535
14275
|
EChartBase,
|
|
13536
14276
|
{
|
|
13537
14277
|
slot: "bar-chart",
|
|
@@ -13545,7 +14285,7 @@ function BarChart2({
|
|
|
13545
14285
|
}
|
|
13546
14286
|
|
|
13547
14287
|
// src/components/chart/BubbleChart/index.tsx
|
|
13548
|
-
var
|
|
14288
|
+
var import_jsx_runtime191 = require("react/jsx-runtime");
|
|
13549
14289
|
function BubbleChart({
|
|
13550
14290
|
data = [],
|
|
13551
14291
|
xKey,
|
|
@@ -13563,7 +14303,7 @@ function BubbleChart({
|
|
|
13563
14303
|
{ data, xKey, yKey, sizeKey, seriesKey, colors, title },
|
|
13564
14304
|
getChartTheme()
|
|
13565
14305
|
);
|
|
13566
|
-
return /* @__PURE__ */ (0,
|
|
14306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime191.jsx)(
|
|
13567
14307
|
EChartBase,
|
|
13568
14308
|
{
|
|
13569
14309
|
slot: "bubble-chart",
|
|
@@ -13577,7 +14317,7 @@ function BubbleChart({
|
|
|
13577
14317
|
}
|
|
13578
14318
|
|
|
13579
14319
|
// src/components/chart/ColumnChart/index.tsx
|
|
13580
|
-
var
|
|
14320
|
+
var import_jsx_runtime192 = require("react/jsx-runtime");
|
|
13581
14321
|
function ColumnChart({
|
|
13582
14322
|
data = [],
|
|
13583
14323
|
xKey,
|
|
@@ -13594,7 +14334,7 @@ function ColumnChart({
|
|
|
13594
14334
|
{ data, xKey, yKeys, stacked, colors, title },
|
|
13595
14335
|
getChartTheme()
|
|
13596
14336
|
);
|
|
13597
|
-
return /* @__PURE__ */ (0,
|
|
14337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime192.jsx)(
|
|
13598
14338
|
EChartBase,
|
|
13599
14339
|
{
|
|
13600
14340
|
slot: "column-chart",
|
|
@@ -13608,7 +14348,7 @@ function ColumnChart({
|
|
|
13608
14348
|
}
|
|
13609
14349
|
|
|
13610
14350
|
// src/components/chart/ComposedChart/index.tsx
|
|
13611
|
-
var
|
|
14351
|
+
var import_jsx_runtime193 = require("react/jsx-runtime");
|
|
13612
14352
|
function ComposedChart({
|
|
13613
14353
|
data = [],
|
|
13614
14354
|
xKey,
|
|
@@ -13624,7 +14364,7 @@ function ComposedChart({
|
|
|
13624
14364
|
{ data, xKey, series, colors, title },
|
|
13625
14365
|
getChartTheme()
|
|
13626
14366
|
);
|
|
13627
|
-
return /* @__PURE__ */ (0,
|
|
14367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime193.jsx)(
|
|
13628
14368
|
EChartBase,
|
|
13629
14369
|
{
|
|
13630
14370
|
slot: "composed-chart",
|
|
@@ -13638,7 +14378,7 @@ function ComposedChart({
|
|
|
13638
14378
|
}
|
|
13639
14379
|
|
|
13640
14380
|
// src/components/chart/DonutChart/index.tsx
|
|
13641
|
-
var
|
|
14381
|
+
var import_jsx_runtime194 = require("react/jsx-runtime");
|
|
13642
14382
|
function DonutChart({
|
|
13643
14383
|
data = [],
|
|
13644
14384
|
nameKey,
|
|
@@ -13670,7 +14410,7 @@ function DonutChart({
|
|
|
13670
14410
|
},
|
|
13671
14411
|
getChartTheme()
|
|
13672
14412
|
);
|
|
13673
|
-
return /* @__PURE__ */ (0,
|
|
14413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime194.jsx)(
|
|
13674
14414
|
EChartBase,
|
|
13675
14415
|
{
|
|
13676
14416
|
slot: "donut-chart",
|
|
@@ -13684,7 +14424,7 @@ function DonutChart({
|
|
|
13684
14424
|
}
|
|
13685
14425
|
|
|
13686
14426
|
// src/components/chart/FunnelChart/index.tsx
|
|
13687
|
-
var
|
|
14427
|
+
var import_jsx_runtime195 = require("react/jsx-runtime");
|
|
13688
14428
|
function FunnelChart2({
|
|
13689
14429
|
data = [],
|
|
13690
14430
|
nameKey,
|
|
@@ -13701,7 +14441,7 @@ function FunnelChart2({
|
|
|
13701
14441
|
{ data, nameKey, valueKey, sort, colors, title },
|
|
13702
14442
|
getChartTheme()
|
|
13703
14443
|
);
|
|
13704
|
-
return /* @__PURE__ */ (0,
|
|
14444
|
+
return /* @__PURE__ */ (0, import_jsx_runtime195.jsx)(
|
|
13705
14445
|
EChartBase,
|
|
13706
14446
|
{
|
|
13707
14447
|
slot: "funnel-chart",
|
|
@@ -13715,7 +14455,7 @@ function FunnelChart2({
|
|
|
13715
14455
|
}
|
|
13716
14456
|
|
|
13717
14457
|
// src/components/chart/GaugeChart/index.tsx
|
|
13718
|
-
var
|
|
14458
|
+
var import_jsx_runtime196 = require("react/jsx-runtime");
|
|
13719
14459
|
function GaugeChart2({
|
|
13720
14460
|
value = 0,
|
|
13721
14461
|
min,
|
|
@@ -13732,7 +14472,7 @@ function GaugeChart2({
|
|
|
13732
14472
|
{ value, min, max, thresholds, unit, title },
|
|
13733
14473
|
getChartTheme()
|
|
13734
14474
|
);
|
|
13735
|
-
return /* @__PURE__ */ (0,
|
|
14475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime196.jsx)(
|
|
13736
14476
|
EChartBase,
|
|
13737
14477
|
{
|
|
13738
14478
|
slot: "gauge-chart",
|
|
@@ -13746,7 +14486,7 @@ function GaugeChart2({
|
|
|
13746
14486
|
}
|
|
13747
14487
|
|
|
13748
14488
|
// src/components/chart/Heatmap/index.tsx
|
|
13749
|
-
var
|
|
14489
|
+
var import_jsx_runtime197 = require("react/jsx-runtime");
|
|
13750
14490
|
function Heatmap({
|
|
13751
14491
|
data = [],
|
|
13752
14492
|
xKey,
|
|
@@ -13762,7 +14502,7 @@ function Heatmap({
|
|
|
13762
14502
|
{ data, xKey, yKey, valueKey, title },
|
|
13763
14503
|
getChartTheme()
|
|
13764
14504
|
);
|
|
13765
|
-
return /* @__PURE__ */ (0,
|
|
14505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime197.jsx)(
|
|
13766
14506
|
EChartBase,
|
|
13767
14507
|
{
|
|
13768
14508
|
slot: "heatmap",
|
|
@@ -13776,7 +14516,7 @@ function Heatmap({
|
|
|
13776
14516
|
}
|
|
13777
14517
|
|
|
13778
14518
|
// src/components/chart/LineChart/index.tsx
|
|
13779
|
-
var
|
|
14519
|
+
var import_jsx_runtime198 = require("react/jsx-runtime");
|
|
13780
14520
|
function LineChart2({
|
|
13781
14521
|
data = [],
|
|
13782
14522
|
xKey,
|
|
@@ -13795,7 +14535,7 @@ function LineChart2({
|
|
|
13795
14535
|
{ data, xKey, yKeys, smooth, showArea, stacked, colors, title },
|
|
13796
14536
|
getChartTheme()
|
|
13797
14537
|
);
|
|
13798
|
-
return /* @__PURE__ */ (0,
|
|
14538
|
+
return /* @__PURE__ */ (0, import_jsx_runtime198.jsx)(
|
|
13799
14539
|
EChartBase,
|
|
13800
14540
|
{
|
|
13801
14541
|
slot: "line-chart",
|
|
@@ -13809,8 +14549,8 @@ function LineChart2({
|
|
|
13809
14549
|
}
|
|
13810
14550
|
|
|
13811
14551
|
// src/components/chart/MapChart/index.tsx
|
|
13812
|
-
var
|
|
13813
|
-
var
|
|
14552
|
+
var import_react69 = require("react");
|
|
14553
|
+
var import_jsx_runtime199 = require("react/jsx-runtime");
|
|
13814
14554
|
var fetchedMaps = /* @__PURE__ */ new Set();
|
|
13815
14555
|
function hasRegisteredMap(mapName) {
|
|
13816
14556
|
try {
|
|
@@ -13832,7 +14572,7 @@ function MapChart2({
|
|
|
13832
14572
|
className,
|
|
13833
14573
|
style
|
|
13834
14574
|
}) {
|
|
13835
|
-
const [loadState, setLoadState] = (0,
|
|
14575
|
+
const [loadState, setLoadState] = (0, import_react69.useState)(
|
|
13836
14576
|
() => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
|
|
13837
14577
|
);
|
|
13838
14578
|
if (geoJson) {
|
|
@@ -13841,7 +14581,7 @@ function MapChart2({
|
|
|
13841
14581
|
} catch {
|
|
13842
14582
|
}
|
|
13843
14583
|
}
|
|
13844
|
-
(0,
|
|
14584
|
+
(0, import_react69.useEffect)(() => {
|
|
13845
14585
|
if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
|
|
13846
14586
|
setLoadState("idle");
|
|
13847
14587
|
return;
|
|
@@ -13866,7 +14606,7 @@ function MapChart2({
|
|
|
13866
14606
|
};
|
|
13867
14607
|
}, [geoJson, geoJsonUrl, mapName]);
|
|
13868
14608
|
if (geoJsonUrl && !geoJson && loadState === "loading") {
|
|
13869
|
-
return /* @__PURE__ */ (0,
|
|
14609
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13870
14610
|
"div",
|
|
13871
14611
|
{
|
|
13872
14612
|
"data-slot": "map-chart-loading",
|
|
@@ -13876,7 +14616,7 @@ function MapChart2({
|
|
|
13876
14616
|
);
|
|
13877
14617
|
}
|
|
13878
14618
|
if (!geoJson && loadState === "error") {
|
|
13879
|
-
return /* @__PURE__ */ (0,
|
|
14619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13880
14620
|
Empty2,
|
|
13881
14621
|
{
|
|
13882
14622
|
title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
|
|
@@ -13888,7 +14628,7 @@ function MapChart2({
|
|
|
13888
14628
|
}
|
|
13889
14629
|
if (!geoJson && !hasRegisteredMap(mapName)) {
|
|
13890
14630
|
console.warn(`[MapChart] \u5730\u56FE "${mapName}" \u672A\u6CE8\u518C\uFF1A\u8BF7\u4F20\u5165 geoJson / geoJsonUrl\uFF0C\u6216\u5728\u5E94\u7528\u542F\u52A8\u65F6 echarts.registerMap`);
|
|
13891
|
-
return /* @__PURE__ */ (0,
|
|
14631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13892
14632
|
Empty2,
|
|
13893
14633
|
{
|
|
13894
14634
|
title: "\u5730\u56FE\u672A\u6CE8\u518C",
|
|
@@ -13899,7 +14639,7 @@ function MapChart2({
|
|
|
13899
14639
|
);
|
|
13900
14640
|
}
|
|
13901
14641
|
const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, getChartTheme());
|
|
13902
|
-
return /* @__PURE__ */ (0,
|
|
14642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime199.jsx)(
|
|
13903
14643
|
EChartBase,
|
|
13904
14644
|
{
|
|
13905
14645
|
slot: "map-chart",
|
|
@@ -13914,7 +14654,7 @@ function MapChart2({
|
|
|
13914
14654
|
|
|
13915
14655
|
// src/components/chart/MetricCard/index.tsx
|
|
13916
14656
|
var import_lucide_react37 = require("lucide-react");
|
|
13917
|
-
var
|
|
14657
|
+
var import_jsx_runtime200 = require("react/jsx-runtime");
|
|
13918
14658
|
function MetricCard({
|
|
13919
14659
|
title,
|
|
13920
14660
|
value,
|
|
@@ -13927,15 +14667,15 @@ function MetricCard({
|
|
|
13927
14667
|
}) {
|
|
13928
14668
|
const showTrend = typeof trend === "number" && trend !== 0;
|
|
13929
14669
|
const rising = (trend ?? 0) > 0;
|
|
13930
|
-
return /* @__PURE__ */ (0,
|
|
14670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13931
14671
|
"div",
|
|
13932
14672
|
{
|
|
13933
14673
|
"data-slot": "metric-card",
|
|
13934
14674
|
className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
|
|
13935
14675
|
style,
|
|
13936
14676
|
children: [
|
|
13937
|
-
title ? /* @__PURE__ */ (0,
|
|
13938
|
-
/* @__PURE__ */ (0,
|
|
14677
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
|
|
14678
|
+
/* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13939
14679
|
"div",
|
|
13940
14680
|
{
|
|
13941
14681
|
"data-slot": "metric-card-value",
|
|
@@ -13947,7 +14687,7 @@ function MetricCard({
|
|
|
13947
14687
|
]
|
|
13948
14688
|
}
|
|
13949
14689
|
),
|
|
13950
|
-
showTrend ? /* @__PURE__ */ (0,
|
|
14690
|
+
showTrend ? /* @__PURE__ */ (0, import_jsx_runtime200.jsxs)(
|
|
13951
14691
|
"div",
|
|
13952
14692
|
{
|
|
13953
14693
|
"data-slot": "metric-card-trend",
|
|
@@ -13957,10 +14697,10 @@ function MetricCard({
|
|
|
13957
14697
|
rising ? "text-success" : "text-destructive"
|
|
13958
14698
|
),
|
|
13959
14699
|
children: [
|
|
13960
|
-
rising ? /* @__PURE__ */ (0,
|
|
14700
|
+
rising ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(import_lucide_react37.ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime200.jsx)(import_lucide_react37.ArrowDownRight, { className: "size-4" }),
|
|
13961
14701
|
Math.abs(trend ?? 0),
|
|
13962
14702
|
"%",
|
|
13963
|
-
trendLabel ? /* @__PURE__ */ (0,
|
|
14703
|
+
trendLabel ? /* @__PURE__ */ (0, import_jsx_runtime200.jsx)("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
|
|
13964
14704
|
]
|
|
13965
14705
|
}
|
|
13966
14706
|
) : null
|
|
@@ -13970,7 +14710,7 @@ function MetricCard({
|
|
|
13970
14710
|
}
|
|
13971
14711
|
|
|
13972
14712
|
// src/components/chart/PieChart/index.tsx
|
|
13973
|
-
var
|
|
14713
|
+
var import_jsx_runtime201 = require("react/jsx-runtime");
|
|
13974
14714
|
function PieChart2({
|
|
13975
14715
|
data = [],
|
|
13976
14716
|
nameKey,
|
|
@@ -13987,7 +14727,7 @@ function PieChart2({
|
|
|
13987
14727
|
{ data, nameKey, valueKey, showLabel, colors, title },
|
|
13988
14728
|
getChartTheme()
|
|
13989
14729
|
);
|
|
13990
|
-
return /* @__PURE__ */ (0,
|
|
14730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime201.jsx)(
|
|
13991
14731
|
EChartBase,
|
|
13992
14732
|
{
|
|
13993
14733
|
slot: "pie-chart",
|
|
@@ -14001,7 +14741,7 @@ function PieChart2({
|
|
|
14001
14741
|
}
|
|
14002
14742
|
|
|
14003
14743
|
// src/components/chart/RadarChart/index.tsx
|
|
14004
|
-
var
|
|
14744
|
+
var import_jsx_runtime202 = require("react/jsx-runtime");
|
|
14005
14745
|
function RadarChart2({
|
|
14006
14746
|
data = [],
|
|
14007
14747
|
indicatorKey,
|
|
@@ -14017,7 +14757,7 @@ function RadarChart2({
|
|
|
14017
14757
|
{ data, indicatorKey, yKeys, colors, title },
|
|
14018
14758
|
getChartTheme()
|
|
14019
14759
|
);
|
|
14020
|
-
return /* @__PURE__ */ (0,
|
|
14760
|
+
return /* @__PURE__ */ (0, import_jsx_runtime202.jsx)(
|
|
14021
14761
|
EChartBase,
|
|
14022
14762
|
{
|
|
14023
14763
|
slot: "radar-chart",
|
|
@@ -14031,7 +14771,7 @@ function RadarChart2({
|
|
|
14031
14771
|
}
|
|
14032
14772
|
|
|
14033
14773
|
// src/components/chart/SankeyChart/index.tsx
|
|
14034
|
-
var
|
|
14774
|
+
var import_jsx_runtime203 = require("react/jsx-runtime");
|
|
14035
14775
|
function SankeyChart2({
|
|
14036
14776
|
nodes = [],
|
|
14037
14777
|
links = [],
|
|
@@ -14042,7 +14782,7 @@ function SankeyChart2({
|
|
|
14042
14782
|
style
|
|
14043
14783
|
}) {
|
|
14044
14784
|
const option = buildSankeyOption({ nodes, links, title }, getChartTheme());
|
|
14045
|
-
return /* @__PURE__ */ (0,
|
|
14785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime203.jsx)(
|
|
14046
14786
|
EChartBase,
|
|
14047
14787
|
{
|
|
14048
14788
|
slot: "sankey-chart",
|
|
@@ -14056,7 +14796,7 @@ function SankeyChart2({
|
|
|
14056
14796
|
}
|
|
14057
14797
|
|
|
14058
14798
|
// src/components/chart/ScatterChart/index.tsx
|
|
14059
|
-
var
|
|
14799
|
+
var import_jsx_runtime204 = require("react/jsx-runtime");
|
|
14060
14800
|
function ScatterChart2({
|
|
14061
14801
|
data = [],
|
|
14062
14802
|
xKey,
|
|
@@ -14073,7 +14813,7 @@ function ScatterChart2({
|
|
|
14073
14813
|
{ data, xKey, yKey, seriesKey, colors, title },
|
|
14074
14814
|
getChartTheme()
|
|
14075
14815
|
);
|
|
14076
|
-
return /* @__PURE__ */ (0,
|
|
14816
|
+
return /* @__PURE__ */ (0, import_jsx_runtime204.jsx)(
|
|
14077
14817
|
EChartBase,
|
|
14078
14818
|
{
|
|
14079
14819
|
slot: "scatter-chart",
|
|
@@ -14087,7 +14827,7 @@ function ScatterChart2({
|
|
|
14087
14827
|
}
|
|
14088
14828
|
|
|
14089
14829
|
// src/components/chart/TreeChart/index.tsx
|
|
14090
|
-
var
|
|
14830
|
+
var import_jsx_runtime205 = require("react/jsx-runtime");
|
|
14091
14831
|
function TreeChart2({
|
|
14092
14832
|
data = [],
|
|
14093
14833
|
title,
|
|
@@ -14103,7 +14843,7 @@ function TreeChart2({
|
|
|
14103
14843
|
{ data, title, orient, edgeShape, initialTreeDepth },
|
|
14104
14844
|
getChartTheme()
|
|
14105
14845
|
);
|
|
14106
|
-
return /* @__PURE__ */ (0,
|
|
14846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime205.jsx)(
|
|
14107
14847
|
EChartBase,
|
|
14108
14848
|
{
|
|
14109
14849
|
slot: "tree-chart",
|