@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
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
Icon,
|
|
3
3
|
Menu,
|
|
4
4
|
Sidebar
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-44DAGWXZ.js";
|
|
6
6
|
import {
|
|
7
7
|
Alert,
|
|
8
8
|
AlertDescription,
|
|
@@ -1611,6 +1611,7 @@ function Command2({
|
|
|
1611
1611
|
import { useRenderer as useRenderer5 } from "@pactor-app/runtime";
|
|
1612
1612
|
import { ArrowUp } from "lucide-react";
|
|
1613
1613
|
import {
|
|
1614
|
+
isValidElement,
|
|
1614
1615
|
useRef as useRef3,
|
|
1615
1616
|
useState as useState10
|
|
1616
1617
|
} from "react";
|
|
@@ -1625,6 +1626,7 @@ function ChatInput({
|
|
|
1625
1626
|
toolbarEnd,
|
|
1626
1627
|
header,
|
|
1627
1628
|
footer,
|
|
1629
|
+
field,
|
|
1628
1630
|
onChange,
|
|
1629
1631
|
onSubmit,
|
|
1630
1632
|
className,
|
|
@@ -1635,6 +1637,8 @@ function ChatInput({
|
|
|
1635
1637
|
const [draft, setDraft] = useState10("");
|
|
1636
1638
|
const text = controlled ? value : draft;
|
|
1637
1639
|
const canSubmit = !disabled && text.trim() !== "";
|
|
1640
|
+
const customField = field !== void 0 && field !== null;
|
|
1641
|
+
const renderSlot = (slot) => isValidElement(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
1638
1642
|
const composingRef = useRef3(false);
|
|
1639
1643
|
const handleChange = (next) => {
|
|
1640
1644
|
if (!controlled) {
|
|
@@ -1670,8 +1674,8 @@ function ChatInput({
|
|
|
1670
1674
|
),
|
|
1671
1675
|
style,
|
|
1672
1676
|
children: [
|
|
1673
|
-
header ? /* @__PURE__ */ jsx26("div", { className: "px-3 pt-3", children:
|
|
1674
|
-
/* @__PURE__ */ jsx26(
|
|
1677
|
+
header ? /* @__PURE__ */ jsx26("div", { className: "px-3 pt-3", children: renderSlot(header) }) : null,
|
|
1678
|
+
customField ? field : /* @__PURE__ */ jsx26(
|
|
1675
1679
|
Textarea,
|
|
1676
1680
|
{
|
|
1677
1681
|
value: text,
|
|
@@ -1686,9 +1690,9 @@ function ChatInput({
|
|
|
1686
1690
|
}
|
|
1687
1691
|
),
|
|
1688
1692
|
toolbarStart || toolbarEnd || !hideSend ? /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1 px-2 pb-2", children: [
|
|
1689
|
-
toolbarStart ?
|
|
1693
|
+
toolbarStart ? renderSlot(toolbarStart) : null,
|
|
1690
1694
|
/* @__PURE__ */ jsx26("span", { className: "flex-1" }),
|
|
1691
|
-
toolbarEnd ?
|
|
1695
|
+
toolbarEnd ? renderSlot(toolbarEnd) : null,
|
|
1692
1696
|
hideSend ? null : /* @__PURE__ */ jsx26(
|
|
1693
1697
|
Button,
|
|
1694
1698
|
{
|
|
@@ -1702,7 +1706,7 @@ function ChatInput({
|
|
|
1702
1706
|
}
|
|
1703
1707
|
)
|
|
1704
1708
|
] }) : null,
|
|
1705
|
-
footer ? /* @__PURE__ */ jsx26("div", { className: "border-t border-border px-3 py-2", children:
|
|
1709
|
+
footer ? /* @__PURE__ */ jsx26("div", { className: "border-t border-border px-3 py-2", children: renderSlot(footer) }) : null
|
|
1706
1710
|
]
|
|
1707
1711
|
}
|
|
1708
1712
|
);
|
|
@@ -2138,7 +2142,8 @@ function DatePicker(props) {
|
|
|
2138
2142
|
onSelect: handleRangeDaySelect,
|
|
2139
2143
|
modifiers: rangeModifiers,
|
|
2140
2144
|
modifiersClassNames: rangeModifierClassNames,
|
|
2141
|
-
locale: dfLocale
|
|
2145
|
+
locale: dfLocale,
|
|
2146
|
+
showOutsideDays: false
|
|
2142
2147
|
}
|
|
2143
2148
|
)
|
|
2144
2149
|
}
|
|
@@ -2152,7 +2157,8 @@ function DatePicker(props) {
|
|
|
2152
2157
|
onSelect: handleRangeDaySelect,
|
|
2153
2158
|
modifiers: rangeModifiers,
|
|
2154
2159
|
modifiersClassNames: rangeModifierClassNames,
|
|
2155
|
-
locale: dfLocale
|
|
2160
|
+
locale: dfLocale,
|
|
2161
|
+
showOutsideDays: false
|
|
2156
2162
|
}
|
|
2157
2163
|
) })
|
|
2158
2164
|
] }) : /* @__PURE__ */ jsx31(
|
|
@@ -7557,7 +7563,14 @@ function ArtifactTreeRow({
|
|
|
7557
7563
|
className: "flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm hover:bg-accent",
|
|
7558
7564
|
onClick: () => setOpen((value) => !value),
|
|
7559
7565
|
children: [
|
|
7560
|
-
/* @__PURE__ */ jsx113(
|
|
7566
|
+
/* @__PURE__ */ jsx113(
|
|
7567
|
+
"span",
|
|
7568
|
+
{
|
|
7569
|
+
className: "inline-flex transition-transform data-[open=true]:rotate-90",
|
|
7570
|
+
"data-open": open,
|
|
7571
|
+
children: /* @__PURE__ */ jsx113(Icon, { name: "chevron-right", size: 12 })
|
|
7572
|
+
}
|
|
7573
|
+
),
|
|
7561
7574
|
/* @__PURE__ */ jsx113(Icon, { name: "folder", size: 13 }),
|
|
7562
7575
|
/* @__PURE__ */ jsx113("span", { className: "min-w-0 flex-1 truncate", children: node.name })
|
|
7563
7576
|
]
|
|
@@ -7689,6 +7702,7 @@ function ArtifactPanel({
|
|
|
7689
7702
|
icon: "download",
|
|
7690
7703
|
variant: "text",
|
|
7691
7704
|
tooltip: "\u4E0B\u8F7D\u4EA7\u7269",
|
|
7705
|
+
className: "px-2",
|
|
7692
7706
|
onClick: () => onDownload ? onDownload(artifact) : void downloadArtifact(artifact)
|
|
7693
7707
|
}
|
|
7694
7708
|
) : null,
|
|
@@ -7698,11 +7712,12 @@ function ArtifactPanel({
|
|
|
7698
7712
|
icon: "x",
|
|
7699
7713
|
variant: "text",
|
|
7700
7714
|
tooltip: "\u6536\u8D77\u4EA7\u7269\u533A",
|
|
7715
|
+
className: "px-2",
|
|
7701
7716
|
onClick: () => onClose?.()
|
|
7702
7717
|
}
|
|
7703
7718
|
)
|
|
7704
7719
|
] }),
|
|
7705
|
-
/* @__PURE__ */ jsx113("div", { className: "min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ jsx113(
|
|
7720
|
+
/* @__PURE__ */ jsx113("div", { className: "scrollbar-subtle min-h-0 flex-1 overflow-auto p-4", children: view === "list" && artifacts !== void 0 ? /* @__PURE__ */ jsx113(
|
|
7706
7721
|
ArtifactListView,
|
|
7707
7722
|
{
|
|
7708
7723
|
nodes: buildArtifactTree(artifacts),
|
|
@@ -7873,7 +7888,7 @@ function Thinking({
|
|
|
7873
7888
|
{
|
|
7874
7889
|
"data-slot": "thinking",
|
|
7875
7890
|
"data-status": status,
|
|
7876
|
-
className: cn("w-full
|
|
7891
|
+
className: cn("w-full", className),
|
|
7877
7892
|
style,
|
|
7878
7893
|
children: [
|
|
7879
7894
|
/* @__PURE__ */ jsxs82(
|
|
@@ -7882,12 +7897,12 @@ function Thinking({
|
|
|
7882
7897
|
type: "button",
|
|
7883
7898
|
"data-slot": "thinking-trigger",
|
|
7884
7899
|
"aria-expanded": isExpanded,
|
|
7885
|
-
className: "flex w-full items-center gap-2
|
|
7900
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
7886
7901
|
onClick: toggle,
|
|
7887
7902
|
children: [
|
|
7888
7903
|
/* @__PURE__ */ jsx118("span", { className: cn("text-muted-foreground", status === "thinking" && "animate-pulse motion-reduce:animate-none"), children: /* @__PURE__ */ jsx118(Icon, { name: "brain", size: "sm" }) }),
|
|
7889
|
-
/* @__PURE__ */ jsx118("span", { "data-slot": "thinking-title", className: "
|
|
7890
|
-
/* @__PURE__ */ jsx118(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
7904
|
+
/* @__PURE__ */ jsx118("span", { "data-slot": "thinking-title", className: "text-muted-foreground", children: resolvedTitle }),
|
|
7905
|
+
/* @__PURE__ */ jsx118("span", { className: "text-muted-foreground", children: /* @__PURE__ */ jsx118(Icon, { name: isExpanded ? "chevron-down" : "chevron-right", size: "sm" }) })
|
|
7891
7906
|
]
|
|
7892
7907
|
}
|
|
7893
7908
|
),
|
|
@@ -7895,7 +7910,7 @@ function Thinking({
|
|
|
7895
7910
|
"div",
|
|
7896
7911
|
{
|
|
7897
7912
|
"data-slot": "thinking-content",
|
|
7898
|
-
className: "
|
|
7913
|
+
className: "py-1 pl-6 text-sm whitespace-pre-wrap text-muted-foreground",
|
|
7899
7914
|
children: content
|
|
7900
7915
|
}
|
|
7901
7916
|
) : null
|
|
@@ -7906,7 +7921,7 @@ function Thinking({
|
|
|
7906
7921
|
|
|
7907
7922
|
// src/components/chat/ToolCall/index.tsx
|
|
7908
7923
|
import { useState as useState40 } from "react";
|
|
7909
|
-
import { jsx as jsx119, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
7924
|
+
import { Fragment as Fragment11, jsx as jsx119, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
7910
7925
|
var statusIcon3 = {
|
|
7911
7926
|
running: { icon: "loader-circle", className: "text-info", spin: true },
|
|
7912
7927
|
done: { icon: "circle-check", className: "text-success" },
|
|
@@ -7925,42 +7940,51 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
7925
7940
|
const [expanded, setExpanded] = useState40(defaultExpanded ?? status === "running");
|
|
7926
7941
|
const meta = statusIcon3[status];
|
|
7927
7942
|
const paramsText = renderValue(params);
|
|
7943
|
+
const hasDetail = Boolean(paramsText) || Boolean(result);
|
|
7944
|
+
const headerInner = /* @__PURE__ */ jsxs83(Fragment11, { children: [
|
|
7945
|
+
/* @__PURE__ */ jsx119("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsx119(Icon, { name: "terminal", size: "sm" }) }),
|
|
7946
|
+
/* @__PURE__ */ jsx119("span", { "data-slot": "tool-call-name", className: "min-w-0 truncate font-medium", children: name ?? "\u5DE5\u5177\u8C03\u7528" }),
|
|
7947
|
+
/* @__PURE__ */ jsx119("span", { className: cn("shrink-0", meta.className, meta.spin && "animate-spin motion-reduce:animate-none"), children: /* @__PURE__ */ jsx119(Icon, { name: meta.icon, size: "sm" }) }),
|
|
7948
|
+
durationMs !== void 0 ? /* @__PURE__ */ jsxs83("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
|
|
7949
|
+
(durationMs / 1e3).toFixed(1),
|
|
7950
|
+
"s"
|
|
7951
|
+
] }) : null,
|
|
7952
|
+
hasDetail ? /* @__PURE__ */ jsx119("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsx119(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" }) }) : null
|
|
7953
|
+
] });
|
|
7928
7954
|
return /* @__PURE__ */ jsxs83(
|
|
7929
7955
|
"div",
|
|
7930
7956
|
{
|
|
7931
7957
|
"data-slot": "tool-call",
|
|
7932
7958
|
"data-status": status,
|
|
7933
|
-
className: cn("w-full
|
|
7959
|
+
className: cn("w-full", className),
|
|
7934
7960
|
style,
|
|
7935
7961
|
children: [
|
|
7936
|
-
/* @__PURE__ */
|
|
7962
|
+
hasDetail ? /* @__PURE__ */ jsx119(
|
|
7937
7963
|
"button",
|
|
7938
7964
|
{
|
|
7939
7965
|
type: "button",
|
|
7940
7966
|
"data-slot": "tool-call-trigger",
|
|
7941
7967
|
"aria-expanded": expanded,
|
|
7942
|
-
className: "flex w-full items-center gap-2
|
|
7968
|
+
className: "flex w-full cursor-pointer items-center gap-2 py-1 text-left text-sm",
|
|
7943
7969
|
onClick: () => setExpanded((value) => !value),
|
|
7944
|
-
children:
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
/* @__PURE__ */ jsx119(Icon, { name: expanded ? "chevron-down" : "chevron-right", size: "sm" })
|
|
7953
|
-
]
|
|
7970
|
+
children: headerInner
|
|
7971
|
+
}
|
|
7972
|
+
) : /* @__PURE__ */ jsx119(
|
|
7973
|
+
"div",
|
|
7974
|
+
{
|
|
7975
|
+
"data-slot": "tool-call-trigger",
|
|
7976
|
+
className: "flex w-full items-center gap-2 py-1 text-left text-sm",
|
|
7977
|
+
children: headerInner
|
|
7954
7978
|
}
|
|
7955
7979
|
),
|
|
7956
|
-
expanded ? /* @__PURE__ */ jsxs83("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2
|
|
7980
|
+
hasDetail && expanded ? /* @__PURE__ */ jsxs83("div", { "data-slot": "tool-call-body", className: "flex flex-col gap-2 py-1 pl-6", children: [
|
|
7957
7981
|
paramsText ? /* @__PURE__ */ jsxs83("div", { children: [
|
|
7958
7982
|
/* @__PURE__ */ jsx119("div", { className: "text-xs font-medium text-muted-foreground", children: "\u53C2\u6570" }),
|
|
7959
|
-
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto
|
|
7983
|
+
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-params", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: paramsText })
|
|
7960
7984
|
] }) : null,
|
|
7961
7985
|
result ? /* @__PURE__ */ jsxs83("div", { children: [
|
|
7962
7986
|
/* @__PURE__ */ jsx119("div", { className: "text-xs font-medium text-muted-foreground", children: "\u7ED3\u679C" }),
|
|
7963
|
-
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto
|
|
7987
|
+
/* @__PURE__ */ jsx119("pre", { "data-slot": "tool-call-result", className: "mt-1 overflow-x-auto text-xs whitespace-pre-wrap text-muted-foreground", children: result })
|
|
7964
7988
|
] }) : null
|
|
7965
7989
|
] }) : null
|
|
7966
7990
|
]
|
|
@@ -7970,12 +7994,26 @@ function ToolCall({ name, params, status = "done", result, durationMs, defaultEx
|
|
|
7970
7994
|
|
|
7971
7995
|
// src/components/chat/ChatMessage/index.tsx
|
|
7972
7996
|
import { jsx as jsx120, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
7973
|
-
function PartView({
|
|
7997
|
+
function PartView({
|
|
7998
|
+
part,
|
|
7999
|
+
role,
|
|
8000
|
+
onOpenArtifacts
|
|
8001
|
+
}) {
|
|
8002
|
+
if (role === "system" && (part.type === "text" || part.type === "markdown")) {
|
|
8003
|
+
return /* @__PURE__ */ jsx120(
|
|
8004
|
+
"div",
|
|
8005
|
+
{
|
|
8006
|
+
"data-slot": "chat-message-system-part",
|
|
8007
|
+
className: "w-full text-center text-xs text-muted-foreground",
|
|
8008
|
+
children: part.type === "markdown" ? /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content }) : part.content
|
|
8009
|
+
}
|
|
8010
|
+
);
|
|
8011
|
+
}
|
|
7974
8012
|
switch (part.type) {
|
|
7975
8013
|
case "text":
|
|
7976
8014
|
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "muted", children: /* @__PURE__ */ jsx120("span", { className: "text-sm whitespace-pre-wrap", children: part.content }) });
|
|
7977
8015
|
case "markdown":
|
|
7978
|
-
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content
|
|
8016
|
+
return /* @__PURE__ */ jsx120(Bubble2, { align: role === "user" ? "end" : "start", variant: role === "user" ? "default" : "ghost", children: /* @__PURE__ */ jsx120(MarkdownDslComponent, { content: part.content }) });
|
|
7979
8017
|
case "thinking":
|
|
7980
8018
|
return /* @__PURE__ */ jsx120(Thinking, { content: part.content, status: part.status ?? "done" });
|
|
7981
8019
|
case "tool-call":
|
|
@@ -7983,10 +8021,31 @@ function PartView({ part, role }) {
|
|
|
7983
8021
|
case "tool-result":
|
|
7984
8022
|
return /* @__PURE__ */ jsx120("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 });
|
|
7985
8023
|
case "status":
|
|
7986
|
-
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-status", className: "flex items-center gap-1.5 text-
|
|
8024
|
+
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-status", className: "flex w-fit items-center gap-1.5 text-muted-foreground", children: [
|
|
7987
8025
|
/* @__PURE__ */ jsx120(Icon, { name: "clock", size: "sm" }),
|
|
7988
8026
|
part.text
|
|
7989
8027
|
] });
|
|
8028
|
+
case "artifacts": {
|
|
8029
|
+
const artifactsClass = "flex w-fit items-center gap-1.5 text-muted-foreground";
|
|
8030
|
+
const label = `\u5DF2\u751F\u6210 ${part.count} \u4E2A\u4EA7\u7269`;
|
|
8031
|
+
return onOpenArtifacts ? /* @__PURE__ */ jsxs84(
|
|
8032
|
+
"button",
|
|
8033
|
+
{
|
|
8034
|
+
type: "button",
|
|
8035
|
+
"data-slot": "chat-message-artifacts",
|
|
8036
|
+
className: cn(artifactsClass, "cursor-pointer hover:text-foreground"),
|
|
8037
|
+
onClick: onOpenArtifacts,
|
|
8038
|
+
children: [
|
|
8039
|
+
/* @__PURE__ */ jsx120(Icon, { name: "package", size: "sm" }),
|
|
8040
|
+
label,
|
|
8041
|
+
/* @__PURE__ */ jsx120(Icon, { name: "chevron-right", size: 12 })
|
|
8042
|
+
]
|
|
8043
|
+
}
|
|
8044
|
+
) : /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-artifacts", className: artifactsClass, children: [
|
|
8045
|
+
/* @__PURE__ */ jsx120(Icon, { name: "package", size: "sm" }),
|
|
8046
|
+
label
|
|
8047
|
+
] });
|
|
8048
|
+
}
|
|
7990
8049
|
case "error":
|
|
7991
8050
|
return /* @__PURE__ */ jsxs84("div", { "data-slot": "chat-message-error", className: "flex items-center gap-1.5 text-sm text-destructive", children: [
|
|
7992
8051
|
/* @__PURE__ */ jsx120(Icon, { name: "circle-alert", size: "sm" }),
|
|
@@ -7996,19 +8055,31 @@ function PartView({ part, role }) {
|
|
|
7996
8055
|
return null;
|
|
7997
8056
|
}
|
|
7998
8057
|
}
|
|
8058
|
+
var ACTION_ICON_BY_NAME = {
|
|
8059
|
+
copy: "copy",
|
|
8060
|
+
retry: "rotate-ccw",
|
|
8061
|
+
regenerate: "refresh-ccw",
|
|
8062
|
+
edit: "pencil",
|
|
8063
|
+
like: "thumbs-up",
|
|
8064
|
+
dislike: "thumbs-down",
|
|
8065
|
+
share: "share",
|
|
8066
|
+
delete: "trash"
|
|
8067
|
+
};
|
|
7999
8068
|
function ChatMessage({
|
|
8000
8069
|
role = "assistant",
|
|
8001
8070
|
parts = [],
|
|
8002
8071
|
status = "completed",
|
|
8003
8072
|
agent,
|
|
8004
8073
|
time,
|
|
8005
|
-
showSender =
|
|
8074
|
+
showSender = false,
|
|
8006
8075
|
actions = [],
|
|
8007
8076
|
onAction,
|
|
8077
|
+
onOpenArtifacts,
|
|
8008
8078
|
className,
|
|
8009
8079
|
style
|
|
8010
8080
|
}) {
|
|
8011
8081
|
const isUser = role === "user";
|
|
8082
|
+
const isSystem = role === "system";
|
|
8012
8083
|
const senderName = isUser ? "\u6211" : agent?.name ?? "\u52A9\u624B";
|
|
8013
8084
|
return /* @__PURE__ */ jsxs84(
|
|
8014
8085
|
"div",
|
|
@@ -8016,10 +8087,16 @@ function ChatMessage({
|
|
|
8016
8087
|
"data-slot": "chat-message",
|
|
8017
8088
|
"data-role": role,
|
|
8018
8089
|
"data-status": status,
|
|
8019
|
-
className: cn(
|
|
8090
|
+
className: cn(
|
|
8091
|
+
"flex w-full flex-col gap-1.5",
|
|
8092
|
+
isUser && "items-end",
|
|
8093
|
+
// system 居中弱提示(参考 @pactor-app/chat MessageBubble)
|
|
8094
|
+
isSystem && "items-center text-muted-foreground",
|
|
8095
|
+
className
|
|
8096
|
+
),
|
|
8020
8097
|
style,
|
|
8021
8098
|
children: [
|
|
8022
|
-
showSender
|
|
8099
|
+
showSender ? /* @__PURE__ */ jsx120(
|
|
8023
8100
|
Sender,
|
|
8024
8101
|
{
|
|
8025
8102
|
name: senderName,
|
|
@@ -8028,35 +8105,454 @@ function ChatMessage({
|
|
|
8028
8105
|
align: isUser ? "end" : "start"
|
|
8029
8106
|
}
|
|
8030
8107
|
) : null,
|
|
8031
|
-
/* @__PURE__ */ jsxs84("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end"), children: [
|
|
8032
|
-
parts.map((part, index) => /* @__PURE__ */ jsx120(PartView, { part, role }, index)),
|
|
8108
|
+
/* @__PURE__ */ jsxs84("div", { className: cn("flex min-w-0 w-full max-w-full flex-col gap-2", isUser && "items-end", isSystem && "items-center"), children: [
|
|
8109
|
+
parts.map((part, index) => /* @__PURE__ */ jsx120(PartView, { part, role, onOpenArtifacts }, index)),
|
|
8033
8110
|
status === "streaming" ? /* @__PURE__ */ jsx120(StreamingText, { content: "", streaming: true }) : null
|
|
8034
8111
|
] }),
|
|
8035
|
-
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ jsx120("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1", children: actions.map((action) =>
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8112
|
+
actions.length > 0 && (status === "completed" || status === "error") ? /* @__PURE__ */ jsx120("div", { "data-slot": "chat-message-actions", className: "flex items-center gap-1 mt-2", children: actions.map((action) => {
|
|
8113
|
+
const label = action.label ?? action.name;
|
|
8114
|
+
const iconName = action.icon ?? ACTION_ICON_BY_NAME[action.name];
|
|
8115
|
+
if (iconName) {
|
|
8116
|
+
return /* @__PURE__ */ jsx120(Tooltip2, { content: label, side: "top", children: /* @__PURE__ */ jsx120(
|
|
8117
|
+
"button",
|
|
8118
|
+
{
|
|
8119
|
+
type: "button",
|
|
8120
|
+
"data-slot": "chat-message-action",
|
|
8121
|
+
"data-action": action.name,
|
|
8122
|
+
"aria-label": label,
|
|
8123
|
+
className: "flex cursor-pointer items-center rounded-sm p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
8124
|
+
onClick: () => onAction?.(action.name),
|
|
8125
|
+
children: /* @__PURE__ */ jsx120(Icon, { name: iconName, size: "sm" })
|
|
8126
|
+
}
|
|
8127
|
+
) }, action.name);
|
|
8128
|
+
}
|
|
8129
|
+
return /* @__PURE__ */ jsx120(
|
|
8130
|
+
"button",
|
|
8131
|
+
{
|
|
8132
|
+
type: "button",
|
|
8133
|
+
"data-slot": "chat-message-action",
|
|
8134
|
+
"data-action": action.name,
|
|
8135
|
+
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",
|
|
8136
|
+
onClick: () => onAction?.(action.name),
|
|
8137
|
+
children: label
|
|
8138
|
+
},
|
|
8139
|
+
action.name
|
|
8140
|
+
);
|
|
8141
|
+
}) }) : null
|
|
8050
8142
|
]
|
|
8051
8143
|
}
|
|
8052
8144
|
);
|
|
8053
8145
|
}
|
|
8054
8146
|
|
|
8055
8147
|
// src/components/chat/ChatPage/index.tsx
|
|
8056
|
-
import {
|
|
8148
|
+
import { useRenderer as useRenderer18 } from "@pactor-app/runtime";
|
|
8149
|
+
import { isValidElement as isValidElement2, useState as useState44 } from "react";
|
|
8150
|
+
|
|
8151
|
+
// src/components/chat/Composer/index.tsx
|
|
8152
|
+
import {
|
|
8153
|
+
useRef as useRef9,
|
|
8154
|
+
useState as useState42
|
|
8155
|
+
} from "react";
|
|
8156
|
+
|
|
8157
|
+
// src/components/chat/Composer/mention-input.tsx
|
|
8158
|
+
import {
|
|
8159
|
+
forwardRef,
|
|
8160
|
+
useEffect as useEffect34,
|
|
8161
|
+
useImperativeHandle,
|
|
8162
|
+
useRef as useRef8,
|
|
8163
|
+
useState as useState41
|
|
8164
|
+
} from "react";
|
|
8165
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
8166
|
+
import { Fragment as Fragment12, jsx as jsx121, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
8167
|
+
var NBSP = "\xA0";
|
|
8168
|
+
var CHIP_ATTR = "data-mention-chip";
|
|
8169
|
+
function escapeRegExp(text) {
|
|
8170
|
+
return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8171
|
+
}
|
|
8172
|
+
function isChipElement(node) {
|
|
8173
|
+
return node instanceof HTMLElement && node.hasAttribute(CHIP_ATTR);
|
|
8174
|
+
}
|
|
8175
|
+
function serializeNode(node) {
|
|
8176
|
+
let out = "";
|
|
8177
|
+
node.childNodes.forEach((child) => {
|
|
8178
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
8179
|
+
out += (child.textContent ?? "").replace(/\u00A0/g, " ");
|
|
8180
|
+
} else if (isChipElement(child)) {
|
|
8181
|
+
out += `${child.dataset["trigger"] ?? ""}${child.dataset["label"] ?? ""}`;
|
|
8182
|
+
} else if (child instanceof HTMLBRElement) {
|
|
8183
|
+
out += "\n";
|
|
8184
|
+
} else if (child instanceof HTMLElement) {
|
|
8185
|
+
const inner = serializeNode(child).replace(/\n$/, "");
|
|
8186
|
+
out += (out === "" || out.endsWith("\n") ? "" : "\n") + inner + "\n";
|
|
8187
|
+
}
|
|
8188
|
+
});
|
|
8189
|
+
return out;
|
|
8190
|
+
}
|
|
8191
|
+
function collectChips(field) {
|
|
8192
|
+
return Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).map((el) => ({
|
|
8193
|
+
id: el.dataset["id"] ?? "",
|
|
8194
|
+
label: el.dataset["label"] ?? "",
|
|
8195
|
+
trigger: el.dataset["trigger"] ?? ""
|
|
8196
|
+
}));
|
|
8197
|
+
}
|
|
8198
|
+
function detectActiveMention(field, sources) {
|
|
8199
|
+
const selection = window.getSelection();
|
|
8200
|
+
if (!selection || selection.rangeCount === 0 || !selection.isCollapsed) {
|
|
8201
|
+
return null;
|
|
8202
|
+
}
|
|
8203
|
+
const anchor = selection.anchorNode;
|
|
8204
|
+
if (!anchor || anchor.nodeType !== Node.TEXT_NODE || !field.contains(anchor)) {
|
|
8205
|
+
return null;
|
|
8206
|
+
}
|
|
8207
|
+
const caretOffset = selection.anchorOffset;
|
|
8208
|
+
const beforeCaret = (anchor.textContent ?? "").slice(0, caretOffset);
|
|
8209
|
+
for (const source of sources) {
|
|
8210
|
+
const trigger = source.trigger;
|
|
8211
|
+
const match = new RegExp(
|
|
8212
|
+
`(?:^|\\s)${escapeRegExp(trigger)}([^\\s${escapeRegExp(trigger)}]*)$`
|
|
8213
|
+
).exec(beforeCaret);
|
|
8214
|
+
if (match) {
|
|
8215
|
+
const query = match[1] ?? "";
|
|
8216
|
+
return {
|
|
8217
|
+
source,
|
|
8218
|
+
query,
|
|
8219
|
+
node: anchor,
|
|
8220
|
+
triggerStart: caretOffset - query.length - trigger.length,
|
|
8221
|
+
caretOffset
|
|
8222
|
+
};
|
|
8223
|
+
}
|
|
8224
|
+
}
|
|
8225
|
+
return null;
|
|
8226
|
+
}
|
|
8227
|
+
function chipIcon(item, source) {
|
|
8228
|
+
return item.icon ?? source.icon ?? (source.trigger === "@" ? "user" : "file-text");
|
|
8229
|
+
}
|
|
8230
|
+
var MentionInput = forwardRef(
|
|
8231
|
+
function MentionInput2({
|
|
8232
|
+
value,
|
|
8233
|
+
placeholder,
|
|
8234
|
+
disabled,
|
|
8235
|
+
sources,
|
|
8236
|
+
chips,
|
|
8237
|
+
onChipsChange,
|
|
8238
|
+
onChange,
|
|
8239
|
+
onSubmit,
|
|
8240
|
+
className,
|
|
8241
|
+
style
|
|
8242
|
+
}, ref) {
|
|
8243
|
+
const fieldRef = useRef8(null);
|
|
8244
|
+
const [menu, setMenu] = useState41(null);
|
|
8245
|
+
const [empty, setEmpty] = useState41(true);
|
|
8246
|
+
const suppressSyncRef = useRef8(false);
|
|
8247
|
+
const composingRef = useRef8(false);
|
|
8248
|
+
const emitChips = () => {
|
|
8249
|
+
if (suppressSyncRef.current || !fieldRef.current) {
|
|
8250
|
+
return;
|
|
8251
|
+
}
|
|
8252
|
+
onChipsChange?.(collectChips(fieldRef.current));
|
|
8253
|
+
};
|
|
8254
|
+
const serialize = () => fieldRef.current ? serializeNode(fieldRef.current).replace(/\n$/, "") : "";
|
|
8255
|
+
const buildChipElement = (item, source) => {
|
|
8256
|
+
const chip = document.createElement("span");
|
|
8257
|
+
chip.setAttribute(CHIP_ATTR, "");
|
|
8258
|
+
chip.dataset["id"] = item.id;
|
|
8259
|
+
chip.dataset["label"] = item.label;
|
|
8260
|
+
chip.dataset["trigger"] = item.trigger ?? source.trigger;
|
|
8261
|
+
chip.contentEditable = "false";
|
|
8262
|
+
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";
|
|
8263
|
+
const iconMarkup = renderToStaticMarkup(
|
|
8264
|
+
/* @__PURE__ */ jsx121(Icon, { name: chipIcon(item, source), size: 12 })
|
|
8265
|
+
);
|
|
8266
|
+
const label = document.createElement("span");
|
|
8267
|
+
label.textContent = item.label;
|
|
8268
|
+
chip.innerHTML = iconMarkup;
|
|
8269
|
+
chip.appendChild(label);
|
|
8270
|
+
return chip;
|
|
8271
|
+
};
|
|
8272
|
+
const insertChipElement = (item, source, replace) => {
|
|
8273
|
+
const field = fieldRef.current;
|
|
8274
|
+
if (!field) {
|
|
8275
|
+
return;
|
|
8276
|
+
}
|
|
8277
|
+
const chip = buildChipElement(item, source);
|
|
8278
|
+
let caretNode;
|
|
8279
|
+
if (replace) {
|
|
8280
|
+
const { node, start, end } = replace;
|
|
8281
|
+
const text = node.textContent ?? "";
|
|
8282
|
+
node.textContent = text.slice(0, start);
|
|
8283
|
+
caretNode = document.createTextNode(`${NBSP}${text.slice(end)}`);
|
|
8284
|
+
node.after(chip, caretNode);
|
|
8285
|
+
} else {
|
|
8286
|
+
caretNode = document.createTextNode(NBSP);
|
|
8287
|
+
const selection2 = window.getSelection();
|
|
8288
|
+
if (selection2 && selection2.rangeCount > 0 && selection2.anchorNode !== null && field.contains(selection2.anchorNode)) {
|
|
8289
|
+
const range = selection2.getRangeAt(0);
|
|
8290
|
+
range.deleteContents();
|
|
8291
|
+
range.insertNode(caretNode);
|
|
8292
|
+
range.insertNode(chip);
|
|
8293
|
+
} else {
|
|
8294
|
+
field.append(chip, caretNode);
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
const selection = window.getSelection();
|
|
8298
|
+
if (selection) {
|
|
8299
|
+
const range = document.createRange();
|
|
8300
|
+
range.setStart(caretNode, 1);
|
|
8301
|
+
range.collapse(true);
|
|
8302
|
+
selection.removeAllRanges();
|
|
8303
|
+
selection.addRange(range);
|
|
8304
|
+
}
|
|
8305
|
+
setEmpty(false);
|
|
8306
|
+
onChange?.(serialize());
|
|
8307
|
+
emitChips();
|
|
8308
|
+
};
|
|
8309
|
+
useImperativeHandle(ref, () => ({
|
|
8310
|
+
insertChip: (item, source) => {
|
|
8311
|
+
fieldRef.current?.focus();
|
|
8312
|
+
insertChipElement(item, source);
|
|
8313
|
+
},
|
|
8314
|
+
focus: () => fieldRef.current?.focus()
|
|
8315
|
+
}));
|
|
8316
|
+
useEffect34(() => {
|
|
8317
|
+
const field = fieldRef.current;
|
|
8318
|
+
if (field && value === "" && serializeNode(field).trim() !== "") {
|
|
8319
|
+
suppressSyncRef.current = true;
|
|
8320
|
+
field.innerHTML = "";
|
|
8321
|
+
setEmpty(true);
|
|
8322
|
+
setMenu(null);
|
|
8323
|
+
suppressSyncRef.current = false;
|
|
8324
|
+
}
|
|
8325
|
+
}, [value]);
|
|
8326
|
+
useEffect34(() => {
|
|
8327
|
+
const field = fieldRef.current;
|
|
8328
|
+
if (!field) {
|
|
8329
|
+
return;
|
|
8330
|
+
}
|
|
8331
|
+
const keep = new Set(chips.map((chip) => `${chip.trigger}:${chip.id}`));
|
|
8332
|
+
const stale = Array.from(field.querySelectorAll(`[${CHIP_ATTR}]`)).filter(
|
|
8333
|
+
(el) => !keep.has(
|
|
8334
|
+
`${el.dataset["trigger"]}:${el.dataset["id"]}`
|
|
8335
|
+
)
|
|
8336
|
+
);
|
|
8337
|
+
if (stale.length > 0) {
|
|
8338
|
+
suppressSyncRef.current = true;
|
|
8339
|
+
stale.forEach((el) => el.remove());
|
|
8340
|
+
suppressSyncRef.current = false;
|
|
8341
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8342
|
+
}
|
|
8343
|
+
}, [chips]);
|
|
8344
|
+
const closeMenu = () => setMenu(null);
|
|
8345
|
+
const filteredItems = (state) => state.query ? state.source.items.filter((item) => item.label.includes(state.query)) : state.source.items;
|
|
8346
|
+
const refreshMenu = () => {
|
|
8347
|
+
const field = fieldRef.current;
|
|
8348
|
+
if (!field) {
|
|
8349
|
+
return;
|
|
8350
|
+
}
|
|
8351
|
+
const active = detectActiveMention(field, sources);
|
|
8352
|
+
if (!active) {
|
|
8353
|
+
setMenu(null);
|
|
8354
|
+
return;
|
|
8355
|
+
}
|
|
8356
|
+
const range = document.createRange();
|
|
8357
|
+
range.setStart(active.node, active.triggerStart);
|
|
8358
|
+
range.setEnd(active.node, active.caretOffset);
|
|
8359
|
+
const rect = typeof range.getBoundingClientRect === "function" ? range.getBoundingClientRect() : field.getBoundingClientRect();
|
|
8360
|
+
setMenu((prev) => ({
|
|
8361
|
+
source: active.source,
|
|
8362
|
+
query: active.query,
|
|
8363
|
+
left: rect.left,
|
|
8364
|
+
top: rect.top,
|
|
8365
|
+
// 过滤结果变化后候选下标钳制在有效范围内(DSL 每次渲染产出新
|
|
8366
|
+
// props 对象,source 按 trigger 比较而非引用)
|
|
8367
|
+
activeIndex: Math.min(
|
|
8368
|
+
prev?.source.trigger === active.source.trigger ? prev.activeIndex : 0,
|
|
8369
|
+
Math.max(filteredItems({ source: active.source, query: active.query, left: 0, top: 0, activeIndex: 0 }).length - 1, 0)
|
|
8370
|
+
)
|
|
8371
|
+
}));
|
|
8372
|
+
};
|
|
8373
|
+
const selectMenuItem = (item) => {
|
|
8374
|
+
const field = fieldRef.current;
|
|
8375
|
+
if (!field || !menu) {
|
|
8376
|
+
return;
|
|
8377
|
+
}
|
|
8378
|
+
const active = detectActiveMention(field, sources);
|
|
8379
|
+
insertChipElement(
|
|
8380
|
+
{ ...item, trigger: item.trigger ?? menu.source.trigger },
|
|
8381
|
+
menu.source,
|
|
8382
|
+
active && active.source.trigger === menu.source.trigger ? { node: active.node, start: active.triggerStart, end: active.caretOffset } : void 0
|
|
8383
|
+
);
|
|
8384
|
+
setMenu(null);
|
|
8385
|
+
};
|
|
8386
|
+
const handleInput = () => {
|
|
8387
|
+
const field = fieldRef.current;
|
|
8388
|
+
if (!field) {
|
|
8389
|
+
return;
|
|
8390
|
+
}
|
|
8391
|
+
if ((field.textContent ?? "") === "" && field.querySelector(`[${CHIP_ATTR}]`) === null) {
|
|
8392
|
+
field.innerHTML = "";
|
|
8393
|
+
}
|
|
8394
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8395
|
+
onChange?.(serialize());
|
|
8396
|
+
refreshMenu();
|
|
8397
|
+
};
|
|
8398
|
+
const handleKeyDown = (event) => {
|
|
8399
|
+
if (menu) {
|
|
8400
|
+
const items = filteredItems(menu);
|
|
8401
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
8402
|
+
event.preventDefault();
|
|
8403
|
+
if (items.length > 0) {
|
|
8404
|
+
const delta = event.key === "ArrowDown" ? 1 : -1;
|
|
8405
|
+
setMenu({
|
|
8406
|
+
...menu,
|
|
8407
|
+
activeIndex: (menu.activeIndex + delta + items.length) % items.length
|
|
8408
|
+
});
|
|
8409
|
+
}
|
|
8410
|
+
return;
|
|
8411
|
+
}
|
|
8412
|
+
if (event.key === "Enter" && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
8413
|
+
event.preventDefault();
|
|
8414
|
+
const item = items[Math.min(menu.activeIndex, items.length - 1)];
|
|
8415
|
+
if (item) {
|
|
8416
|
+
selectMenuItem(item);
|
|
8417
|
+
} else {
|
|
8418
|
+
closeMenu();
|
|
8419
|
+
}
|
|
8420
|
+
return;
|
|
8421
|
+
}
|
|
8422
|
+
if (event.key === "Escape") {
|
|
8423
|
+
event.preventDefault();
|
|
8424
|
+
closeMenu();
|
|
8425
|
+
return;
|
|
8426
|
+
}
|
|
8427
|
+
}
|
|
8428
|
+
if (event.key === "Enter" && !event.shiftKey && !composingRef.current && !event.nativeEvent.isComposing) {
|
|
8429
|
+
event.preventDefault();
|
|
8430
|
+
const text = serialize();
|
|
8431
|
+
if (text.trim() !== "" && !disabled) {
|
|
8432
|
+
onSubmit?.(text);
|
|
8433
|
+
}
|
|
8434
|
+
return;
|
|
8435
|
+
}
|
|
8436
|
+
if (event.key === "Backspace") {
|
|
8437
|
+
const selection = window.getSelection();
|
|
8438
|
+
const field = fieldRef.current;
|
|
8439
|
+
if (!selection || !selection.isCollapsed || !field) {
|
|
8440
|
+
return;
|
|
8441
|
+
}
|
|
8442
|
+
let chip = null;
|
|
8443
|
+
const anchor = selection.anchorNode;
|
|
8444
|
+
if (anchor === field && selection.anchorOffset > 0) {
|
|
8445
|
+
const before = field.childNodes[selection.anchorOffset - 1];
|
|
8446
|
+
if (isChipElement(before)) {
|
|
8447
|
+
chip = before;
|
|
8448
|
+
}
|
|
8449
|
+
} else if (anchor?.nodeType === Node.TEXT_NODE && selection.anchorOffset === 0) {
|
|
8450
|
+
if (isChipElement(anchor.previousSibling)) {
|
|
8451
|
+
chip = anchor.previousSibling;
|
|
8452
|
+
}
|
|
8453
|
+
}
|
|
8454
|
+
if (chip) {
|
|
8455
|
+
event.preventDefault();
|
|
8456
|
+
chip.remove();
|
|
8457
|
+
onChange?.(serialize());
|
|
8458
|
+
emitChips();
|
|
8459
|
+
setEmpty(serializeNode(field).trim() === "");
|
|
8460
|
+
}
|
|
8461
|
+
}
|
|
8462
|
+
};
|
|
8463
|
+
const menuItems = menu ? filteredItems(menu) : [];
|
|
8464
|
+
const activeIndex = Math.min(menu?.activeIndex ?? 0, Math.max(menuItems.length - 1, 0));
|
|
8465
|
+
return /* @__PURE__ */ jsxs85("div", { className: "relative", children: [
|
|
8466
|
+
/* @__PURE__ */ jsx121(
|
|
8467
|
+
"div",
|
|
8468
|
+
{
|
|
8469
|
+
ref: fieldRef,
|
|
8470
|
+
"data-slot": "mention-input",
|
|
8471
|
+
role: "textbox",
|
|
8472
|
+
"aria-multiline": "true",
|
|
8473
|
+
"aria-placeholder": placeholder,
|
|
8474
|
+
contentEditable: !disabled,
|
|
8475
|
+
suppressContentEditableWarning: true,
|
|
8476
|
+
className: cn(
|
|
8477
|
+
"min-h-[60px] w-full px-4 pt-3 pb-1 text-sm whitespace-pre-wrap break-words outline-none",
|
|
8478
|
+
className
|
|
8479
|
+
),
|
|
8480
|
+
style,
|
|
8481
|
+
onInput: handleInput,
|
|
8482
|
+
onKeyDown: handleKeyDown,
|
|
8483
|
+
onCompositionStart: () => {
|
|
8484
|
+
composingRef.current = true;
|
|
8485
|
+
},
|
|
8486
|
+
onCompositionEnd: () => {
|
|
8487
|
+
composingRef.current = false;
|
|
8488
|
+
},
|
|
8489
|
+
onPaste: (event) => {
|
|
8490
|
+
event.preventDefault();
|
|
8491
|
+
const text = event.clipboardData?.getData("text/plain") ?? "";
|
|
8492
|
+
if (text) {
|
|
8493
|
+
document.execCommand("insertText", false, text);
|
|
8494
|
+
}
|
|
8495
|
+
}
|
|
8496
|
+
}
|
|
8497
|
+
),
|
|
8498
|
+
empty && placeholder !== void 0 ? /* @__PURE__ */ jsx121("span", { className: "pointer-events-none absolute top-3 left-4 text-sm text-muted-foreground", children: placeholder }) : null,
|
|
8499
|
+
menu ? /* @__PURE__ */ jsxs85(Fragment12, { children: [
|
|
8500
|
+
/* @__PURE__ */ jsx121(
|
|
8501
|
+
"div",
|
|
8502
|
+
{
|
|
8503
|
+
className: "fixed inset-0 z-40",
|
|
8504
|
+
onMouseDown: (event) => {
|
|
8505
|
+
event.preventDefault();
|
|
8506
|
+
closeMenu();
|
|
8507
|
+
}
|
|
8508
|
+
}
|
|
8509
|
+
),
|
|
8510
|
+
/* @__PURE__ */ jsxs85(
|
|
8511
|
+
"div",
|
|
8512
|
+
{
|
|
8513
|
+
"data-slot": "mention-menu",
|
|
8514
|
+
role: "listbox",
|
|
8515
|
+
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",
|
|
8516
|
+
style: {
|
|
8517
|
+
left: menu.left,
|
|
8518
|
+
bottom: typeof window === "undefined" ? void 0 : window.innerHeight - menu.top + 6
|
|
8519
|
+
},
|
|
8520
|
+
children: [
|
|
8521
|
+
/* @__PURE__ */ jsx121("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: menu.source.label }),
|
|
8522
|
+
menuItems.length === 0 ? /* @__PURE__ */ jsx121("div", { className: "px-2 py-2 text-xs text-muted-foreground", children: "\u65E0\u5339\u914D\u9879" }) : menuItems.map((item, index) => /* @__PURE__ */ jsxs85(
|
|
8523
|
+
"button",
|
|
8524
|
+
{
|
|
8525
|
+
type: "button",
|
|
8526
|
+
role: "option",
|
|
8527
|
+
"aria-selected": index === activeIndex,
|
|
8528
|
+
className: cn(
|
|
8529
|
+
"flex w-full cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm",
|
|
8530
|
+
index === activeIndex ? "bg-accent" : "hover:bg-accent"
|
|
8531
|
+
),
|
|
8532
|
+
onMouseDown: (event) => {
|
|
8533
|
+
event.preventDefault();
|
|
8534
|
+
selectMenuItem(item);
|
|
8535
|
+
},
|
|
8536
|
+
children: [
|
|
8537
|
+
/* @__PURE__ */ jsx121(Icon, { name: chipIcon(item, menu.source), size: "sm" }),
|
|
8538
|
+
/* @__PURE__ */ jsx121("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
8539
|
+
]
|
|
8540
|
+
},
|
|
8541
|
+
item.id
|
|
8542
|
+
))
|
|
8543
|
+
]
|
|
8544
|
+
}
|
|
8545
|
+
)
|
|
8546
|
+
] }) : null
|
|
8547
|
+
] });
|
|
8548
|
+
}
|
|
8549
|
+
);
|
|
8057
8550
|
|
|
8058
8551
|
// src/components/chat/Composer/index.tsx
|
|
8059
|
-
import { jsx as
|
|
8552
|
+
import { Fragment as Fragment13, jsx as jsx122, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
8553
|
+
var toolButtonClass3 = "flex cursor-pointer items-center rounded-md p-1.5 text-muted-foreground hover:bg-accent hover:text-foreground";
|
|
8554
|
+
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";
|
|
8555
|
+
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";
|
|
8060
8556
|
function Composer({
|
|
8061
8557
|
value,
|
|
8062
8558
|
placeholder,
|
|
@@ -8066,33 +8562,236 @@ function Composer({
|
|
|
8066
8562
|
attachments = [],
|
|
8067
8563
|
onRemoveAttachment,
|
|
8068
8564
|
onRetryAttachment,
|
|
8565
|
+
onAttachFiles,
|
|
8069
8566
|
onChange,
|
|
8070
8567
|
onSubmit,
|
|
8568
|
+
models,
|
|
8569
|
+
model,
|
|
8570
|
+
onModelChange,
|
|
8571
|
+
contexts,
|
|
8572
|
+
contextItems,
|
|
8573
|
+
onContextItemsChange,
|
|
8574
|
+
footer,
|
|
8071
8575
|
className,
|
|
8072
8576
|
style
|
|
8073
8577
|
}) {
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8578
|
+
const textControlled = value !== void 0;
|
|
8579
|
+
const [innerText, setInnerText] = useState42("");
|
|
8580
|
+
const text = textControlled ? value : innerText;
|
|
8581
|
+
const [dragOver, setDragOver] = useState42(false);
|
|
8582
|
+
const [plusOpen, setPlusOpen] = useState42(false);
|
|
8583
|
+
const [modelOpen, setModelOpen] = useState42(false);
|
|
8584
|
+
const fileInputRef = useRef9(null);
|
|
8585
|
+
const mentionRef = useRef9(null);
|
|
8586
|
+
const sources = contexts ?? [];
|
|
8587
|
+
const rich = sources.length > 0;
|
|
8588
|
+
const plusSources = sources.filter((s) => s.trigger === "+");
|
|
8589
|
+
const plusEnabled = plusSources.length > 0;
|
|
8590
|
+
const modelEnabled = models !== void 0 && models.length > 0;
|
|
8591
|
+
const currentModel = models?.find((m) => m.value === model) ?? models?.[0];
|
|
8592
|
+
const chips = contextItems ?? [];
|
|
8593
|
+
const closePopovers = () => {
|
|
8594
|
+
setPlusOpen(false);
|
|
8595
|
+
setModelOpen(false);
|
|
8596
|
+
};
|
|
8597
|
+
const handleChange = (next) => {
|
|
8598
|
+
if (!textControlled) {
|
|
8599
|
+
setInnerText(next);
|
|
8600
|
+
}
|
|
8601
|
+
onChange?.(next);
|
|
8602
|
+
};
|
|
8603
|
+
const handleSubmit = (submitted) => {
|
|
8604
|
+
onSubmit?.(submitted);
|
|
8605
|
+
if (!textControlled) {
|
|
8606
|
+
setInnerText("");
|
|
8607
|
+
}
|
|
8608
|
+
closePopovers();
|
|
8609
|
+
};
|
|
8610
|
+
const selectContext = (item, source) => {
|
|
8611
|
+
if (rich) {
|
|
8612
|
+
mentionRef.current?.insertChip(item, source);
|
|
8613
|
+
} else {
|
|
8614
|
+
const chip = { ...item, trigger: item.trigger ?? source.trigger };
|
|
8615
|
+
const duplicated = chips.some(
|
|
8616
|
+
(existing) => existing.id === chip.id && existing.trigger === chip.trigger
|
|
8617
|
+
);
|
|
8618
|
+
if (!duplicated) {
|
|
8619
|
+
onContextItemsChange?.([...chips, chip]);
|
|
8620
|
+
}
|
|
8621
|
+
}
|
|
8622
|
+
closePopovers();
|
|
8623
|
+
};
|
|
8624
|
+
const emitFiles = (files) => {
|
|
8625
|
+
if (files.length > 0 && onAttachFiles) {
|
|
8626
|
+
onAttachFiles(files);
|
|
8627
|
+
}
|
|
8628
|
+
};
|
|
8629
|
+
const handleDrop = (event) => {
|
|
8630
|
+
if (!onAttachFiles) {
|
|
8631
|
+
return;
|
|
8632
|
+
}
|
|
8633
|
+
event.preventDefault();
|
|
8634
|
+
setDragOver(false);
|
|
8635
|
+
emitFiles(Array.from(event.dataTransfer?.files ?? []));
|
|
8636
|
+
};
|
|
8637
|
+
const toolbarStart = plusEnabled || onAttachFiles ? /* @__PURE__ */ jsxs86(Fragment13, { children: [
|
|
8638
|
+
plusEnabled ? /* @__PURE__ */ jsx122(
|
|
8639
|
+
"button",
|
|
8078
8640
|
{
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8641
|
+
type: "button",
|
|
8642
|
+
"aria-label": "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
8643
|
+
title: "\u6DFB\u52A0\u4E0A\u4E0B\u6587",
|
|
8644
|
+
className: toolButtonClass3,
|
|
8645
|
+
onClick: () => {
|
|
8646
|
+
setPlusOpen((prev) => !prev);
|
|
8647
|
+
setModelOpen(false);
|
|
8648
|
+
},
|
|
8649
|
+
children: /* @__PURE__ */ jsx122(Icon, { name: "plus", size: "sm" })
|
|
8085
8650
|
}
|
|
8086
|
-
)
|
|
8087
|
-
|
|
8651
|
+
) : null,
|
|
8652
|
+
onAttachFiles ? /* @__PURE__ */ jsx122(
|
|
8653
|
+
"button",
|
|
8654
|
+
{
|
|
8655
|
+
type: "button",
|
|
8656
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
8657
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
8658
|
+
className: toolButtonClass3,
|
|
8659
|
+
onClick: () => fileInputRef.current?.click(),
|
|
8660
|
+
children: /* @__PURE__ */ jsx122(Icon, { name: "paperclip", size: "sm" })
|
|
8661
|
+
}
|
|
8662
|
+
) : null
|
|
8663
|
+
] }) : void 0;
|
|
8664
|
+
const toolbarEnd = modelEnabled ? /* @__PURE__ */ jsxs86(
|
|
8665
|
+
"button",
|
|
8666
|
+
{
|
|
8667
|
+
type: "button",
|
|
8668
|
+
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
8669
|
+
title: "\u9009\u62E9\u6A21\u578B",
|
|
8670
|
+
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",
|
|
8671
|
+
onClick: () => {
|
|
8672
|
+
setModelOpen((prev) => !prev);
|
|
8673
|
+
setPlusOpen(false);
|
|
8674
|
+
},
|
|
8675
|
+
children: [
|
|
8676
|
+
currentModel?.label,
|
|
8677
|
+
/* @__PURE__ */ jsx122(Icon, { name: "chevrons-up-down", size: 12 })
|
|
8678
|
+
]
|
|
8679
|
+
}
|
|
8680
|
+
) : void 0;
|
|
8681
|
+
const activePopover = plusOpen ? "plus" : modelOpen ? "model" : null;
|
|
8682
|
+
return /* @__PURE__ */ jsxs86(
|
|
8683
|
+
"div",
|
|
8684
|
+
{
|
|
8685
|
+
"data-slot": "composer",
|
|
8686
|
+
className: cn("relative flex w-full flex-col gap-2", className),
|
|
8687
|
+
style,
|
|
8688
|
+
onDragOver: (event) => {
|
|
8689
|
+
if (onAttachFiles) {
|
|
8690
|
+
event.preventDefault();
|
|
8691
|
+
setDragOver(true);
|
|
8692
|
+
}
|
|
8693
|
+
},
|
|
8694
|
+
onDragLeave: () => setDragOver(false),
|
|
8695
|
+
onDrop: handleDrop,
|
|
8696
|
+
onPaste: (event) => {
|
|
8697
|
+
const files = Array.from(event.clipboardData?.files ?? []);
|
|
8698
|
+
if (files.length > 0 && onAttachFiles) {
|
|
8699
|
+
event.preventDefault();
|
|
8700
|
+
emitFiles(files);
|
|
8701
|
+
}
|
|
8702
|
+
},
|
|
8703
|
+
children: [
|
|
8704
|
+
attachments.length > 0 ? /* @__PURE__ */ jsx122(Attachment, { items: attachments, onRemove: onRemoveAttachment, onRetry: onRetryAttachment }) : null,
|
|
8705
|
+
/* @__PURE__ */ jsx122("div", { className: cn(dragOver && "rounded-xl ring-2 ring-ring/50"), children: /* @__PURE__ */ jsx122(
|
|
8706
|
+
ChatInput,
|
|
8707
|
+
{
|
|
8708
|
+
value: text,
|
|
8709
|
+
placeholder,
|
|
8710
|
+
disabled: disabled || loading,
|
|
8711
|
+
rows,
|
|
8712
|
+
toolbarStart,
|
|
8713
|
+
toolbarEnd,
|
|
8714
|
+
footer,
|
|
8715
|
+
field: rich ? /* @__PURE__ */ jsx122(
|
|
8716
|
+
MentionInput,
|
|
8717
|
+
{
|
|
8718
|
+
ref: mentionRef,
|
|
8719
|
+
value: text,
|
|
8720
|
+
placeholder,
|
|
8721
|
+
disabled: disabled || loading,
|
|
8722
|
+
sources,
|
|
8723
|
+
chips,
|
|
8724
|
+
onChipsChange: onContextItemsChange,
|
|
8725
|
+
onChange: handleChange,
|
|
8726
|
+
onSubmit: handleSubmit
|
|
8727
|
+
}
|
|
8728
|
+
) : void 0,
|
|
8729
|
+
onChange: handleChange,
|
|
8730
|
+
onSubmit: handleSubmit
|
|
8731
|
+
}
|
|
8732
|
+
) }),
|
|
8733
|
+
onAttachFiles ? /* @__PURE__ */ jsx122(
|
|
8734
|
+
"input",
|
|
8735
|
+
{
|
|
8736
|
+
ref: fileInputRef,
|
|
8737
|
+
type: "file",
|
|
8738
|
+
multiple: true,
|
|
8739
|
+
hidden: true,
|
|
8740
|
+
onChange: (event) => {
|
|
8741
|
+
emitFiles(Array.from(event.target.files ?? []));
|
|
8742
|
+
event.target.value = "";
|
|
8743
|
+
}
|
|
8744
|
+
}
|
|
8745
|
+
) : null,
|
|
8746
|
+
activePopover !== null ? /* @__PURE__ */ jsxs86(Fragment13, { children: [
|
|
8747
|
+
/* @__PURE__ */ jsx122("div", { className: "fixed inset-0 z-40", onClick: closePopovers }),
|
|
8748
|
+
activePopover === "model" ? /* @__PURE__ */ jsx122("div", { "data-slot": "composer-model-popover", className: cn(popoverPanelClass, "right-0 left-auto w-48"), role: "listbox", children: models.map((option) => /* @__PURE__ */ jsxs86(
|
|
8749
|
+
"button",
|
|
8750
|
+
{
|
|
8751
|
+
type: "button",
|
|
8752
|
+
role: "option",
|
|
8753
|
+
"aria-selected": option.value === currentModel?.value,
|
|
8754
|
+
className: popoverItemClass,
|
|
8755
|
+
onClick: () => {
|
|
8756
|
+
onModelChange?.(option.value);
|
|
8757
|
+
closePopovers();
|
|
8758
|
+
},
|
|
8759
|
+
children: [
|
|
8760
|
+
/* @__PURE__ */ jsx122("span", { className: "min-w-0 flex-1 truncate", children: option.label }),
|
|
8761
|
+
option.value === currentModel?.value ? /* @__PURE__ */ jsx122(Icon, { name: "check", size: 14 }) : null
|
|
8762
|
+
]
|
|
8763
|
+
},
|
|
8764
|
+
option.value
|
|
8765
|
+
)) }) : /* @__PURE__ */ jsx122("div", { "data-slot": "composer-context-popover", className: popoverPanelClass, role: "listbox", children: plusSources.map(
|
|
8766
|
+
(source) => source.items.length === 0 ? null : /* @__PURE__ */ jsxs86("div", { children: [
|
|
8767
|
+
/* @__PURE__ */ jsx122("div", { className: "px-2 py-1 text-xs text-muted-foreground", children: source.label }),
|
|
8768
|
+
source.items.map((item) => /* @__PURE__ */ jsxs86(
|
|
8769
|
+
"button",
|
|
8770
|
+
{
|
|
8771
|
+
type: "button",
|
|
8772
|
+
className: popoverItemClass,
|
|
8773
|
+
onClick: () => selectContext(item, source),
|
|
8774
|
+
children: [
|
|
8775
|
+
/* @__PURE__ */ jsx122(Icon, { name: item.icon ?? source.icon ?? "file-text", size: "sm" }),
|
|
8776
|
+
/* @__PURE__ */ jsx122("span", { className: "min-w-0 flex-1 truncate", children: item.label })
|
|
8777
|
+
]
|
|
8778
|
+
},
|
|
8779
|
+
item.id
|
|
8780
|
+
))
|
|
8781
|
+
] }, source.trigger)
|
|
8782
|
+
) })
|
|
8783
|
+
] }) : null
|
|
8784
|
+
]
|
|
8785
|
+
}
|
|
8786
|
+
);
|
|
8088
8787
|
}
|
|
8089
8788
|
|
|
8090
8789
|
// src/components/chat/ConversationList/index.tsx
|
|
8091
|
-
import { useMemo as useMemo6, useState as
|
|
8092
|
-
import { jsx as
|
|
8790
|
+
import { useMemo as useMemo6, useState as useState43 } from "react";
|
|
8791
|
+
import { jsx as jsx123, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
8093
8792
|
function ConversationList({ items = [], activeId, searchable, onSelect, onDelete, className, style }) {
|
|
8094
|
-
const [innerActive, setInnerActive] =
|
|
8095
|
-
const [keyword, setKeyword] =
|
|
8793
|
+
const [innerActive, setInnerActive] = useState43();
|
|
8794
|
+
const [keyword, setKeyword] = useState43("");
|
|
8096
8795
|
const active = activeId ?? innerActive;
|
|
8097
8796
|
const filtered = useMemo6(() => {
|
|
8098
8797
|
const query = keyword.trim().toLowerCase();
|
|
@@ -8107,10 +8806,10 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8107
8806
|
}
|
|
8108
8807
|
onSelect?.(id);
|
|
8109
8808
|
};
|
|
8110
|
-
return /* @__PURE__ */
|
|
8111
|
-
searchable ? /* @__PURE__ */
|
|
8112
|
-
/* @__PURE__ */
|
|
8113
|
-
/* @__PURE__ */
|
|
8809
|
+
return /* @__PURE__ */ jsxs87("div", { "data-slot": "conversation-list", className: cn("flex w-full flex-col gap-1", className), style, children: [
|
|
8810
|
+
searchable ? /* @__PURE__ */ jsxs87("div", { className: "relative mb-1", children: [
|
|
8811
|
+
/* @__PURE__ */ jsx123("span", { className: "absolute top-1/2 left-2 -translate-y-1/2 text-muted-foreground", children: /* @__PURE__ */ jsx123(Icon, { name: "search", size: "sm" }) }),
|
|
8812
|
+
/* @__PURE__ */ jsx123(
|
|
8114
8813
|
"input",
|
|
8115
8814
|
{
|
|
8116
8815
|
"data-slot": "conversation-list-search",
|
|
@@ -8121,7 +8820,7 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8121
8820
|
}
|
|
8122
8821
|
)
|
|
8123
8822
|
] }) : null,
|
|
8124
|
-
filtered.map((item) => /* @__PURE__ */
|
|
8823
|
+
filtered.map((item) => /* @__PURE__ */ jsxs87(
|
|
8125
8824
|
"div",
|
|
8126
8825
|
{
|
|
8127
8826
|
"data-slot": "conversation-list-item",
|
|
@@ -8132,12 +8831,12 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8132
8831
|
),
|
|
8133
8832
|
onClick: () => select(item.id),
|
|
8134
8833
|
children: [
|
|
8135
|
-
/* @__PURE__ */
|
|
8136
|
-
/* @__PURE__ */
|
|
8137
|
-
item.description ? /* @__PURE__ */
|
|
8834
|
+
/* @__PURE__ */ jsxs87("div", { className: "min-w-0 flex-1", children: [
|
|
8835
|
+
/* @__PURE__ */ jsx123("div", { className: cn("truncate text-sm", item.id === active && "font-medium"), children: item.title }),
|
|
8836
|
+
item.description ? /* @__PURE__ */ jsx123("div", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
8138
8837
|
] }),
|
|
8139
|
-
item.time ? /* @__PURE__ */
|
|
8140
|
-
onDelete ? /* @__PURE__ */
|
|
8838
|
+
item.time ? /* @__PURE__ */ jsx123("span", { className: "shrink-0 text-xs text-muted-foreground", children: item.time }) : null,
|
|
8839
|
+
onDelete ? /* @__PURE__ */ jsx123(
|
|
8141
8840
|
"button",
|
|
8142
8841
|
{
|
|
8143
8842
|
type: "button",
|
|
@@ -8148,41 +8847,42 @@ function ConversationList({ items = [], activeId, searchable, onSelect, onDelete
|
|
|
8148
8847
|
event.stopPropagation();
|
|
8149
8848
|
onDelete(item.id);
|
|
8150
8849
|
},
|
|
8151
|
-
children: /* @__PURE__ */
|
|
8850
|
+
children: /* @__PURE__ */ jsx123(Icon, { name: "trash-2", size: "sm" })
|
|
8152
8851
|
}
|
|
8153
8852
|
) : null
|
|
8154
8853
|
]
|
|
8155
8854
|
},
|
|
8156
8855
|
item.id
|
|
8157
8856
|
)),
|
|
8158
|
-
filtered.length === 0 ? /* @__PURE__ */
|
|
8857
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx123("div", { className: "px-2 py-4 text-center text-sm text-muted-foreground", children: "\u65E0\u5339\u914D\u4F1A\u8BDD" }) : null
|
|
8159
8858
|
] });
|
|
8160
8859
|
}
|
|
8161
8860
|
|
|
8162
8861
|
// src/components/chat/MessageList/index.tsx
|
|
8163
|
-
import { useEffect as
|
|
8164
|
-
import { jsx as
|
|
8165
|
-
function MessageList({ messages = [], autoScroll = true, onAction, className, style }) {
|
|
8166
|
-
const listRef =
|
|
8167
|
-
|
|
8862
|
+
import { useEffect as useEffect35, useRef as useRef10 } from "react";
|
|
8863
|
+
import { jsx as jsx124 } from "react/jsx-runtime";
|
|
8864
|
+
function MessageList({ messages = [], autoScroll = true, onAction, onOpenArtifacts, className, style }) {
|
|
8865
|
+
const listRef = useRef10(null);
|
|
8866
|
+
useEffect35(() => {
|
|
8168
8867
|
if (!autoScroll) return;
|
|
8169
8868
|
const el = listRef.current;
|
|
8170
8869
|
if (el) {
|
|
8171
8870
|
el.scrollTop = el.scrollHeight;
|
|
8172
8871
|
}
|
|
8173
8872
|
}, [messages, autoScroll]);
|
|
8174
|
-
return /* @__PURE__ */
|
|
8873
|
+
return /* @__PURE__ */ jsx124(
|
|
8175
8874
|
"div",
|
|
8176
8875
|
{
|
|
8177
8876
|
ref: listRef,
|
|
8178
8877
|
"data-slot": "message-list",
|
|
8179
8878
|
className: cn("flex w-full flex-col gap-4 overflow-y-auto", className),
|
|
8180
8879
|
style,
|
|
8181
|
-
children: messages.map((message, index) => /* @__PURE__ */
|
|
8880
|
+
children: messages.map((message, index) => /* @__PURE__ */ jsx124(
|
|
8182
8881
|
ChatMessage,
|
|
8183
8882
|
{
|
|
8184
8883
|
...message,
|
|
8185
|
-
onAction: (action) => onAction?.({ id: message.id, action })
|
|
8884
|
+
onAction: (action) => onAction?.({ id: message.id, action }),
|
|
8885
|
+
onOpenArtifacts: onOpenArtifacts ? () => onOpenArtifacts({ id: message.id }) : void 0
|
|
8186
8886
|
},
|
|
8187
8887
|
message.id ?? index
|
|
8188
8888
|
))
|
|
@@ -8191,9 +8891,9 @@ function MessageList({ messages = [], autoScroll = true, onAction, className, st
|
|
|
8191
8891
|
}
|
|
8192
8892
|
|
|
8193
8893
|
// src/components/chat/Prompt/index.tsx
|
|
8194
|
-
import { jsx as
|
|
8894
|
+
import { jsx as jsx125, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
8195
8895
|
function Prompt({ title, description, icon, value, disabled, onSelect, className, style }) {
|
|
8196
|
-
return /* @__PURE__ */
|
|
8896
|
+
return /* @__PURE__ */ jsxs88(
|
|
8197
8897
|
"button",
|
|
8198
8898
|
{
|
|
8199
8899
|
type: "button",
|
|
@@ -8206,10 +8906,10 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
8206
8906
|
style,
|
|
8207
8907
|
onClick: () => onSelect?.(value ?? title ?? ""),
|
|
8208
8908
|
children: [
|
|
8209
|
-
icon ? /* @__PURE__ */
|
|
8210
|
-
/* @__PURE__ */
|
|
8211
|
-
/* @__PURE__ */
|
|
8212
|
-
description ? /* @__PURE__ */
|
|
8909
|
+
icon ? /* @__PURE__ */ jsx125("span", { className: "mt-0.5 shrink-0 text-primary", children: /* @__PURE__ */ jsx125(Icon, { name: icon, size: "sm" }) }) : null,
|
|
8910
|
+
/* @__PURE__ */ jsxs88("span", { className: "min-w-0", children: [
|
|
8911
|
+
/* @__PURE__ */ jsx125("span", { "data-slot": "prompt-title", className: "block text-sm font-medium", children: title }),
|
|
8912
|
+
description ? /* @__PURE__ */ jsx125("span", { "data-slot": "prompt-description", className: "mt-0.5 block text-xs text-muted-foreground", children: description }) : null
|
|
8213
8913
|
] })
|
|
8214
8914
|
]
|
|
8215
8915
|
}
|
|
@@ -8217,7 +8917,7 @@ function Prompt({ title, description, icon, value, disabled, onSelect, className
|
|
|
8217
8917
|
}
|
|
8218
8918
|
|
|
8219
8919
|
// src/components/chat/Welcome/index.tsx
|
|
8220
|
-
import { jsx as
|
|
8920
|
+
import { jsx as jsx126, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
8221
8921
|
function Welcome({
|
|
8222
8922
|
title = "\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F",
|
|
8223
8923
|
description,
|
|
@@ -8227,19 +8927,19 @@ function Welcome({
|
|
|
8227
8927
|
className,
|
|
8228
8928
|
style
|
|
8229
8929
|
}) {
|
|
8230
|
-
return /* @__PURE__ */
|
|
8930
|
+
return /* @__PURE__ */ jsxs89(
|
|
8231
8931
|
"div",
|
|
8232
8932
|
{
|
|
8233
8933
|
"data-slot": "welcome",
|
|
8234
8934
|
className: cn("flex w-full flex-col items-center gap-4 py-10 text-center", className),
|
|
8235
8935
|
style,
|
|
8236
8936
|
children: [
|
|
8237
|
-
/* @__PURE__ */
|
|
8238
|
-
/* @__PURE__ */
|
|
8239
|
-
/* @__PURE__ */
|
|
8240
|
-
description ? /* @__PURE__ */
|
|
8937
|
+
/* @__PURE__ */ jsx126("span", { "data-slot": "welcome-icon", className: "text-primary", children: /* @__PURE__ */ jsx126(Icon, { name: icon, size: "lg" }) }),
|
|
8938
|
+
/* @__PURE__ */ jsxs89("div", { children: [
|
|
8939
|
+
/* @__PURE__ */ jsx126("div", { "data-slot": "welcome-title", className: "text-xl font-semibold", children: title }),
|
|
8940
|
+
description ? /* @__PURE__ */ jsx126("div", { "data-slot": "welcome-description", className: "mt-1 text-sm text-muted-foreground", children: description }) : null
|
|
8241
8941
|
] }),
|
|
8242
|
-
prompts.length > 0 ? /* @__PURE__ */
|
|
8942
|
+
prompts.length > 0 ? /* @__PURE__ */ jsx126("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__ */ jsx126(
|
|
8243
8943
|
Prompt,
|
|
8244
8944
|
{
|
|
8245
8945
|
title: item.title,
|
|
@@ -8256,7 +8956,7 @@ function Welcome({
|
|
|
8256
8956
|
}
|
|
8257
8957
|
|
|
8258
8958
|
// src/components/chat/ChatPage/index.tsx
|
|
8259
|
-
import { jsx as
|
|
8959
|
+
import { jsx as jsx127, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
8260
8960
|
function ChatPage({
|
|
8261
8961
|
brand,
|
|
8262
8962
|
menuItems = [],
|
|
@@ -8282,12 +8982,26 @@ function ChatPage({
|
|
|
8282
8982
|
defaultFooterSectionCollapsed = false,
|
|
8283
8983
|
onFooterSectionToggle,
|
|
8284
8984
|
conversationTitle,
|
|
8985
|
+
conversationHeaderAction,
|
|
8986
|
+
onConversationHeaderAction,
|
|
8285
8987
|
messages = [],
|
|
8286
8988
|
sending,
|
|
8287
8989
|
composerPlaceholder,
|
|
8288
8990
|
welcome,
|
|
8289
8991
|
onSend,
|
|
8290
8992
|
onMessageAction,
|
|
8993
|
+
models,
|
|
8994
|
+
model,
|
|
8995
|
+
onModelChange,
|
|
8996
|
+
contexts,
|
|
8997
|
+
contextItems,
|
|
8998
|
+
onContextItemsChange,
|
|
8999
|
+
attachments,
|
|
9000
|
+
onAttachFiles,
|
|
9001
|
+
onRemoveAttachment,
|
|
9002
|
+
onRetryAttachment,
|
|
9003
|
+
composerFooter,
|
|
9004
|
+
composerBottom,
|
|
8291
9005
|
artifactTitle = "\u4EA7\u7269",
|
|
8292
9006
|
artifacts = [],
|
|
8293
9007
|
activeArtifactId,
|
|
@@ -8298,20 +9012,22 @@ function ChatPage({
|
|
|
8298
9012
|
artifactViewers,
|
|
8299
9013
|
onDownloadArtifact,
|
|
8300
9014
|
artifactOpen,
|
|
8301
|
-
defaultArtifactOpen =
|
|
9015
|
+
defaultArtifactOpen = false,
|
|
8302
9016
|
onArtifactOpenChange,
|
|
8303
9017
|
className,
|
|
8304
9018
|
style
|
|
8305
9019
|
}) {
|
|
8306
9020
|
const controlled = artifactOpen !== void 0;
|
|
8307
|
-
const [innerOpen, setInnerOpen] =
|
|
9021
|
+
const [innerOpen, setInnerOpen] = useState44(defaultArtifactOpen);
|
|
8308
9022
|
const open = controlled ? artifactOpen === true : innerOpen;
|
|
8309
9023
|
const setOpen = (next) => {
|
|
8310
9024
|
if (!controlled) setInnerOpen(next);
|
|
8311
9025
|
onArtifactOpenChange?.(next);
|
|
8312
9026
|
};
|
|
9027
|
+
const { renderChildren } = useRenderer18();
|
|
9028
|
+
const renderSlot = (slot) => isValidElement2(slot) || typeof slot !== "object" || slot === null ? slot : renderChildren([slot]);
|
|
8313
9029
|
const convCollControlled = conversationSectionCollapsed !== void 0;
|
|
8314
|
-
const [convCollapsedInner, setConvCollapsedInner] =
|
|
9030
|
+
const [convCollapsedInner, setConvCollapsedInner] = useState44(
|
|
8315
9031
|
defaultConversationSectionCollapsed
|
|
8316
9032
|
);
|
|
8317
9033
|
const convCollapsed = convCollControlled ? conversationSectionCollapsed === true : convCollapsedInner;
|
|
@@ -8321,7 +9037,7 @@ function ChatPage({
|
|
|
8321
9037
|
onConversationSectionToggle?.(next);
|
|
8322
9038
|
};
|
|
8323
9039
|
const footerCollControlled = footerSectionCollapsed !== void 0;
|
|
8324
|
-
const [footerCollapsedInner, setFooterCollapsedInner] =
|
|
9040
|
+
const [footerCollapsedInner, setFooterCollapsedInner] = useState44(
|
|
8325
9041
|
defaultFooterSectionCollapsed
|
|
8326
9042
|
);
|
|
8327
9043
|
const footerCollapsed = footerCollControlled ? footerSectionCollapsed === true : footerCollapsedInner;
|
|
@@ -8331,7 +9047,7 @@ function ChatPage({
|
|
|
8331
9047
|
onFooterSectionToggle?.(next);
|
|
8332
9048
|
};
|
|
8333
9049
|
const railVisible = railItems.length > 0 || railFooterItems.length > 0;
|
|
8334
|
-
const railButton = (item) => /* @__PURE__ */
|
|
9050
|
+
const railButton = (item) => /* @__PURE__ */ jsx127(Tooltip2, { content: item.label, side: "right", children: /* @__PURE__ */ jsx127(
|
|
8335
9051
|
Button2,
|
|
8336
9052
|
{
|
|
8337
9053
|
icon: item.icon,
|
|
@@ -8339,17 +9055,25 @@ function ChatPage({
|
|
|
8339
9055
|
onClick: () => onMenuSelect?.(item.key)
|
|
8340
9056
|
}
|
|
8341
9057
|
) }, item.key);
|
|
8342
|
-
const chatArea = /* @__PURE__ */
|
|
8343
|
-
/* @__PURE__ */
|
|
9058
|
+
const chatArea = /* @__PURE__ */ jsxs90("div", { "data-slot": "chat-page-conversation", className: "flex h-full min-w-0 flex-1 flex-col", children: [
|
|
9059
|
+
/* @__PURE__ */ jsxs90(
|
|
8344
9060
|
"div",
|
|
8345
9061
|
{
|
|
8346
9062
|
className: "flex shrink-0 items-center justify-between border-b border-border px-4 py-2.5",
|
|
8347
9063
|
children: [
|
|
8348
|
-
/* @__PURE__ */
|
|
8349
|
-
/* @__PURE__ */
|
|
9064
|
+
/* @__PURE__ */ jsx127(Text, { text: conversationTitle, strong: true }),
|
|
9065
|
+
conversationHeaderAction ? /* @__PURE__ */ jsx127(Tooltip2, { content: conversationHeaderAction.tooltip ?? conversationHeaderAction.label, side: "bottom", children: /* @__PURE__ */ jsx127(
|
|
9066
|
+
Button2,
|
|
9067
|
+
{
|
|
9068
|
+
text: conversationHeaderAction.label,
|
|
9069
|
+
icon: conversationHeaderAction.icon,
|
|
9070
|
+
variant: "text",
|
|
9071
|
+
onClick: () => onConversationHeaderAction?.()
|
|
9072
|
+
}
|
|
9073
|
+
) }) : /* @__PURE__ */ jsx127(Tooltip2, { content: open ? "\u6536\u8D77\u4EA7\u7269\u533A" : artifactTitle, side: "bottom", children: /* @__PURE__ */ jsx127(
|
|
8350
9074
|
Button2,
|
|
8351
9075
|
{
|
|
8352
|
-
icon: "panel-right-open",
|
|
9076
|
+
icon: open ? "panel-right-close" : "panel-right-open",
|
|
8353
9077
|
variant: "text",
|
|
8354
9078
|
onClick: () => setOpen(!open)
|
|
8355
9079
|
}
|
|
@@ -8357,40 +9081,63 @@ function ChatPage({
|
|
|
8357
9081
|
]
|
|
8358
9082
|
}
|
|
8359
9083
|
),
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
{
|
|
8363
|
-
title: welcome?.title,
|
|
8364
|
-
description: welcome?.description,
|
|
8365
|
-
prompts: welcome?.prompts,
|
|
8366
|
-
style: { flex: 1 },
|
|
8367
|
-
onSelect: (value) => onSend?.(value)
|
|
8368
|
-
}
|
|
8369
|
-
) : /* @__PURE__ */ jsx126(
|
|
8370
|
-
MessageList,
|
|
8371
|
-
{
|
|
8372
|
-
messages,
|
|
8373
|
-
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
8374
|
-
onAction: onMessageAction
|
|
8375
|
-
}
|
|
8376
|
-
),
|
|
8377
|
-
/* @__PURE__ */ jsx126(
|
|
8378
|
-
Composer,
|
|
9084
|
+
/* @__PURE__ */ jsxs90(
|
|
9085
|
+
"div",
|
|
8379
9086
|
{
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
9087
|
+
"data-slot": "chat-page-conversation-body",
|
|
9088
|
+
className: "mx-auto flex min-h-0 w-[61.8cqw] max-w-full flex-1 flex-col",
|
|
9089
|
+
children: [
|
|
9090
|
+
messages.length === 0 ? /* @__PURE__ */ jsx127(
|
|
9091
|
+
Welcome,
|
|
9092
|
+
{
|
|
9093
|
+
title: welcome?.title,
|
|
9094
|
+
description: welcome?.description,
|
|
9095
|
+
prompts: welcome?.prompts,
|
|
9096
|
+
style: { flex: 1 },
|
|
9097
|
+
onSelect: (value) => onSend?.(value)
|
|
9098
|
+
}
|
|
9099
|
+
) : /* @__PURE__ */ jsx127(
|
|
9100
|
+
MessageList,
|
|
9101
|
+
{
|
|
9102
|
+
messages,
|
|
9103
|
+
className: "scrollbar-subtle",
|
|
9104
|
+
style: { flex: 1, minHeight: 0, padding: 16 },
|
|
9105
|
+
onAction: onMessageAction,
|
|
9106
|
+
onOpenArtifacts: () => setOpen(true)
|
|
9107
|
+
}
|
|
9108
|
+
),
|
|
9109
|
+
/* @__PURE__ */ jsx127(
|
|
9110
|
+
Composer,
|
|
9111
|
+
{
|
|
9112
|
+
placeholder: composerPlaceholder,
|
|
9113
|
+
loading: sending,
|
|
9114
|
+
models,
|
|
9115
|
+
model,
|
|
9116
|
+
contexts,
|
|
9117
|
+
contextItems,
|
|
9118
|
+
attachments,
|
|
9119
|
+
footer: composerFooter,
|
|
9120
|
+
style: { padding: 16, paddingBottom: composerBottom ? 8 : 16, flexShrink: 0 },
|
|
9121
|
+
onModelChange,
|
|
9122
|
+
onContextItemsChange,
|
|
9123
|
+
onAttachFiles,
|
|
9124
|
+
onRemoveAttachment,
|
|
9125
|
+
onRetryAttachment,
|
|
9126
|
+
onSubmit: (text) => onSend?.(text)
|
|
9127
|
+
}
|
|
9128
|
+
),
|
|
9129
|
+
composerBottom ? /* @__PURE__ */ jsx127("div", { "data-slot": "chat-page-composer-bottom", className: "shrink-0 px-4 pb-2 text-center", children: renderSlot(composerBottom) }) : null
|
|
9130
|
+
]
|
|
8384
9131
|
}
|
|
8385
9132
|
)
|
|
8386
9133
|
] });
|
|
8387
9134
|
const activeArtifact = artifacts.find((item) => item.id === activeArtifactId) ?? (activeArtifactId === void 0 || activeArtifactId === "" ? artifacts[artifacts.length - 1] : void 0);
|
|
8388
|
-
const artifactPanel = /* @__PURE__ */
|
|
9135
|
+
const artifactPanel = /* @__PURE__ */ jsx127(
|
|
8389
9136
|
"div",
|
|
8390
9137
|
{
|
|
8391
9138
|
"data-slot": "chat-page-artifact",
|
|
8392
9139
|
className: "flex h-full min-w-0 flex-col border-l border-border bg-muted",
|
|
8393
|
-
children: /* @__PURE__ */
|
|
9140
|
+
children: /* @__PURE__ */ jsx127(
|
|
8394
9141
|
ArtifactPanel,
|
|
8395
9142
|
{
|
|
8396
9143
|
artifact: activeArtifact,
|
|
@@ -8408,37 +9155,37 @@ function ChatPage({
|
|
|
8408
9155
|
)
|
|
8409
9156
|
}
|
|
8410
9157
|
);
|
|
8411
|
-
return /* @__PURE__ */
|
|
9158
|
+
return /* @__PURE__ */ jsxs90(
|
|
8412
9159
|
"div",
|
|
8413
9160
|
{
|
|
8414
9161
|
"data-slot": "chat-page",
|
|
8415
9162
|
className: cn("flex w-full overflow-hidden", className),
|
|
8416
9163
|
style: { height: "100vh", ...style },
|
|
8417
9164
|
children: [
|
|
8418
|
-
railVisible ? /* @__PURE__ */
|
|
9165
|
+
railVisible ? /* @__PURE__ */ jsxs90(
|
|
8419
9166
|
"div",
|
|
8420
9167
|
{
|
|
8421
9168
|
"data-slot": "chat-page-rail",
|
|
8422
9169
|
className: "flex h-full w-[52px] shrink-0 flex-col items-center gap-1 border-r border-border py-2.5",
|
|
8423
9170
|
children: [
|
|
8424
9171
|
railItems.map(railButton),
|
|
8425
|
-
/* @__PURE__ */
|
|
9172
|
+
/* @__PURE__ */ jsx127("div", { className: "flex-1" }),
|
|
8426
9173
|
railFooterItems.map(railButton)
|
|
8427
9174
|
]
|
|
8428
9175
|
}
|
|
8429
9176
|
) : null,
|
|
8430
|
-
/* @__PURE__ */
|
|
9177
|
+
/* @__PURE__ */ jsxs90(
|
|
8431
9178
|
"div",
|
|
8432
9179
|
{
|
|
8433
9180
|
"data-slot": "chat-page-menu",
|
|
8434
|
-
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-
|
|
9181
|
+
className: "flex h-full w-[264px] shrink-0 flex-col gap-2 overflow-hidden border-r border-border px-2 py-3",
|
|
8435
9182
|
children: [
|
|
8436
|
-
brand ? /* @__PURE__ */
|
|
8437
|
-
/* @__PURE__ */
|
|
8438
|
-
/* @__PURE__ */
|
|
8439
|
-
brand.version !== void 0 ? /* @__PURE__ */
|
|
9183
|
+
brand ? /* @__PURE__ */ jsxs90("div", { className: "flex shrink-0 items-center justify-between px-2", children: [
|
|
9184
|
+
/* @__PURE__ */ jsxs90("div", { className: "flex flex-col gap-0.5", children: [
|
|
9185
|
+
/* @__PURE__ */ jsx127(Text, { text: brand.title, strong: true, size: "large" }),
|
|
9186
|
+
brand.version !== void 0 ? /* @__PURE__ */ jsx127(Text, { text: brand.version, type: "secondary", size: "small" }) : null
|
|
8440
9187
|
] }),
|
|
8441
|
-
menuAction ? /* @__PURE__ */
|
|
9188
|
+
menuAction ? /* @__PURE__ */ jsx127(
|
|
8442
9189
|
Button2,
|
|
8443
9190
|
{
|
|
8444
9191
|
text: menuAction.label,
|
|
@@ -8448,24 +9195,24 @@ function ChatPage({
|
|
|
8448
9195
|
}
|
|
8449
9196
|
) : null
|
|
8450
9197
|
] }) : null,
|
|
8451
|
-
/* @__PURE__ */
|
|
9198
|
+
/* @__PURE__ */ jsx127("div", { className: "scrollbar-subtle max-h-[40%] min-h-0 shrink-0 overflow-y-auto", children: /* @__PURE__ */ jsx127(
|
|
8452
9199
|
Menu,
|
|
8453
9200
|
{
|
|
8454
9201
|
items: menuItems,
|
|
8455
9202
|
selectedKey: activeMenuKey,
|
|
8456
9203
|
onSelect: (key) => onMenuSelect?.(key)
|
|
8457
9204
|
}
|
|
8458
|
-
),
|
|
8459
|
-
conversationSectionTitle !== void 0 ? /* @__PURE__ */
|
|
9205
|
+
) }),
|
|
9206
|
+
conversationSectionTitle !== void 0 ? /* @__PURE__ */ jsxs90(
|
|
8460
9207
|
"button",
|
|
8461
9208
|
{
|
|
8462
9209
|
type: "button",
|
|
8463
9210
|
"data-slot": "chat-page-section-toggle",
|
|
8464
9211
|
"aria-expanded": !convCollapsed,
|
|
8465
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
9212
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
8466
9213
|
onClick: toggleConvSection,
|
|
8467
9214
|
children: [
|
|
8468
|
-
/* @__PURE__ */
|
|
9215
|
+
/* @__PURE__ */ jsx127(
|
|
8469
9216
|
Text,
|
|
8470
9217
|
{
|
|
8471
9218
|
text: `${conversationSectionTitle} (${conversations.length})`,
|
|
@@ -8474,48 +9221,50 @@ function ChatPage({
|
|
|
8474
9221
|
strong: true
|
|
8475
9222
|
}
|
|
8476
9223
|
),
|
|
8477
|
-
/* @__PURE__ */
|
|
9224
|
+
/* @__PURE__ */ jsx127(Icon, { name: convCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
8478
9225
|
]
|
|
8479
9226
|
}
|
|
8480
9227
|
) : null,
|
|
8481
|
-
!convCollapsed ? /* @__PURE__ */
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
9228
|
+
!convCollapsed ? /* @__PURE__ */ jsxs90("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle flex min-h-0 flex-1 flex-col overflow-y-auto", children: [
|
|
9229
|
+
/* @__PURE__ */ jsx127(
|
|
9230
|
+
ConversationList,
|
|
9231
|
+
{
|
|
9232
|
+
items: conversations,
|
|
9233
|
+
activeId: activeConversationId,
|
|
9234
|
+
onSelect: (id) => onSelectConversation?.(id),
|
|
9235
|
+
onDelete: (id) => onDeleteConversation?.(id)
|
|
9236
|
+
}
|
|
9237
|
+
),
|
|
9238
|
+
moreLabel !== void 0 ? /* @__PURE__ */ jsx127("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx127(Button2, { text: `${moreLabel} >>`, variant: "link", size: "small", onClick: () => onMore?.() }) }) : null
|
|
9239
|
+
] }) : null,
|
|
9240
|
+
footerSectionTitle !== void 0 ? /* @__PURE__ */ jsxs90(
|
|
8492
9241
|
"button",
|
|
8493
9242
|
{
|
|
8494
9243
|
type: "button",
|
|
8495
9244
|
"data-slot": "chat-page-section-toggle",
|
|
8496
9245
|
"aria-expanded": !footerCollapsed,
|
|
8497
|
-
className: "flex w-full cursor-pointer items-center justify-between px-2 pt-2",
|
|
9246
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-between px-2 pt-2",
|
|
8498
9247
|
onClick: toggleFooterSection,
|
|
8499
9248
|
children: [
|
|
8500
|
-
/* @__PURE__ */
|
|
8501
|
-
/* @__PURE__ */
|
|
9249
|
+
/* @__PURE__ */ jsx127(Text, { text: footerSectionTitle, type: "secondary", className: "text-sm", strong: true }),
|
|
9250
|
+
/* @__PURE__ */ jsx127(Icon, { name: footerCollapsed ? "chevron-right" : "chevron-down", size: 14 })
|
|
8502
9251
|
]
|
|
8503
9252
|
}
|
|
8504
9253
|
) : null,
|
|
8505
|
-
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */
|
|
9254
|
+
!footerCollapsed && footerItems.length > 0 ? /* @__PURE__ */ jsx127("div", { "data-slot": "chat-page-section-body", className: "scrollbar-subtle min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx127(
|
|
8506
9255
|
Menu,
|
|
8507
9256
|
{
|
|
8508
9257
|
items: footerItems,
|
|
8509
9258
|
onSelect: (key) => onMenuSelect?.(key)
|
|
8510
9259
|
}
|
|
8511
|
-
) : null
|
|
9260
|
+
) }) : null
|
|
8512
9261
|
]
|
|
8513
9262
|
}
|
|
8514
9263
|
),
|
|
8515
|
-
/* @__PURE__ */
|
|
8516
|
-
/* @__PURE__ */
|
|
8517
|
-
/* @__PURE__ */
|
|
8518
|
-
/* @__PURE__ */
|
|
9264
|
+
/* @__PURE__ */ jsx127("div", { className: "@container h-full min-w-0 flex-1", children: open ? /* @__PURE__ */ jsxs90(PanelGroup, { orientation: "horizontal", style: { width: "100%", height: "100%" }, children: [
|
|
9265
|
+
/* @__PURE__ */ jsx127(Panel, { defaultSize: "62%", children: chatArea }),
|
|
9266
|
+
/* @__PURE__ */ jsx127(ResizableHandle, { withHandle: true }),
|
|
9267
|
+
/* @__PURE__ */ jsx127(Panel, { defaultSize: "38%", minSize: "380px", maxSize: "760px", children: artifactPanel })
|
|
8519
9268
|
] }) : chatArea })
|
|
8520
9269
|
]
|
|
8521
9270
|
}
|
|
@@ -8523,10 +9272,10 @@ function ChatPage({
|
|
|
8523
9272
|
}
|
|
8524
9273
|
|
|
8525
9274
|
// src/components/chat/Citation/index.tsx
|
|
8526
|
-
import { jsx as
|
|
9275
|
+
import { jsx as jsx128, jsxs as jsxs91 } from "react/jsx-runtime";
|
|
8527
9276
|
function Citation({ items = [], start = 1, className, style }) {
|
|
8528
|
-
return /* @__PURE__ */
|
|
8529
|
-
/* @__PURE__ */
|
|
9277
|
+
return /* @__PURE__ */ jsx128("span", { "data-slot": "citation", className: cn("inline-flex gap-1 align-super", className), style, children: items.map((item, index) => /* @__PURE__ */ jsxs91(HoverCard, { children: [
|
|
9278
|
+
/* @__PURE__ */ jsxs91(
|
|
8530
9279
|
HoverCardTrigger,
|
|
8531
9280
|
{
|
|
8532
9281
|
"data-slot": "citation-marker",
|
|
@@ -8538,10 +9287,10 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
8538
9287
|
]
|
|
8539
9288
|
}
|
|
8540
9289
|
),
|
|
8541
|
-
/* @__PURE__ */
|
|
8542
|
-
/* @__PURE__ */
|
|
8543
|
-
item.snippet ? /* @__PURE__ */
|
|
8544
|
-
item.url ? /* @__PURE__ */
|
|
9290
|
+
/* @__PURE__ */ jsxs91(HoverCardContent, { "data-slot": "citation-card", className: "w-72", children: [
|
|
9291
|
+
/* @__PURE__ */ jsx128("div", { className: "text-sm font-medium", children: item.title }),
|
|
9292
|
+
item.snippet ? /* @__PURE__ */ jsx128("div", { className: "mt-1 line-clamp-3 text-xs text-muted-foreground", children: item.snippet }) : null,
|
|
9293
|
+
item.url ? /* @__PURE__ */ jsx128(
|
|
8545
9294
|
"a",
|
|
8546
9295
|
{
|
|
8547
9296
|
href: item.url,
|
|
@@ -8556,13 +9305,13 @@ function Citation({ items = [], start = 1, className, style }) {
|
|
|
8556
9305
|
}
|
|
8557
9306
|
|
|
8558
9307
|
// src/components/chat/Suggestion/index.tsx
|
|
8559
|
-
import { jsx as
|
|
9308
|
+
import { jsx as jsx129, jsxs as jsxs92 } from "react/jsx-runtime";
|
|
8560
9309
|
function normalize(item) {
|
|
8561
9310
|
if (typeof item === "string") return { label: item, value: item };
|
|
8562
9311
|
return { label: item.label, value: item.value ?? item.label, icon: item.icon };
|
|
8563
9312
|
}
|
|
8564
9313
|
function Suggestion({ items = [], justify = "start", onSelect, className, style }) {
|
|
8565
|
-
return /* @__PURE__ */
|
|
9314
|
+
return /* @__PURE__ */ jsx129(
|
|
8566
9315
|
"div",
|
|
8567
9316
|
{
|
|
8568
9317
|
"data-slot": "suggestion",
|
|
@@ -8570,7 +9319,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8570
9319
|
style,
|
|
8571
9320
|
children: items.map((item, index) => {
|
|
8572
9321
|
const { label, value, icon } = normalize(item);
|
|
8573
|
-
return /* @__PURE__ */
|
|
9322
|
+
return /* @__PURE__ */ jsxs92(
|
|
8574
9323
|
"button",
|
|
8575
9324
|
{
|
|
8576
9325
|
type: "button",
|
|
@@ -8579,7 +9328,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8579
9328
|
className: "flex items-center gap-1.5 rounded-full border border-border px-3 py-1 text-sm transition-colors hover:bg-accent",
|
|
8580
9329
|
onClick: () => onSelect?.(value),
|
|
8581
9330
|
children: [
|
|
8582
|
-
icon ? /* @__PURE__ */
|
|
9331
|
+
icon ? /* @__PURE__ */ jsx129(Icon, { name: icon, size: "sm" }) : null,
|
|
8583
9332
|
label
|
|
8584
9333
|
]
|
|
8585
9334
|
},
|
|
@@ -8591,7 +9340,7 @@ function Suggestion({ items = [], justify = "start", onSelect, className, style
|
|
|
8591
9340
|
}
|
|
8592
9341
|
|
|
8593
9342
|
// src/components/chart/EChartBase/index.tsx
|
|
8594
|
-
import { useEffect as
|
|
9343
|
+
import { useEffect as useEffect36, useRef as useRef11, useState as useState45 } from "react";
|
|
8595
9344
|
|
|
8596
9345
|
// src/components/chart/echarts-modules.ts
|
|
8597
9346
|
import * as echarts from "echarts/core";
|
|
@@ -8643,7 +9392,7 @@ echarts.use([
|
|
|
8643
9392
|
]);
|
|
8644
9393
|
|
|
8645
9394
|
// src/components/chart/EChartBase/index.tsx
|
|
8646
|
-
import { jsx as
|
|
9395
|
+
import { jsx as jsx130 } from "react/jsx-runtime";
|
|
8647
9396
|
function EChartBase({
|
|
8648
9397
|
option,
|
|
8649
9398
|
height = 256,
|
|
@@ -8652,12 +9401,12 @@ function EChartBase({
|
|
|
8652
9401
|
style,
|
|
8653
9402
|
slot
|
|
8654
9403
|
}) {
|
|
8655
|
-
const hostRef =
|
|
8656
|
-
const chartRef =
|
|
8657
|
-
const onSelectRef =
|
|
9404
|
+
const hostRef = useRef11(null);
|
|
9405
|
+
const chartRef = useRef11(null);
|
|
9406
|
+
const onSelectRef = useRef11(onSelect);
|
|
8658
9407
|
onSelectRef.current = onSelect;
|
|
8659
|
-
const [failed, setFailed] =
|
|
8660
|
-
|
|
9408
|
+
const [failed, setFailed] = useState45(false);
|
|
9409
|
+
useEffect36(() => {
|
|
8661
9410
|
const host = hostRef.current;
|
|
8662
9411
|
if (!host) return;
|
|
8663
9412
|
let chart = null;
|
|
@@ -8684,14 +9433,14 @@ function EChartBase({
|
|
|
8684
9433
|
chartRef.current = null;
|
|
8685
9434
|
};
|
|
8686
9435
|
}, []);
|
|
8687
|
-
|
|
9436
|
+
useEffect36(() => {
|
|
8688
9437
|
try {
|
|
8689
9438
|
chartRef.current?.setOption(option, { notMerge: true });
|
|
8690
9439
|
} catch {
|
|
8691
9440
|
}
|
|
8692
9441
|
}, [option]);
|
|
8693
9442
|
if (failed) {
|
|
8694
|
-
return /* @__PURE__ */
|
|
9443
|
+
return /* @__PURE__ */ jsx130(
|
|
8695
9444
|
"div",
|
|
8696
9445
|
{
|
|
8697
9446
|
"data-slot": "chart-fallback",
|
|
@@ -8704,7 +9453,7 @@ function EChartBase({
|
|
|
8704
9453
|
}
|
|
8705
9454
|
);
|
|
8706
9455
|
}
|
|
8707
|
-
return /* @__PURE__ */
|
|
9456
|
+
return /* @__PURE__ */ jsx130(
|
|
8708
9457
|
"div",
|
|
8709
9458
|
{
|
|
8710
9459
|
ref: hostRef,
|
|
@@ -9238,7 +9987,7 @@ function getChartTheme() {
|
|
|
9238
9987
|
}
|
|
9239
9988
|
|
|
9240
9989
|
// src/components/chart/AreaChart/index.tsx
|
|
9241
|
-
import { jsx as
|
|
9990
|
+
import { jsx as jsx131 } from "react/jsx-runtime";
|
|
9242
9991
|
function AreaChart({
|
|
9243
9992
|
data = [],
|
|
9244
9993
|
xKey,
|
|
@@ -9256,7 +10005,7 @@ function AreaChart({
|
|
|
9256
10005
|
{ data, xKey, yKeys, stacked, fillOpacity, colors, title },
|
|
9257
10006
|
getChartTheme()
|
|
9258
10007
|
);
|
|
9259
|
-
return /* @__PURE__ */
|
|
10008
|
+
return /* @__PURE__ */ jsx131(
|
|
9260
10009
|
EChartBase,
|
|
9261
10010
|
{
|
|
9262
10011
|
slot: "area-chart",
|
|
@@ -9270,7 +10019,7 @@ function AreaChart({
|
|
|
9270
10019
|
}
|
|
9271
10020
|
|
|
9272
10021
|
// src/components/chart/BarChart/index.tsx
|
|
9273
|
-
import { jsx as
|
|
10022
|
+
import { jsx as jsx132 } from "react/jsx-runtime";
|
|
9274
10023
|
function BarChart2({
|
|
9275
10024
|
data = [],
|
|
9276
10025
|
yKey,
|
|
@@ -9287,7 +10036,7 @@ function BarChart2({
|
|
|
9287
10036
|
{ data, yKey, yKeys: xKeys, stacked, colors, title },
|
|
9288
10037
|
getChartTheme()
|
|
9289
10038
|
);
|
|
9290
|
-
return /* @__PURE__ */
|
|
10039
|
+
return /* @__PURE__ */ jsx132(
|
|
9291
10040
|
EChartBase,
|
|
9292
10041
|
{
|
|
9293
10042
|
slot: "bar-chart",
|
|
@@ -9301,7 +10050,7 @@ function BarChart2({
|
|
|
9301
10050
|
}
|
|
9302
10051
|
|
|
9303
10052
|
// src/components/chart/BubbleChart/index.tsx
|
|
9304
|
-
import { jsx as
|
|
10053
|
+
import { jsx as jsx133 } from "react/jsx-runtime";
|
|
9305
10054
|
function BubbleChart({
|
|
9306
10055
|
data = [],
|
|
9307
10056
|
xKey,
|
|
@@ -9319,7 +10068,7 @@ function BubbleChart({
|
|
|
9319
10068
|
{ data, xKey, yKey, sizeKey, seriesKey, colors, title },
|
|
9320
10069
|
getChartTheme()
|
|
9321
10070
|
);
|
|
9322
|
-
return /* @__PURE__ */
|
|
10071
|
+
return /* @__PURE__ */ jsx133(
|
|
9323
10072
|
EChartBase,
|
|
9324
10073
|
{
|
|
9325
10074
|
slot: "bubble-chart",
|
|
@@ -9333,7 +10082,7 @@ function BubbleChart({
|
|
|
9333
10082
|
}
|
|
9334
10083
|
|
|
9335
10084
|
// src/components/chart/ColumnChart/index.tsx
|
|
9336
|
-
import { jsx as
|
|
10085
|
+
import { jsx as jsx134 } from "react/jsx-runtime";
|
|
9337
10086
|
function ColumnChart({
|
|
9338
10087
|
data = [],
|
|
9339
10088
|
xKey,
|
|
@@ -9350,7 +10099,7 @@ function ColumnChart({
|
|
|
9350
10099
|
{ data, xKey, yKeys, stacked, colors, title },
|
|
9351
10100
|
getChartTheme()
|
|
9352
10101
|
);
|
|
9353
|
-
return /* @__PURE__ */
|
|
10102
|
+
return /* @__PURE__ */ jsx134(
|
|
9354
10103
|
EChartBase,
|
|
9355
10104
|
{
|
|
9356
10105
|
slot: "column-chart",
|
|
@@ -9364,7 +10113,7 @@ function ColumnChart({
|
|
|
9364
10113
|
}
|
|
9365
10114
|
|
|
9366
10115
|
// src/components/chart/ComposedChart/index.tsx
|
|
9367
|
-
import { jsx as
|
|
10116
|
+
import { jsx as jsx135 } from "react/jsx-runtime";
|
|
9368
10117
|
function ComposedChart({
|
|
9369
10118
|
data = [],
|
|
9370
10119
|
xKey,
|
|
@@ -9380,7 +10129,7 @@ function ComposedChart({
|
|
|
9380
10129
|
{ data, xKey, series, colors, title },
|
|
9381
10130
|
getChartTheme()
|
|
9382
10131
|
);
|
|
9383
|
-
return /* @__PURE__ */
|
|
10132
|
+
return /* @__PURE__ */ jsx135(
|
|
9384
10133
|
EChartBase,
|
|
9385
10134
|
{
|
|
9386
10135
|
slot: "composed-chart",
|
|
@@ -9394,7 +10143,7 @@ function ComposedChart({
|
|
|
9394
10143
|
}
|
|
9395
10144
|
|
|
9396
10145
|
// src/components/chart/DonutChart/index.tsx
|
|
9397
|
-
import { jsx as
|
|
10146
|
+
import { jsx as jsx136 } from "react/jsx-runtime";
|
|
9398
10147
|
function DonutChart({
|
|
9399
10148
|
data = [],
|
|
9400
10149
|
nameKey,
|
|
@@ -9426,7 +10175,7 @@ function DonutChart({
|
|
|
9426
10175
|
},
|
|
9427
10176
|
getChartTheme()
|
|
9428
10177
|
);
|
|
9429
|
-
return /* @__PURE__ */
|
|
10178
|
+
return /* @__PURE__ */ jsx136(
|
|
9430
10179
|
EChartBase,
|
|
9431
10180
|
{
|
|
9432
10181
|
slot: "donut-chart",
|
|
@@ -9440,7 +10189,7 @@ function DonutChart({
|
|
|
9440
10189
|
}
|
|
9441
10190
|
|
|
9442
10191
|
// src/components/chart/FunnelChart/index.tsx
|
|
9443
|
-
import { jsx as
|
|
10192
|
+
import { jsx as jsx137 } from "react/jsx-runtime";
|
|
9444
10193
|
function FunnelChart2({
|
|
9445
10194
|
data = [],
|
|
9446
10195
|
nameKey,
|
|
@@ -9457,7 +10206,7 @@ function FunnelChart2({
|
|
|
9457
10206
|
{ data, nameKey, valueKey, sort, colors, title },
|
|
9458
10207
|
getChartTheme()
|
|
9459
10208
|
);
|
|
9460
|
-
return /* @__PURE__ */
|
|
10209
|
+
return /* @__PURE__ */ jsx137(
|
|
9461
10210
|
EChartBase,
|
|
9462
10211
|
{
|
|
9463
10212
|
slot: "funnel-chart",
|
|
@@ -9471,7 +10220,7 @@ function FunnelChart2({
|
|
|
9471
10220
|
}
|
|
9472
10221
|
|
|
9473
10222
|
// src/components/chart/GaugeChart/index.tsx
|
|
9474
|
-
import { jsx as
|
|
10223
|
+
import { jsx as jsx138 } from "react/jsx-runtime";
|
|
9475
10224
|
function GaugeChart2({
|
|
9476
10225
|
value = 0,
|
|
9477
10226
|
min,
|
|
@@ -9488,7 +10237,7 @@ function GaugeChart2({
|
|
|
9488
10237
|
{ value, min, max, thresholds, unit, title },
|
|
9489
10238
|
getChartTheme()
|
|
9490
10239
|
);
|
|
9491
|
-
return /* @__PURE__ */
|
|
10240
|
+
return /* @__PURE__ */ jsx138(
|
|
9492
10241
|
EChartBase,
|
|
9493
10242
|
{
|
|
9494
10243
|
slot: "gauge-chart",
|
|
@@ -9502,7 +10251,7 @@ function GaugeChart2({
|
|
|
9502
10251
|
}
|
|
9503
10252
|
|
|
9504
10253
|
// src/components/chart/Heatmap/index.tsx
|
|
9505
|
-
import { jsx as
|
|
10254
|
+
import { jsx as jsx139 } from "react/jsx-runtime";
|
|
9506
10255
|
function Heatmap({
|
|
9507
10256
|
data = [],
|
|
9508
10257
|
xKey,
|
|
@@ -9518,7 +10267,7 @@ function Heatmap({
|
|
|
9518
10267
|
{ data, xKey, yKey, valueKey, title },
|
|
9519
10268
|
getChartTheme()
|
|
9520
10269
|
);
|
|
9521
|
-
return /* @__PURE__ */
|
|
10270
|
+
return /* @__PURE__ */ jsx139(
|
|
9522
10271
|
EChartBase,
|
|
9523
10272
|
{
|
|
9524
10273
|
slot: "heatmap",
|
|
@@ -9532,7 +10281,7 @@ function Heatmap({
|
|
|
9532
10281
|
}
|
|
9533
10282
|
|
|
9534
10283
|
// src/components/chart/LineChart/index.tsx
|
|
9535
|
-
import { jsx as
|
|
10284
|
+
import { jsx as jsx140 } from "react/jsx-runtime";
|
|
9536
10285
|
function LineChart2({
|
|
9537
10286
|
data = [],
|
|
9538
10287
|
xKey,
|
|
@@ -9551,7 +10300,7 @@ function LineChart2({
|
|
|
9551
10300
|
{ data, xKey, yKeys, smooth, showArea, stacked, colors, title },
|
|
9552
10301
|
getChartTheme()
|
|
9553
10302
|
);
|
|
9554
|
-
return /* @__PURE__ */
|
|
10303
|
+
return /* @__PURE__ */ jsx140(
|
|
9555
10304
|
EChartBase,
|
|
9556
10305
|
{
|
|
9557
10306
|
slot: "line-chart",
|
|
@@ -9565,8 +10314,8 @@ function LineChart2({
|
|
|
9565
10314
|
}
|
|
9566
10315
|
|
|
9567
10316
|
// src/components/chart/MapChart/index.tsx
|
|
9568
|
-
import { useEffect as
|
|
9569
|
-
import { jsx as
|
|
10317
|
+
import { useEffect as useEffect37, useState as useState46 } from "react";
|
|
10318
|
+
import { jsx as jsx141 } from "react/jsx-runtime";
|
|
9570
10319
|
var fetchedMaps = /* @__PURE__ */ new Set();
|
|
9571
10320
|
function hasRegisteredMap(mapName) {
|
|
9572
10321
|
try {
|
|
@@ -9588,7 +10337,7 @@ function MapChart2({
|
|
|
9588
10337
|
className,
|
|
9589
10338
|
style
|
|
9590
10339
|
}) {
|
|
9591
|
-
const [loadState, setLoadState] =
|
|
10340
|
+
const [loadState, setLoadState] = useState46(
|
|
9592
10341
|
() => geoJson || !geoJsonUrl || hasRegisteredMap(mapName) ? "idle" : "loading"
|
|
9593
10342
|
);
|
|
9594
10343
|
if (geoJson) {
|
|
@@ -9597,7 +10346,7 @@ function MapChart2({
|
|
|
9597
10346
|
} catch {
|
|
9598
10347
|
}
|
|
9599
10348
|
}
|
|
9600
|
-
|
|
10349
|
+
useEffect37(() => {
|
|
9601
10350
|
if (geoJson || !geoJsonUrl || hasRegisteredMap(mapName) || fetchedMaps.has(mapName)) {
|
|
9602
10351
|
setLoadState("idle");
|
|
9603
10352
|
return;
|
|
@@ -9622,7 +10371,7 @@ function MapChart2({
|
|
|
9622
10371
|
};
|
|
9623
10372
|
}, [geoJson, geoJsonUrl, mapName]);
|
|
9624
10373
|
if (geoJsonUrl && !geoJson && loadState === "loading") {
|
|
9625
|
-
return /* @__PURE__ */
|
|
10374
|
+
return /* @__PURE__ */ jsx141(
|
|
9626
10375
|
"div",
|
|
9627
10376
|
{
|
|
9628
10377
|
"data-slot": "map-chart-loading",
|
|
@@ -9632,7 +10381,7 @@ function MapChart2({
|
|
|
9632
10381
|
);
|
|
9633
10382
|
}
|
|
9634
10383
|
if (!geoJson && loadState === "error") {
|
|
9635
|
-
return /* @__PURE__ */
|
|
10384
|
+
return /* @__PURE__ */ jsx141(
|
|
9636
10385
|
Empty2,
|
|
9637
10386
|
{
|
|
9638
10387
|
title: "\u5730\u56FE\u52A0\u8F7D\u5931\u8D25",
|
|
@@ -9644,7 +10393,7 @@ function MapChart2({
|
|
|
9644
10393
|
}
|
|
9645
10394
|
if (!geoJson && !hasRegisteredMap(mapName)) {
|
|
9646
10395
|
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`);
|
|
9647
|
-
return /* @__PURE__ */
|
|
10396
|
+
return /* @__PURE__ */ jsx141(
|
|
9648
10397
|
Empty2,
|
|
9649
10398
|
{
|
|
9650
10399
|
title: "\u5730\u56FE\u672A\u6CE8\u518C",
|
|
@@ -9655,7 +10404,7 @@ function MapChart2({
|
|
|
9655
10404
|
);
|
|
9656
10405
|
}
|
|
9657
10406
|
const option = buildMapOption({ mapName, data, nameKey, valueKey, title }, getChartTheme());
|
|
9658
|
-
return /* @__PURE__ */
|
|
10407
|
+
return /* @__PURE__ */ jsx141(
|
|
9659
10408
|
EChartBase,
|
|
9660
10409
|
{
|
|
9661
10410
|
slot: "map-chart",
|
|
@@ -9670,7 +10419,7 @@ function MapChart2({
|
|
|
9670
10419
|
|
|
9671
10420
|
// src/components/chart/MetricCard/index.tsx
|
|
9672
10421
|
import { ArrowDownRight, ArrowUpRight } from "lucide-react";
|
|
9673
|
-
import { jsx as
|
|
10422
|
+
import { jsx as jsx142, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
9674
10423
|
function MetricCard({
|
|
9675
10424
|
title,
|
|
9676
10425
|
value,
|
|
@@ -9683,15 +10432,15 @@ function MetricCard({
|
|
|
9683
10432
|
}) {
|
|
9684
10433
|
const showTrend = typeof trend === "number" && trend !== 0;
|
|
9685
10434
|
const rising = (trend ?? 0) > 0;
|
|
9686
|
-
return /* @__PURE__ */
|
|
10435
|
+
return /* @__PURE__ */ jsxs93(
|
|
9687
10436
|
"div",
|
|
9688
10437
|
{
|
|
9689
10438
|
"data-slot": "metric-card",
|
|
9690
10439
|
className: cn("rounded-lg border bg-card p-4 text-card-foreground shadow-sm", className),
|
|
9691
10440
|
style,
|
|
9692
10441
|
children: [
|
|
9693
|
-
title ? /* @__PURE__ */
|
|
9694
|
-
/* @__PURE__ */
|
|
10442
|
+
title ? /* @__PURE__ */ jsx142("div", { "data-slot": "metric-card-title", className: "text-sm text-muted-foreground", children: title }) : null,
|
|
10443
|
+
/* @__PURE__ */ jsxs93(
|
|
9695
10444
|
"div",
|
|
9696
10445
|
{
|
|
9697
10446
|
"data-slot": "metric-card-value",
|
|
@@ -9703,7 +10452,7 @@ function MetricCard({
|
|
|
9703
10452
|
]
|
|
9704
10453
|
}
|
|
9705
10454
|
),
|
|
9706
|
-
showTrend ? /* @__PURE__ */
|
|
10455
|
+
showTrend ? /* @__PURE__ */ jsxs93(
|
|
9707
10456
|
"div",
|
|
9708
10457
|
{
|
|
9709
10458
|
"data-slot": "metric-card-trend",
|
|
@@ -9713,10 +10462,10 @@ function MetricCard({
|
|
|
9713
10462
|
rising ? "text-success" : "text-destructive"
|
|
9714
10463
|
),
|
|
9715
10464
|
children: [
|
|
9716
|
-
rising ? /* @__PURE__ */
|
|
10465
|
+
rising ? /* @__PURE__ */ jsx142(ArrowUpRight, { className: "size-4" }) : /* @__PURE__ */ jsx142(ArrowDownRight, { className: "size-4" }),
|
|
9717
10466
|
Math.abs(trend ?? 0),
|
|
9718
10467
|
"%",
|
|
9719
|
-
trendLabel ? /* @__PURE__ */
|
|
10468
|
+
trendLabel ? /* @__PURE__ */ jsx142("span", { className: "ml-1 text-muted-foreground", children: trendLabel }) : null
|
|
9720
10469
|
]
|
|
9721
10470
|
}
|
|
9722
10471
|
) : null
|
|
@@ -9726,7 +10475,7 @@ function MetricCard({
|
|
|
9726
10475
|
}
|
|
9727
10476
|
|
|
9728
10477
|
// src/components/chart/PieChart/index.tsx
|
|
9729
|
-
import { jsx as
|
|
10478
|
+
import { jsx as jsx143 } from "react/jsx-runtime";
|
|
9730
10479
|
function PieChart2({
|
|
9731
10480
|
data = [],
|
|
9732
10481
|
nameKey,
|
|
@@ -9743,7 +10492,7 @@ function PieChart2({
|
|
|
9743
10492
|
{ data, nameKey, valueKey, showLabel, colors, title },
|
|
9744
10493
|
getChartTheme()
|
|
9745
10494
|
);
|
|
9746
|
-
return /* @__PURE__ */
|
|
10495
|
+
return /* @__PURE__ */ jsx143(
|
|
9747
10496
|
EChartBase,
|
|
9748
10497
|
{
|
|
9749
10498
|
slot: "pie-chart",
|
|
@@ -9757,7 +10506,7 @@ function PieChart2({
|
|
|
9757
10506
|
}
|
|
9758
10507
|
|
|
9759
10508
|
// src/components/chart/RadarChart/index.tsx
|
|
9760
|
-
import { jsx as
|
|
10509
|
+
import { jsx as jsx144 } from "react/jsx-runtime";
|
|
9761
10510
|
function RadarChart2({
|
|
9762
10511
|
data = [],
|
|
9763
10512
|
indicatorKey,
|
|
@@ -9773,7 +10522,7 @@ function RadarChart2({
|
|
|
9773
10522
|
{ data, indicatorKey, yKeys, colors, title },
|
|
9774
10523
|
getChartTheme()
|
|
9775
10524
|
);
|
|
9776
|
-
return /* @__PURE__ */
|
|
10525
|
+
return /* @__PURE__ */ jsx144(
|
|
9777
10526
|
EChartBase,
|
|
9778
10527
|
{
|
|
9779
10528
|
slot: "radar-chart",
|
|
@@ -9787,7 +10536,7 @@ function RadarChart2({
|
|
|
9787
10536
|
}
|
|
9788
10537
|
|
|
9789
10538
|
// src/components/chart/SankeyChart/index.tsx
|
|
9790
|
-
import { jsx as
|
|
10539
|
+
import { jsx as jsx145 } from "react/jsx-runtime";
|
|
9791
10540
|
function SankeyChart2({
|
|
9792
10541
|
nodes = [],
|
|
9793
10542
|
links = [],
|
|
@@ -9798,7 +10547,7 @@ function SankeyChart2({
|
|
|
9798
10547
|
style
|
|
9799
10548
|
}) {
|
|
9800
10549
|
const option = buildSankeyOption({ nodes, links, title }, getChartTheme());
|
|
9801
|
-
return /* @__PURE__ */
|
|
10550
|
+
return /* @__PURE__ */ jsx145(
|
|
9802
10551
|
EChartBase,
|
|
9803
10552
|
{
|
|
9804
10553
|
slot: "sankey-chart",
|
|
@@ -9812,7 +10561,7 @@ function SankeyChart2({
|
|
|
9812
10561
|
}
|
|
9813
10562
|
|
|
9814
10563
|
// src/components/chart/ScatterChart/index.tsx
|
|
9815
|
-
import { jsx as
|
|
10564
|
+
import { jsx as jsx146 } from "react/jsx-runtime";
|
|
9816
10565
|
function ScatterChart2({
|
|
9817
10566
|
data = [],
|
|
9818
10567
|
xKey,
|
|
@@ -9829,7 +10578,7 @@ function ScatterChart2({
|
|
|
9829
10578
|
{ data, xKey, yKey, seriesKey, colors, title },
|
|
9830
10579
|
getChartTheme()
|
|
9831
10580
|
);
|
|
9832
|
-
return /* @__PURE__ */
|
|
10581
|
+
return /* @__PURE__ */ jsx146(
|
|
9833
10582
|
EChartBase,
|
|
9834
10583
|
{
|
|
9835
10584
|
slot: "scatter-chart",
|
|
@@ -9843,7 +10592,7 @@ function ScatterChart2({
|
|
|
9843
10592
|
}
|
|
9844
10593
|
|
|
9845
10594
|
// src/components/chart/TreeChart/index.tsx
|
|
9846
|
-
import { jsx as
|
|
10595
|
+
import { jsx as jsx147 } from "react/jsx-runtime";
|
|
9847
10596
|
function TreeChart2({
|
|
9848
10597
|
data = [],
|
|
9849
10598
|
title,
|
|
@@ -9859,7 +10608,7 @@ function TreeChart2({
|
|
|
9859
10608
|
{ data, title, orient, edgeShape, initialTreeDepth },
|
|
9860
10609
|
getChartTheme()
|
|
9861
10610
|
);
|
|
9862
|
-
return /* @__PURE__ */
|
|
10611
|
+
return /* @__PURE__ */ jsx147(
|
|
9863
10612
|
EChartBase,
|
|
9864
10613
|
{
|
|
9865
10614
|
slot: "tree-chart",
|