初始化提交
This commit is contained in:
@@ -9,23 +9,33 @@ import {
|
||||
import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
|
||||
import { SourceData } from "../index";
|
||||
import PdfDialog from "../widgets/PdfDialog";
|
||||
import { useClientConfig } from "../hooks/use-config";
|
||||
|
||||
const SCORE_THRESHOLD = 0.3;
|
||||
|
||||
function SourceNumberButton({ index }: { index: number }) {
|
||||
function truncateNumber(num: number | undefined, precision: number): number {
|
||||
if (num == undefined || num == 0) return 0;
|
||||
const factor = Math.pow(10, precision);
|
||||
return Math.trunc(num * factor) / factor;
|
||||
}
|
||||
|
||||
function SourceNumberButton({ index, score }: { index: number, score: number | undefined }) {
|
||||
return (
|
||||
<div className="text-xs w-5 h-5 rounded-full bg-gray-100 mb-2 flex items-center justify-center hover:text-white hover:bg-primary hover:cursor-pointer">
|
||||
{index + 1}
|
||||
<div className="text-xs w-45 h-45 rounded-full bg-gray-100 mb-2 flex items-center justify-center hover:text-white hover:bg-primary hover:cursor-pointer">
|
||||
{truncateNumber(score, 2)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type NodeInfo = {
|
||||
id: string;
|
||||
score?: number;
|
||||
text: string;
|
||||
url?: string;
|
||||
};
|
||||
|
||||
export function ChatSources({ data }: { data: SourceData }) {
|
||||
const { backend } = useClientConfig();
|
||||
const sources: NodeInfo[] = useMemo(() => {
|
||||
// aggregate nodes by url or file_path (get the highest one by score)
|
||||
const nodesByPath: { [path: string]: NodeInfo } = {};
|
||||
@@ -36,6 +46,8 @@ export function ChatSources({ data }: { data: SourceData }) {
|
||||
.forEach((node) => {
|
||||
const nodeInfo = {
|
||||
id: node.id,
|
||||
score: node.score,
|
||||
text: node.text,
|
||||
url: node.url,
|
||||
};
|
||||
const key = nodeInfo.url ?? nodeInfo.id; // use id as key for UNKNOWN type
|
||||
@@ -51,7 +63,7 @@ export function ChatSources({ data }: { data: SourceData }) {
|
||||
|
||||
return (
|
||||
<div className="space-x-2 text-sm">
|
||||
<span className="font-semibold">Sources:</span>
|
||||
<span className="font-semibold">来源:</span>
|
||||
<div className="inline-flex gap-1 items-center">
|
||||
{sources.map((nodeInfo: NodeInfo, index: number) => {
|
||||
if (nodeInfo.url?.endsWith(".pdf")) {
|
||||
@@ -59,8 +71,8 @@ export function ChatSources({ data }: { data: SourceData }) {
|
||||
<PdfDialog
|
||||
key={nodeInfo.id}
|
||||
documentId={nodeInfo.id}
|
||||
url={nodeInfo.url!}
|
||||
trigger={<SourceNumberButton index={index} />}
|
||||
url={backend+nodeInfo.url}
|
||||
trigger={<SourceNumberButton index={index} score={nodeInfo.score} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -68,9 +80,9 @@ export function ChatSources({ data }: { data: SourceData }) {
|
||||
<div key={nodeInfo.id}>
|
||||
<HoverCard>
|
||||
<HoverCardTrigger>
|
||||
<SourceNumberButton index={index} />
|
||||
<SourceNumberButton index={index} score={nodeInfo.score}/>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent className="w-[320px]">
|
||||
<HoverCardContent className="w-[450px]">
|
||||
<NodeInfo nodeInfo={nodeInfo} />
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
@@ -83,6 +95,7 @@ export function ChatSources({ data }: { data: SourceData }) {
|
||||
}
|
||||
|
||||
function NodeInfo({ nodeInfo }: { nodeInfo: NodeInfo }) {
|
||||
const { backend } = useClientConfig();
|
||||
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 1000 });
|
||||
|
||||
if (nodeInfo.url) {
|
||||
@@ -92,10 +105,10 @@ function NodeInfo({ nodeInfo }: { nodeInfo: NodeInfo }) {
|
||||
<div className="flex items-center my-2">
|
||||
<a
|
||||
className="hover:text-blue-900 truncate"
|
||||
href={nodeInfo.url}
|
||||
href={backend+nodeInfo.url}
|
||||
target="_blank"
|
||||
>
|
||||
<span>{nodeInfo.url}</span>
|
||||
<span>{nodeInfo.text}</span>
|
||||
</a>
|
||||
<Button
|
||||
onClick={() => copyToClipboard(nodeInfo.url!)}
|
||||
@@ -116,8 +129,7 @@ function NodeInfo({ nodeInfo }: { nodeInfo: NodeInfo }) {
|
||||
// node generated by unknown loader, implement renderer by analyzing logged out metadata
|
||||
return (
|
||||
<p>
|
||||
Sorry, unknown node type. Please add a new renderer in the NodeInfo
|
||||
component.
|
||||
对不起, 未知文件类型. 无法打开当前的来源文件。
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user