mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-22 14:16:42 +08:00
### What problem does this PR solve? Feat: Display the log after the data flow runs #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Timeline,
|
Timeline,
|
||||||
TimelineContent,
|
TimelineContent,
|
||||||
TimelineDate,
|
|
||||||
TimelineHeader,
|
TimelineHeader,
|
||||||
TimelineIndicator,
|
TimelineIndicator,
|
||||||
TimelineItem,
|
TimelineItem,
|
||||||
@ -9,45 +8,10 @@ import {
|
|||||||
TimelineTitle,
|
TimelineTitle,
|
||||||
} from '@/components/originui/timeline';
|
} from '@/components/originui/timeline';
|
||||||
import { ITraceData } from '@/interfaces/database/agent';
|
import { ITraceData } from '@/interfaces/database/agent';
|
||||||
import { Aperture } from 'lucide-react';
|
import { useCallback } from 'react';
|
||||||
|
import { Operator } from '../constant';
|
||||||
const items = [
|
import OperatorIcon from '../operator-icon';
|
||||||
{
|
import useGraphStore from '../store';
|
||||||
id: 1,
|
|
||||||
date: '15 minutes ago',
|
|
||||||
title: 'Hannah Kandell',
|
|
||||||
action: 'opened a new issue',
|
|
||||||
description:
|
|
||||||
"I'm having trouble with the new component library. It's not rendering properly.",
|
|
||||||
image: '/avatar-40-01.jpg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
date: '10 minutes ago',
|
|
||||||
title: 'Chris Tompson',
|
|
||||||
action: 'commented on',
|
|
||||||
description:
|
|
||||||
"Hey Hannah, I'm having trouble with the new component library. It's not rendering properly.",
|
|
||||||
image: '/avatar-40-02.jpg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
date: '5 minutes ago',
|
|
||||||
title: 'Emma Davis',
|
|
||||||
action: 'assigned you to',
|
|
||||||
description:
|
|
||||||
'The new component library is not rendering properly. Can you take a look?',
|
|
||||||
image: '/avatar-40-03.jpg',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
date: '2 minutes ago',
|
|
||||||
title: 'Alex Morgan',
|
|
||||||
action: 'closed the issue',
|
|
||||||
description: 'The issue has been fixed. Please review the changes.',
|
|
||||||
image: '/avatar-40-05.jpg',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export type DataflowTimelineProps = {
|
export type DataflowTimelineProps = {
|
||||||
traceList?: ITraceData[];
|
traceList?: ITraceData[];
|
||||||
@ -61,36 +25,73 @@ interface DataflowTrace {
|
|||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
export function DataflowTimeline({ traceList }: DataflowTimelineProps) {
|
export function DataflowTimeline({ traceList }: DataflowTimelineProps) {
|
||||||
|
const getNode = useGraphStore((state) => state.getNode);
|
||||||
|
|
||||||
|
const getNodeData = useCallback(
|
||||||
|
(componentId: string) => {
|
||||||
|
return getNode(componentId)?.data;
|
||||||
|
},
|
||||||
|
[getNode],
|
||||||
|
);
|
||||||
|
|
||||||
|
const getNodeLabel = useCallback(
|
||||||
|
(componentId: string) => {
|
||||||
|
return getNodeData(componentId)?.label as Operator;
|
||||||
|
},
|
||||||
|
[getNodeData],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Timeline>
|
<Timeline>
|
||||||
{items.map((item) => (
|
{Array.isArray(traceList) &&
|
||||||
|
traceList?.map((item, index) => {
|
||||||
|
const traces = item.trace as DataflowTrace[];
|
||||||
|
const nodeLabel = getNodeLabel(item.component_id);
|
||||||
|
|
||||||
|
return (
|
||||||
<TimelineItem
|
<TimelineItem
|
||||||
key={item.id}
|
key={item.component_id}
|
||||||
step={item.id}
|
step={index}
|
||||||
className="group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8"
|
className="group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8"
|
||||||
>
|
>
|
||||||
<TimelineHeader>
|
<TimelineHeader>
|
||||||
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-7" />
|
<TimelineSeparator className="group-data-[orientation=vertical]/timeline:-left-7 group-data-[orientation=vertical]/timeline:h-[calc(100%-1.5rem-0.25rem)] group-data-[orientation=vertical]/timeline:translate-y-7 bg-accent-primary" />
|
||||||
<TimelineTitle className="">
|
<TimelineTitle className="">
|
||||||
{/* {item.title}
|
|
||||||
<span className="text-muted-foreground text-sm font-normal">
|
|
||||||
{item.action}
|
|
||||||
</span> */}
|
|
||||||
<TimelineContent className="text-foreground mt-2 rounded-lg border px-4 py-3">
|
<TimelineContent className="text-foreground mt-2 rounded-lg border px-4 py-3">
|
||||||
{item.description}
|
<p className="mb-2">
|
||||||
<TimelineDate className="mt-1 mb-0">{item.date}</TimelineDate>
|
{getNodeData(item.component_id)?.name || 'END'}
|
||||||
|
</p>
|
||||||
|
<div className="divide-y space-y-1">
|
||||||
|
{traces.map((x, idx) => (
|
||||||
|
<section
|
||||||
|
key={idx}
|
||||||
|
className="text-text-secondary text-xs"
|
||||||
|
>
|
||||||
|
<div className="space-x-2">
|
||||||
|
<span>{x.datetime}</span>
|
||||||
|
<span>{x.progress * 100}%</span>
|
||||||
|
<span>{x.elapsed_time.toString().slice(0, 6)}</span>
|
||||||
|
</div>
|
||||||
|
{item.component_id !== 'END' && (
|
||||||
|
<div>{x.message}</div>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</TimelineContent>
|
</TimelineContent>
|
||||||
</TimelineTitle>
|
</TimelineTitle>
|
||||||
<TimelineIndicator className="bg-primary/10 group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center border-none group-data-[orientation=vertical]/timeline:-left-7">
|
<TimelineIndicator className="border border-accent-primary group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-6 items-center justify-center group-data-[orientation=vertical]/timeline:-left-7">
|
||||||
<Aperture className="size-6 rounded-full" />
|
{nodeLabel && (
|
||||||
|
<OperatorIcon
|
||||||
|
name={nodeLabel}
|
||||||
|
className="size-6 rounded-full"
|
||||||
|
></OperatorIcon>
|
||||||
|
)}
|
||||||
</TimelineIndicator>
|
</TimelineIndicator>
|
||||||
</TimelineHeader>
|
</TimelineHeader>
|
||||||
{/* <TimelineContent className="text-foreground mt-2 rounded-lg border px-4 py-3">
|
|
||||||
{item.description}
|
|
||||||
<TimelineDate className="mt-1 mb-0">{item.date}</TimelineDate>
|
|
||||||
</TimelineContent> */}
|
|
||||||
</TimelineItem>
|
</TimelineItem>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</Timeline>
|
</Timeline>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,11 +37,12 @@ export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
|||||||
<SheetContent className={cn('top-20')}>
|
<SheetContent className={cn('top-20')}>
|
||||||
<SheetHeader>
|
<SheetHeader>
|
||||||
<SheetTitle className="flex items-center gap-1">
|
<SheetTitle className="flex items-center gap-1">
|
||||||
<NotebookText className="size-4" />
|
<NotebookText className="size-4" /> {t('flow.log')}
|
||||||
</SheetTitle>
|
</SheetTitle>
|
||||||
</SheetHeader>
|
</SheetHeader>
|
||||||
<section className="max-h-[82vh] overflow-auto mt-6">
|
<section className="max-h-[82vh] overflow-auto mt-6">
|
||||||
<DataflowTimeline traceList={data}></DataflowTimeline>
|
<DataflowTimeline traceList={data}></DataflowTimeline>
|
||||||
|
</section>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleDownloadJson}
|
onClick={handleDownloadJson}
|
||||||
disabled={isEndOutputEmpty(data)}
|
disabled={isEndOutputEmpty(data)}
|
||||||
@ -50,7 +51,6 @@ export function LogSheet({ hideModal, messageId }: LogSheetProps) {
|
|||||||
<SquareArrowOutUpRight />
|
<SquareArrowOutUpRight />
|
||||||
{t('dataflow.exportJson')}
|
{t('dataflow.exportJson')}
|
||||||
</Button>
|
</Button>
|
||||||
</section>
|
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user