mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-18 11:36:44 +08:00
Feat: Use data pipeline to visualize the parsing configuration of the knowledge base (#10423)
### What problem does this PR solve? #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: jinhai <haijin.chn@gmail.com> Signed-off-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: chanx <1243304602@qq.com> Co-authored-by: balibabu <cike8899@users.noreply.github.com> Co-authored-by: Lynn <lynn_inf@hotmail.com> Co-authored-by: 纷繁下的无奈 <zhileihuang@126.com> Co-authored-by: huangzl <huangzl@shinemo.com> Co-authored-by: writinwaters <93570324+writinwaters@users.noreply.github.com> Co-authored-by: Wilmer <33392318@qq.com> Co-authored-by: Adrian Weidig <adrianweidig@gmx.net> Co-authored-by: Zhichang Yu <yuzhichang@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Yongteng Lei <yongtengrey@outlook.com> Co-authored-by: Liu An <asiro@qq.com> Co-authored-by: buua436 <66937541+buua436@users.noreply.github.com> Co-authored-by: BadwomanCraZY <511528396@qq.com> Co-authored-by: cucusenok <31804608+cucusenok@users.noreply.github.com> Co-authored-by: Russell Valentine <russ@coldstonelabs.org> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Billy Bao <newyorkupperbay@gmail.com> Co-authored-by: Zhedong Cen <cenzhedong2@126.com> Co-authored-by: TensorNull <129579691+TensorNull@users.noreply.github.com> Co-authored-by: TensorNull <tensor.null@gmail.com> Co-authored-by: TeslaZY <TeslaZY@outlook.com> Co-authored-by: Ajay <160579663+aybanda@users.noreply.github.com> Co-authored-by: AB <aj@Ajays-MacBook-Air.local> Co-authored-by: 天海蒼灆 <huangaoqin@tecpie.com> Co-authored-by: He Wang <wanghechn@qq.com> Co-authored-by: Atsushi Hatakeyama <atu729@icloud.com> Co-authored-by: Jin Hai <haijin.chn@gmail.com> Co-authored-by: Mohamed Mathari <155896313+melmathari@users.noreply.github.com> Co-authored-by: Mohamed Mathari <nocodeventure@Mac-mini-van-Mohamed.fritz.box> Co-authored-by: Stephen Hu <stephenhu@seismic.com> Co-authored-by: Shaun Zhang <zhangwfjh@users.noreply.github.com> Co-authored-by: zhimeng123 <60221886+zhimeng123@users.noreply.github.com> Co-authored-by: mxc <mxc@example.com> Co-authored-by: Dominik Novotný <50611433+SgtMarmite@users.noreply.github.com> Co-authored-by: EVGENY M <168018528+rjohny55@users.noreply.github.com> Co-authored-by: mcoder6425 <mcoder64@gmail.com> Co-authored-by: lemsn <lemsn@msn.com> Co-authored-by: lemsn <lemsn@126.com> Co-authored-by: Adrian Gora <47756404+adagora@users.noreply.github.com> Co-authored-by: Womsxd <45663319+Womsxd@users.noreply.github.com> Co-authored-by: FatMii <39074672+FatMii@users.noreply.github.com>
This commit is contained in:
137
web/src/pages/data-flow/log-sheet/dataflow-timeline.tsx
Normal file
137
web/src/pages/data-flow/log-sheet/dataflow-timeline.tsx
Normal file
@ -0,0 +1,137 @@
|
||||
import {
|
||||
Timeline,
|
||||
TimelineContent,
|
||||
TimelineHeader,
|
||||
TimelineIndicator,
|
||||
TimelineItem,
|
||||
TimelineSeparator,
|
||||
TimelineTitle,
|
||||
} from '@/components/originui/timeline';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { ITraceData } from '@/interfaces/database/agent';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { File } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { Operator } from '../constant';
|
||||
import OperatorIcon from '../operator-icon';
|
||||
import useGraphStore from '../store';
|
||||
|
||||
export type DataflowTimelineProps = {
|
||||
traceList?: ITraceData[];
|
||||
};
|
||||
|
||||
const END = 'END';
|
||||
|
||||
interface DataflowTrace {
|
||||
datetime: string;
|
||||
elapsed_time: number;
|
||||
message: string;
|
||||
progress: number;
|
||||
timestamp: number;
|
||||
}
|
||||
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 (
|
||||
<Timeline>
|
||||
{Array.isArray(traceList) &&
|
||||
traceList?.map((item, index) => {
|
||||
const traces = item.trace as DataflowTrace[];
|
||||
const nodeLabel = getNodeLabel(item.component_id);
|
||||
|
||||
const latest = traces[traces.length - 1];
|
||||
const progress = latest.progress * 100;
|
||||
|
||||
return (
|
||||
<TimelineItem
|
||||
key={item.component_id}
|
||||
step={index}
|
||||
className="group-data-[orientation=vertical]/timeline:ms-10 group-data-[orientation=vertical]/timeline:not-last:pb-8 pb-6"
|
||||
>
|
||||
<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 bg-accent-primary" />
|
||||
<TimelineTitle className="">
|
||||
<TimelineContent
|
||||
className={cn(
|
||||
'text-foreground rounded-lg border px-4 py-3',
|
||||
)}
|
||||
>
|
||||
<section className="flex items-center justify-between mb-2">
|
||||
<span className="flex-1 truncate">
|
||||
{getNodeData(item.component_id)?.name || END}
|
||||
</span>
|
||||
<div className="flex-1 flex items-center gap-5">
|
||||
<Progress value={progress} className="h-1 flex-1" />
|
||||
<span className="text-accent-primary text-xs">
|
||||
{progress}%
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<div className="divide-y space-y-1">
|
||||
{traces
|
||||
.filter((x) => !isEmpty(x.message))
|
||||
.map((x, idx) => (
|
||||
<section
|
||||
key={idx}
|
||||
className="text-text-secondary text-xs space-x-2 py-2.5 !m-0"
|
||||
>
|
||||
<span>{x.datetime}</span>
|
||||
{item.component_id !== 'END' && (
|
||||
<span
|
||||
className={cn({
|
||||
'text-state-error':
|
||||
x.message.startsWith('[ERROR]'),
|
||||
})}
|
||||
>
|
||||
{x.message}
|
||||
</span>
|
||||
)}
|
||||
<span>
|
||||
{x.elapsed_time.toString().slice(0, 6)}s
|
||||
</span>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</TimelineContent>
|
||||
</TimelineTitle>
|
||||
<TimelineIndicator
|
||||
className={cn(
|
||||
'border border-accent-primary group-data-completed/timeline-item:bg-primary group-data-completed/timeline-item:text-primary-foreground flex size-5 items-center justify-center group-data-[orientation=vertical]/timeline:-left-7',
|
||||
{
|
||||
'rounded bg-accent-primary': nodeLabel === Operator.Begin,
|
||||
},
|
||||
)}
|
||||
>
|
||||
{item.component_id === END ? (
|
||||
<span className="rounded-full inline-block size-2 bg-accent-primary"></span>
|
||||
) : nodeLabel === Operator.Begin ? (
|
||||
<File className="size-3.5 text-bg-base"></File>
|
||||
) : (
|
||||
<OperatorIcon
|
||||
name={nodeLabel}
|
||||
className="size-3.5 rounded-full"
|
||||
></OperatorIcon>
|
||||
)}
|
||||
</TimelineIndicator>
|
||||
</TimelineHeader>
|
||||
</TimelineItem>
|
||||
);
|
||||
})}
|
||||
</Timeline>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user