mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Fix: Interface integration for the file log page in the overview - Support for selecting data pipeline parsing types - Use the RunningStatus enumeration instead of numeric status - Obtain and display data pipeline file log details - Replace existing mock data with new interface data on the page - Link the file log list to the real data source - Optimize log information display - Fixed a typo in the field name "pipeline_id" → "pipeline_id" ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -18,6 +18,10 @@ import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-reques
|
|||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { IParserConfig } from '@/interfaces/database/document';
|
import { IParserConfig } from '@/interfaces/database/document';
|
||||||
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
import { IChangeParserConfigRequestBody } from '@/interfaces/request/document';
|
||||||
|
import {
|
||||||
|
ChunkMethodItem,
|
||||||
|
ParseTypeItem,
|
||||||
|
} from '@/pages/dataset/dataset-setting/configuration/common-item';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
@ -30,6 +34,7 @@ import {
|
|||||||
AutoKeywordsFormField,
|
AutoKeywordsFormField,
|
||||||
AutoQuestionsFormField,
|
AutoQuestionsFormField,
|
||||||
} from '../auto-keywords-form-field';
|
} from '../auto-keywords-form-field';
|
||||||
|
import { DataFlowSelect } from '../data-pipeline-select';
|
||||||
import { DelimiterFormField } from '../delimiter-form-field';
|
import { DelimiterFormField } from '../delimiter-form-field';
|
||||||
import { EntityTypesFormField } from '../entity-types-form-field';
|
import { EntityTypesFormField } from '../entity-types-form-field';
|
||||||
import { ExcelToHtmlFormField } from '../excel-to-html-form-field';
|
import { ExcelToHtmlFormField } from '../excel-to-html-form-field';
|
||||||
@ -45,7 +50,6 @@ import RaptorFormFields, {
|
|||||||
} from '../parse-configuration/raptor-form-fields';
|
} from '../parse-configuration/raptor-form-fields';
|
||||||
import { ButtonLoading } from '../ui/button';
|
import { ButtonLoading } from '../ui/button';
|
||||||
import { Input } from '../ui/input';
|
import { Input } from '../ui/input';
|
||||||
import { RAGFlowSelect } from '../ui/select';
|
|
||||||
import { DynamicPageRange } from './dynamic-page-range';
|
import { DynamicPageRange } from './dynamic-page-range';
|
||||||
import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks';
|
import { useFetchParserListOnMount, useShowAutoKeywords } from './hooks';
|
||||||
import {
|
import {
|
||||||
@ -62,6 +66,7 @@ interface IProps
|
|||||||
}> {
|
}> {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
parserId: string;
|
parserId: string;
|
||||||
|
pipelineId?: string;
|
||||||
parserConfig: IParserConfig;
|
parserConfig: IParserConfig;
|
||||||
documentExtension: string;
|
documentExtension: string;
|
||||||
documentId: string;
|
documentId: string;
|
||||||
@ -80,6 +85,7 @@ export function ChunkMethodDialog({
|
|||||||
hideModal,
|
hideModal,
|
||||||
onOk,
|
onOk,
|
||||||
parserId,
|
parserId,
|
||||||
|
pipelineId,
|
||||||
documentExtension,
|
documentExtension,
|
||||||
visible,
|
visible,
|
||||||
parserConfig,
|
parserConfig,
|
||||||
@ -100,12 +106,14 @@ export function ChunkMethodDialog({
|
|||||||
const fillDefaultParserValue = useFillDefaultValueOnMount();
|
const fillDefaultParserValue = useFillDefaultValueOnMount();
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
|
parseType: z.number(),
|
||||||
parser_id: z
|
parser_id: z
|
||||||
.string()
|
.string()
|
||||||
.min(1, {
|
.min(1, {
|
||||||
message: t('common.pleaseSelect'),
|
message: t('common.pleaseSelect'),
|
||||||
})
|
})
|
||||||
.trim(),
|
.trim(),
|
||||||
|
pipeline_id: z.string().optional(),
|
||||||
parser_config: z.object({
|
parser_config: z.object({
|
||||||
task_page_size: z.coerce.number().optional(),
|
task_page_size: z.coerce.number().optional(),
|
||||||
layout_recognize: z.string().optional(),
|
layout_recognize: z.string().optional(),
|
||||||
@ -138,7 +146,8 @@ export function ChunkMethodDialog({
|
|||||||
resolver: zodResolver(FormSchema),
|
resolver: zodResolver(FormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
parser_id: parserId,
|
parser_id: parserId,
|
||||||
|
pipeline_id: pipelineId,
|
||||||
|
parseType: pipelineId ? 2 : 1,
|
||||||
parser_config: defaultParserValues,
|
parser_config: defaultParserValues,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -201,6 +210,8 @@ export function ChunkMethodDialog({
|
|||||||
parserConfig?.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? [];
|
parserConfig?.pages?.map((x) => ({ from: x[0], to: x[1] })) ?? [];
|
||||||
form.reset({
|
form.reset({
|
||||||
parser_id: parserId,
|
parser_id: parserId,
|
||||||
|
pipeline_id: pipelineId,
|
||||||
|
parseType: pipelineId ? 2 : 1,
|
||||||
parser_config: fillDefaultParserValue({
|
parser_config: fillDefaultParserValue({
|
||||||
pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
|
pages: pages.length > 0 ? pages : [{ from: 1, to: 1024 }],
|
||||||
...omit(parserConfig, 'pages'),
|
...omit(parserConfig, 'pages'),
|
||||||
@ -223,7 +234,11 @@ export function ChunkMethodDialog({
|
|||||||
useGraphRag,
|
useGraphRag,
|
||||||
visible,
|
visible,
|
||||||
]);
|
]);
|
||||||
|
const parseType = useWatch({
|
||||||
|
control: form.control,
|
||||||
|
name: 'parseType',
|
||||||
|
defaultValue: 1,
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<Dialog open onOpenChange={hideModal}>
|
<Dialog open onOpenChange={hideModal}>
|
||||||
<DialogContent className="max-w-[50vw]">
|
<DialogContent className="max-w-[50vw]">
|
||||||
@ -237,7 +252,17 @@ export function ChunkMethodDialog({
|
|||||||
id={FormId}
|
id={FormId}
|
||||||
>
|
>
|
||||||
<FormContainer>
|
<FormContainer>
|
||||||
<FormField
|
<ParseTypeItem />
|
||||||
|
{parseType === 1 && <ChunkMethodItem></ChunkMethodItem>}
|
||||||
|
{parseType === 2 && (
|
||||||
|
<DataFlowSelect
|
||||||
|
isMult={false}
|
||||||
|
// toDataPipeline={navigateToAgents}
|
||||||
|
formFieldName="pipeline_id"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* <FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="parser_id"
|
name="parser_id"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
@ -252,9 +277,11 @@ export function ChunkMethodDialog({
|
|||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/> */}
|
||||||
{showPages && <DynamicPageRange></DynamicPageRange>}
|
{showPages && parseType === 1 && (
|
||||||
{showPages && layoutRecognize && (
|
<DynamicPageRange></DynamicPageRange>
|
||||||
|
)}
|
||||||
|
{showPages && parseType === 1 && layoutRecognize && (
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="parser_config.task_page_size"
|
name="parser_config.task_page_size"
|
||||||
@ -279,11 +306,15 @@ export function ChunkMethodDialog({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
|
{parseType === 1 && (
|
||||||
|
<>
|
||||||
<FormContainer
|
<FormContainer
|
||||||
show={showOne || showMaxTokenNumber}
|
show={showOne || showMaxTokenNumber}
|
||||||
className="space-y-3"
|
className="space-y-3"
|
||||||
>
|
>
|
||||||
{showOne && <LayoutRecognizeFormField></LayoutRecognizeFormField>}
|
{showOne && (
|
||||||
|
<LayoutRecognizeFormField></LayoutRecognizeFormField>
|
||||||
|
)}
|
||||||
{showMaxTokenNumber && (
|
{showMaxTokenNumber && (
|
||||||
<>
|
<>
|
||||||
<MaxTokenNumberFormField
|
<MaxTokenNumberFormField
|
||||||
@ -307,7 +338,9 @@ export function ChunkMethodDialog({
|
|||||||
<AutoQuestionsFormField></AutoQuestionsFormField>
|
<AutoQuestionsFormField></AutoQuestionsFormField>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{showExcelToHtml && <ExcelToHtmlFormField></ExcelToHtmlFormField>}
|
{showExcelToHtml && (
|
||||||
|
<ExcelToHtmlFormField></ExcelToHtmlFormField>
|
||||||
|
)}
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
{showRaptorParseConfiguration(
|
{showRaptorParseConfiguration(
|
||||||
selectedTag as DocumentParserType,
|
selectedTag as DocumentParserType,
|
||||||
@ -322,7 +355,11 @@ export function ChunkMethodDialog({
|
|||||||
<UseGraphRagFormField></UseGraphRagFormField>
|
<UseGraphRagFormField></UseGraphRagFormField>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
)}
|
)}
|
||||||
{showEntityTypes && <EntityTypesFormField></EntityTypesFormField>}
|
{showEntityTypes && (
|
||||||
|
<EntityTypesFormField></EntityTypesFormField>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|||||||
@ -52,6 +52,7 @@ export function DataFlowSelect(props: IProps) {
|
|||||||
>
|
>
|
||||||
{t('dataFlow')}
|
{t('dataFlow')}
|
||||||
</FormLabel>
|
</FormLabel>
|
||||||
|
{toDataPipeline && (
|
||||||
<div
|
<div
|
||||||
className="text-sm flex text-text-primary cursor-pointer"
|
className="text-sm flex text-text-primary cursor-pointer"
|
||||||
onClick={toDataPipLine}
|
onClick={toDataPipLine}
|
||||||
@ -59,6 +60,7 @@ export function DataFlowSelect(props: IProps) {
|
|||||||
{t('buildItFromScratch')}
|
{t('buildItFromScratch')}
|
||||||
<ArrowUpRight size={14} />
|
<ArrowUpRight size={14} />
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="text-muted-foreground">
|
<div className="text-muted-foreground">
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
// src/pages/dataset/file-logs/file-status-badge.tsx
|
// src/pages/dataset/file-logs/file-status-badge.tsx
|
||||||
|
import { RunningStatus } from '@/pages/dataset/dataset/constant';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
/**
|
/**
|
||||||
* params: status: 0 not run yet 1 running, 2 cancel, 3 success, 4 fail
|
* params: status: 0 not run yet 1 running, 2 cancel, 3 success, 4 fail
|
||||||
*/
|
*/
|
||||||
interface StatusBadgeProps {
|
interface StatusBadgeProps {
|
||||||
// status: 'Success' | 'Failed' | 'Running' | 'Pending';
|
// status: 'Success' | 'Failed' | 'Running' | 'Pending';
|
||||||
status: 0 | 1 | 2 | 3 | 4;
|
status: RunningStatus;
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,13 +17,13 @@ const FileStatusBadge: FC<StatusBadgeProps> = ({ status, name }) => {
|
|||||||
// #00beb4 → rgb(0, 190, 180) // accent-primary
|
// #00beb4 → rgb(0, 190, 180) // accent-primary
|
||||||
// #faad14 → rgb(250, 173, 20) // state-warning
|
// #faad14 → rgb(250, 173, 20) // state-warning
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 3:
|
case RunningStatus.DONE:
|
||||||
return `bg-[rgba(59,160,92,0.1)] text-state-success`;
|
return `bg-[rgba(59,160,92,0.1)] text-state-success`;
|
||||||
case 4:
|
case RunningStatus.FAIL:
|
||||||
return `bg-[rgba(216,73,75,0.1)] text-state-error`;
|
return `bg-[rgba(216,73,75,0.1)] text-state-error`;
|
||||||
case 1:
|
case RunningStatus.RUNNING:
|
||||||
return `bg-[rgba(0,190,180,0.1)] text-accent-primary`;
|
return `bg-[rgba(0,190,180,0.1)] text-accent-primary`;
|
||||||
case 0:
|
case RunningStatus.UNSTART:
|
||||||
return `bg-[rgba(250,173,20,0.1)] text-state-warning`;
|
return `bg-[rgba(250,173,20,0.1)] text-state-warning`;
|
||||||
default:
|
default:
|
||||||
return 'bg-gray-500/10 text-white';
|
return 'bg-gray-500/10 text-white';
|
||||||
@ -35,13 +36,13 @@ const FileStatusBadge: FC<StatusBadgeProps> = ({ status, name }) => {
|
|||||||
// #00beb4 → rgb(0, 190, 180) // accent-primary
|
// #00beb4 → rgb(0, 190, 180) // accent-primary
|
||||||
// #faad14 → rgb(250, 173, 20) // state-warning
|
// #faad14 → rgb(250, 173, 20) // state-warning
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 3:
|
case RunningStatus.DONE:
|
||||||
return `bg-[rgba(59,160,92,1)] text-state-success`;
|
return `bg-[rgba(59,160,92,1)] text-state-success`;
|
||||||
case 4:
|
case RunningStatus.FAIL:
|
||||||
return `bg-[rgba(216,73,75,1)] text-state-error`;
|
return `bg-[rgba(216,73,75,1)] text-state-error`;
|
||||||
case 1:
|
case RunningStatus.RUNNING:
|
||||||
return `bg-[rgba(0,190,180,1)] text-accent-primary`;
|
return `bg-[rgba(0,190,180,1)] text-accent-primary`;
|
||||||
case 0:
|
case RunningStatus.UNSTART:
|
||||||
return `bg-[rgba(250,173,20,1)] text-state-warning`;
|
return `bg-[rgba(250,173,20,1)] text-state-warning`;
|
||||||
default:
|
default:
|
||||||
return 'bg-gray-500/10 text-white';
|
return 'bg-gray-500/10 text-white';
|
||||||
|
|||||||
@ -15,6 +15,14 @@ export enum RunningStatus {
|
|||||||
FAIL = '4', // need to refresh
|
FAIL = '4', // need to refresh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const RunningStatusMap = {
|
||||||
|
[RunningStatus.UNSTART]: 'Pending',
|
||||||
|
[RunningStatus.RUNNING]: 'Running',
|
||||||
|
[RunningStatus.CANCEL]: 'Cancel',
|
||||||
|
[RunningStatus.DONE]: 'Success',
|
||||||
|
[RunningStatus.FAIL]: 'Failed',
|
||||||
|
};
|
||||||
|
|
||||||
export enum ModelVariableType {
|
export enum ModelVariableType {
|
||||||
Improvise = 'Improvise',
|
Improvise = 'Improvise',
|
||||||
Precise = 'Precise',
|
Precise = 'Precise',
|
||||||
|
|||||||
@ -93,8 +93,8 @@ export const useNavigatePage = () => {
|
|||||||
const navigateToChunkParsedResult = useCallback(
|
const navigateToChunkParsedResult = useCallback(
|
||||||
(id: string, knowledgeId?: string) => () => {
|
(id: string, knowledgeId?: string) => () => {
|
||||||
navigate(
|
navigate(
|
||||||
// `${Routes.ParsedResult}/${id}?${QueryStringMap.KnowledgeId}=${knowledgeId}`,
|
`${Routes.ParsedResult}/chunks?id=${knowledgeId}&doc_id=${id}`,
|
||||||
`${Routes.DataflowResult}?id=${knowledgeId}&doc_id=${id}&type=chunk`,
|
// `${Routes.DataflowResult}?id=${knowledgeId}&doc_id=${id}&type=chunk`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[navigate],
|
[navigate],
|
||||||
@ -136,7 +136,7 @@ export const useNavigatePage = () => {
|
|||||||
(id: string, knowledgeId?: string) => () => {
|
(id: string, knowledgeId?: string) => () => {
|
||||||
navigate(
|
navigate(
|
||||||
// `${Routes.ParsedResult}/${id}?${QueryStringMap.KnowledgeId}=${knowledgeId}`,
|
// `${Routes.ParsedResult}/${id}?${QueryStringMap.KnowledgeId}=${knowledgeId}`,
|
||||||
`${Routes.DataflowResult}?id=${knowledgeId}&doc_id=${id}&type=dataflow`,
|
`${Routes.DataflowResult}?id=${id}&type=dataflow`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[navigate],
|
[navigate],
|
||||||
|
|||||||
@ -335,15 +335,18 @@ export const useSetDocumentParser = () => {
|
|||||||
mutationKey: [DocumentApiAction.SetDocumentParser],
|
mutationKey: [DocumentApiAction.SetDocumentParser],
|
||||||
mutationFn: async ({
|
mutationFn: async ({
|
||||||
parserId,
|
parserId,
|
||||||
|
pipelineId,
|
||||||
documentId,
|
documentId,
|
||||||
parserConfig,
|
parserConfig,
|
||||||
}: {
|
}: {
|
||||||
parserId: string;
|
parserId: string;
|
||||||
|
pipelineId: string;
|
||||||
documentId: string;
|
documentId: string;
|
||||||
parserConfig: IChangeParserConfigRequestBody;
|
parserConfig: IChangeParserConfigRequestBody;
|
||||||
}) => {
|
}) => {
|
||||||
const { data } = await kbService.document_change_parser({
|
const { data } = await kbService.document_change_parser({
|
||||||
parser_id: parserId,
|
parser_id: parserId,
|
||||||
|
pipeline_id: pipelineId,
|
||||||
doc_id: documentId,
|
doc_id: documentId,
|
||||||
parser_config: parserConfig,
|
parser_config: parserConfig,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,6 +7,7 @@ export interface IChangeParserConfigRequestBody {
|
|||||||
|
|
||||||
export interface IChangeParserRequestBody {
|
export interface IChangeParserRequestBody {
|
||||||
parser_id: string;
|
parser_id: string;
|
||||||
|
pipeline_id: string;
|
||||||
doc_id: string;
|
doc_id: string;
|
||||||
parser_config: IChangeParserConfigRequestBody;
|
parser_config: IChangeParserConfigRequestBody;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,6 +114,9 @@ export default {
|
|||||||
processingType: 'Processing Type',
|
processingType: 'Processing Type',
|
||||||
dataPipeline: 'Data Pipeline',
|
dataPipeline: 'Data Pipeline',
|
||||||
operations: 'Operations',
|
operations: 'Operations',
|
||||||
|
taskId: 'Task ID',
|
||||||
|
duration: 'Duration',
|
||||||
|
details: 'Details',
|
||||||
status: 'Status',
|
status: 'Status',
|
||||||
task: 'Task',
|
task: 'Task',
|
||||||
startDate: 'Start Date',
|
startDate: 'Start Date',
|
||||||
|
|||||||
@ -102,6 +102,9 @@ export default {
|
|||||||
processingType: '处理类型',
|
processingType: '处理类型',
|
||||||
dataPipeline: '数据管道',
|
dataPipeline: '数据管道',
|
||||||
operations: '操作',
|
operations: '操作',
|
||||||
|
taskId: '任务ID',
|
||||||
|
duration: '耗时',
|
||||||
|
details: '详情',
|
||||||
status: '状态',
|
status: '状态',
|
||||||
task: '任务',
|
task: '任务',
|
||||||
startDate: '开始时间',
|
startDate: '开始时间',
|
||||||
|
|||||||
@ -7,13 +7,74 @@ import {
|
|||||||
import { useSetModalState, useShowDeleteConfirm } from '@/hooks/common-hooks';
|
import { useSetModalState, useShowDeleteConfirm } from '@/hooks/common-hooks';
|
||||||
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
|
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
|
||||||
import { IChunk } from '@/interfaces/database/knowledge';
|
import { IChunk } from '@/interfaces/database/knowledge';
|
||||||
|
import kbService from '@/services/knowledge-service';
|
||||||
import { buildChunkHighlights } from '@/utils/document-util';
|
import { buildChunkHighlights } from '@/utils/document-util';
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { IHighlight } from 'react-pdf-highlighter';
|
import { IHighlight } from 'react-pdf-highlighter';
|
||||||
|
import { useParams, useSearchParams } from 'umi';
|
||||||
import { ChunkTextMode } from './constant';
|
import { ChunkTextMode } from './constant';
|
||||||
|
|
||||||
|
export interface IPipelineFileLogDetail {
|
||||||
|
avatar: string;
|
||||||
|
create_date: string;
|
||||||
|
create_time: number;
|
||||||
|
document_id: string;
|
||||||
|
document_name: string;
|
||||||
|
document_suffix: string;
|
||||||
|
document_type: string;
|
||||||
|
dsl: string;
|
||||||
|
id: string;
|
||||||
|
kb_id: string;
|
||||||
|
operation_status: string;
|
||||||
|
parser_id: string;
|
||||||
|
pipeline_id: string;
|
||||||
|
pipeline_title: string;
|
||||||
|
process_begin_at: string;
|
||||||
|
process_duration: number;
|
||||||
|
progress: number;
|
||||||
|
progress_msg: string;
|
||||||
|
source_from: string;
|
||||||
|
status: string;
|
||||||
|
task_type: string;
|
||||||
|
tenant_id: string;
|
||||||
|
update_date: string;
|
||||||
|
update_time: number;
|
||||||
|
}
|
||||||
|
export const useFetchPipelineFileLogDetail = (props?: {
|
||||||
|
isEdit?: boolean;
|
||||||
|
refreshCount?: number;
|
||||||
|
}) => {
|
||||||
|
const { isEdit = true, refreshCount } = props || { isEdit: true };
|
||||||
|
const { id } = useParams();
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const logId = searchParams.get('id') || id;
|
||||||
|
|
||||||
|
let queryKey: (string | number)[] = [];
|
||||||
|
if (typeof refreshCount === 'number') {
|
||||||
|
queryKey = ['fetchLogDetail', refreshCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, isFetching: loading } = useQuery<IPipelineFileLogDetail>({
|
||||||
|
queryKey,
|
||||||
|
initialData: {} as IPipelineFileLogDetail,
|
||||||
|
gcTime: 0,
|
||||||
|
queryFn: async () => {
|
||||||
|
if (isEdit) {
|
||||||
|
const { data } = await kbService.get_pipeline_detail({
|
||||||
|
log_id: logId,
|
||||||
|
});
|
||||||
|
return data?.data ?? {};
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data, loading };
|
||||||
|
};
|
||||||
|
|
||||||
export const useHandleChunkCardClick = () => {
|
export const useHandleChunkCardClick = () => {
|
||||||
const [selectedChunkId, setSelectedChunkId] = useState<string>('');
|
const [selectedChunkId, setSelectedChunkId] = useState<string>('');
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import DocumentPreview from './components/document-preview';
|
import DocumentPreview from './components/document-preview';
|
||||||
import {
|
import {
|
||||||
|
useFetchPipelineFileLogDetail,
|
||||||
useGetChunkHighlights,
|
useGetChunkHighlights,
|
||||||
useHandleChunkCardClick,
|
useHandleChunkCardClick,
|
||||||
useRerunDataflow,
|
useRerunDataflow,
|
||||||
@ -28,7 +29,6 @@ import {
|
|||||||
useNavigatePage,
|
useNavigatePage,
|
||||||
} from '@/hooks/logic-hooks/navigate-hooks';
|
} from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
|
import { useGetKnowledgeSearchParams } from '@/hooks/route-hook';
|
||||||
import { useFetchKnowledgeBaseConfiguration } from '@/hooks/use-knowledge-request';
|
|
||||||
import { ChunkerContainer } from './chunker';
|
import { ChunkerContainer } from './chunker';
|
||||||
import { useGetDocumentUrl } from './components/document-preview/hooks';
|
import { useGetDocumentUrl } from './components/document-preview/hooks';
|
||||||
import TimelineDataFlow, {
|
import TimelineDataFlow, {
|
||||||
@ -44,7 +44,7 @@ const Chunk = () => {
|
|||||||
} = useFetchNextChunkList();
|
} = useFetchNextChunkList();
|
||||||
const { selectedChunkId } = useHandleChunkCardClick();
|
const { selectedChunkId } = useHandleChunkCardClick();
|
||||||
const [activeStepId, setActiveStepId] = useState<number | string>(0);
|
const [activeStepId, setActiveStepId] = useState<number | string>(0);
|
||||||
const { data: dataset } = useFetchKnowledgeBaseConfiguration();
|
const { data: dataset } = useFetchPipelineFileLogDetail();
|
||||||
const { isChange, setIsChange } = useRerunDataflow();
|
const { isChange, setIsChange } = useRerunDataflow();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,12 @@
|
|||||||
import kbService from '@/services/knowledge-service';
|
import {
|
||||||
|
useGetPaginationWithRouter,
|
||||||
|
useHandleSearchChange,
|
||||||
|
} from '@/hooks/logic-hooks';
|
||||||
|
import kbService, {
|
||||||
|
listDataPipelineLogDocument,
|
||||||
|
} from '@/services/knowledge-service';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { useCallback } from 'react';
|
||||||
import { useParams, useSearchParams } from 'umi';
|
import { useParams, useSearchParams } from 'umi';
|
||||||
|
|
||||||
export interface IOverviewTital {
|
export interface IOverviewTital {
|
||||||
@ -24,4 +31,78 @@ const useFetchOverviewTital = () => {
|
|||||||
return { data };
|
return { data };
|
||||||
};
|
};
|
||||||
|
|
||||||
export { useFetchOverviewTital };
|
export interface IFileLogItem {
|
||||||
|
create_date: string;
|
||||||
|
create_time: number;
|
||||||
|
document_id: string;
|
||||||
|
document_name: string;
|
||||||
|
document_suffix: string;
|
||||||
|
document_type: string;
|
||||||
|
dsl: any;
|
||||||
|
path: string[];
|
||||||
|
task_id: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
kb_id: string;
|
||||||
|
operation_status: string;
|
||||||
|
parser_id: string;
|
||||||
|
pipeline_id: string;
|
||||||
|
pipeline_title: string;
|
||||||
|
avatar: string;
|
||||||
|
process_begin_at: null | string;
|
||||||
|
process_duration: number;
|
||||||
|
progress: number;
|
||||||
|
progress_msg: string;
|
||||||
|
source_from: string;
|
||||||
|
status: string;
|
||||||
|
task_type: string;
|
||||||
|
tenant_id: string;
|
||||||
|
update_date: string;
|
||||||
|
update_time: number;
|
||||||
|
}
|
||||||
|
export interface IFileLogList {
|
||||||
|
docs: IFileLogItem[];
|
||||||
|
total: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useFetchFileLogList = () => {
|
||||||
|
const [searchParams] = useSearchParams();
|
||||||
|
const { searchString, handleInputChange } = useHandleSearchChange();
|
||||||
|
const { pagination, setPagination } = useGetPaginationWithRouter();
|
||||||
|
const { id } = useParams();
|
||||||
|
const knowledgeBaseId = searchParams.get('id') || id;
|
||||||
|
const { data } = useQuery<IFileLogList>({
|
||||||
|
queryKey: [
|
||||||
|
'fileLogList',
|
||||||
|
knowledgeBaseId,
|
||||||
|
pagination.current,
|
||||||
|
pagination.pageSize,
|
||||||
|
searchString,
|
||||||
|
],
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data: res = {} } = await listDataPipelineLogDocument({
|
||||||
|
kb_id: knowledgeBaseId,
|
||||||
|
page: pagination.current,
|
||||||
|
page_size: pagination.pageSize,
|
||||||
|
keywords: searchString,
|
||||||
|
// order_by: '',
|
||||||
|
});
|
||||||
|
return res.data || [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const onInputChange: React.ChangeEventHandler<HTMLInputElement> = useCallback(
|
||||||
|
(e) => {
|
||||||
|
setPagination({ page: 1 });
|
||||||
|
handleInputChange(e);
|
||||||
|
},
|
||||||
|
[handleInputChange, setPagination],
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
searchString,
|
||||||
|
handleInputChange: onInputChange,
|
||||||
|
pagination: { ...pagination, total: data?.total },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useFetchFileLogList, useFetchOverviewTital };
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { FC, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { LogTabs } from './dataset-common';
|
import { LogTabs } from './dataset-common';
|
||||||
import { DatasetFilter } from './dataset-filter';
|
import { DatasetFilter } from './dataset-filter';
|
||||||
import { useFetchOverviewTital } from './hook';
|
import { useFetchFileLogList, useFetchOverviewTital } from './hook';
|
||||||
import FileLogsTable from './overview-table';
|
import FileLogsTable from './overview-table';
|
||||||
|
|
||||||
interface StatCardProps {
|
interface StatCardProps {
|
||||||
@ -94,68 +94,37 @@ const FileLogsPage: FC = () => {
|
|||||||
const { data: topData } = useFetchOverviewTital();
|
const { data: topData } = useFetchOverviewTital();
|
||||||
console.log('topData --> ', topData);
|
console.log('topData --> ', topData);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTopAllData({
|
setTopAllData((prev) => {
|
||||||
...topAllData,
|
return {
|
||||||
|
...prev,
|
||||||
processing: {
|
processing: {
|
||||||
value: topData?.processing || 0,
|
value: topData?.processing || 0,
|
||||||
success: topData?.finished || 0,
|
success: topData?.finished || 0,
|
||||||
failed: topData?.failed || 0,
|
failed: topData?.failed || 0,
|
||||||
},
|
},
|
||||||
});
|
|
||||||
}, [topData, topAllData]);
|
|
||||||
|
|
||||||
const mockData = useMemo(() => {
|
|
||||||
if (active === LogTabs.FILE_LOGS) {
|
|
||||||
return Array(30)
|
|
||||||
.fill(0)
|
|
||||||
.map((_, i) => ({
|
|
||||||
id: i === 0 ? '952734' : `14`,
|
|
||||||
fileName: 'PRD for DealBees 1.2 (1).txt',
|
|
||||||
source: 'GitHub',
|
|
||||||
pipeline:
|
|
||||||
i === 0 ? 'data demo for...' : i === 1 ? 'test' : 'kiki’s demo',
|
|
||||||
startDate: '14/03/2025 14:53:39',
|
|
||||||
task: i === 0 ? 'chunck' : 'Parser',
|
|
||||||
status: i === 0 ? 3 : i === 1 ? 4 : i === 2 ? 1 : 0,
|
|
||||||
statusName:
|
|
||||||
i === 0
|
|
||||||
? 'Success'
|
|
||||||
: i === 1
|
|
||||||
? 'Failed'
|
|
||||||
: i === 2
|
|
||||||
? 'Running'
|
|
||||||
: 'Pending',
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
if (active === LogTabs.DATASET_LOGS) {
|
|
||||||
return Array(8)
|
|
||||||
.fill(0)
|
|
||||||
.map((_, i) => ({
|
|
||||||
id: i === 0 ? '952734' : `14`,
|
|
||||||
fileName: 'PRD for DealBees 1.2 (1).txt',
|
|
||||||
source: 'GitHub',
|
|
||||||
startDate: '14/03/2025 14:53:39',
|
|
||||||
task: i === 0 ? 'chunck' : 'Parser',
|
|
||||||
pipeline:
|
|
||||||
i === 0 ? 'data demo for...' : i === 1 ? 'test' : 'kiki’s demo',
|
|
||||||
status: i === 0 ? 3 : i === 1 ? 4 : i === 2 ? 1 : 0,
|
|
||||||
statusName:
|
|
||||||
i === 0
|
|
||||||
? 'Success'
|
|
||||||
: i === 1
|
|
||||||
? 'Failed'
|
|
||||||
: i === 2
|
|
||||||
? 'Running'
|
|
||||||
: 'Pending',
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [active]);
|
|
||||||
|
|
||||||
const pagination = {
|
|
||||||
current: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
total: 100,
|
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
}, [topData]);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: tableOriginData,
|
||||||
|
searchString,
|
||||||
|
handleInputChange,
|
||||||
|
pagination,
|
||||||
|
} = useFetchFileLogList();
|
||||||
|
|
||||||
|
const tableList = useMemo(() => {
|
||||||
|
console.log('tableList', tableOriginData);
|
||||||
|
if (tableOriginData && tableOriginData.docs?.length) {
|
||||||
|
return tableOriginData.docs.map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
fileName: item.document_name,
|
||||||
|
statusName: item.operation_status,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [tableOriginData, active]);
|
||||||
|
|
||||||
const changeActiveLogs = (active: (typeof LogTabs)[keyof typeof LogTabs]) => {
|
const changeActiveLogs = (active: (typeof LogTabs)[keyof typeof LogTabs]) => {
|
||||||
setActive(active);
|
setActive(active);
|
||||||
@ -223,11 +192,16 @@ const FileLogsPage: FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs & Search */}
|
{/* Tabs & Search */}
|
||||||
<DatasetFilter active={active} setActive={changeActiveLogs} />
|
<DatasetFilter
|
||||||
|
active={active}
|
||||||
|
setActive={changeActiveLogs}
|
||||||
|
searchString={searchString}
|
||||||
|
onSearchChange={handleInputChange}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Table */}
|
{/* Table */}
|
||||||
<FileLogsTable
|
<FileLogsTable
|
||||||
data={mockData}
|
data={tableList}
|
||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
setPagination={handlePaginationChange}
|
setPagination={handlePaginationChange}
|
||||||
pageCount={10}
|
pageCount={10}
|
||||||
|
|||||||
@ -12,8 +12,10 @@ import {
|
|||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from '@/components/ui/table';
|
} from '@/components/ui/table';
|
||||||
|
import { RunningStatusMap } from '@/constants/knowledge';
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
|
import { formatDate } from '@/utils/date';
|
||||||
import {
|
import {
|
||||||
ColumnDef,
|
ColumnDef,
|
||||||
ColumnFiltersState,
|
ColumnFiltersState,
|
||||||
@ -28,18 +30,16 @@ import {
|
|||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
import { TFunction } from 'i18next';
|
import { TFunction } from 'i18next';
|
||||||
import { ClipboardList, Eye } from 'lucide-react';
|
import { ClipboardList, Eye } from 'lucide-react';
|
||||||
import { Dispatch, FC, SetStateAction, useMemo, useState } from 'react';
|
import { FC, useMemo, useState } from 'react';
|
||||||
|
import { RunningStatus } from '../dataset/constant';
|
||||||
import ProcessLogModal from '../process-log-modal';
|
import ProcessLogModal from '../process-log-modal';
|
||||||
import { LogTabs, ProcessingType } from './dataset-common';
|
import { LogTabs, ProcessingType } from './dataset-common';
|
||||||
|
import { IFileLogItem } from './hook';
|
||||||
|
|
||||||
interface DocumentLog {
|
interface DocumentLog {
|
||||||
id: string;
|
|
||||||
fileName: string;
|
fileName: string;
|
||||||
source: string;
|
status: RunningStatus;
|
||||||
pipeline: string;
|
statusName: typeof RunningStatusMap;
|
||||||
startDate: string;
|
|
||||||
task: string;
|
|
||||||
status: 'Success' | 'Failed' | 'Running' | 'Pending';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FileLogsTableProps {
|
interface FileLogsTableProps {
|
||||||
@ -57,14 +57,14 @@ interface FileLogsTableProps {
|
|||||||
|
|
||||||
export const getFileLogsTableColumns = (
|
export const getFileLogsTableColumns = (
|
||||||
t: TFunction<'translation', string>,
|
t: TFunction<'translation', string>,
|
||||||
setIsModalVisible: Dispatch<SetStateAction<boolean>>,
|
showLog: (row: Row<IFileLogItem & DocumentLog>, active: LogTabs) => void,
|
||||||
navigateToDataflowResult: (
|
navigateToDataflowResult: (
|
||||||
id: string,
|
id: string,
|
||||||
knowledgeId?: string | undefined,
|
knowledgeId?: string | undefined,
|
||||||
) => () => void,
|
) => () => void,
|
||||||
) => {
|
) => {
|
||||||
// const { t } = useTranslate('knowledgeDetails');
|
// const { t } = useTranslate('knowledgeDetails');
|
||||||
const columns: ColumnDef<DocumentLog>[] = [
|
const columns: ColumnDef<IFileLogItem & DocumentLog>[] = [
|
||||||
// {
|
// {
|
||||||
// id: 'select',
|
// id: 'select',
|
||||||
// header: ({ table }) => (
|
// header: ({ table }) => (
|
||||||
@ -97,10 +97,10 @@ export const getFileLogsTableColumns = (
|
|||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div
|
<div
|
||||||
className="flex items-center gap-2 text-text-primary"
|
className="flex items-center gap-2 text-text-primary"
|
||||||
onClick={navigateToDataflowResult(
|
// onClick={navigateToDataflowResult(
|
||||||
row.original.id,
|
// row.original.id,
|
||||||
row.original.kb_id,
|
// row.original.kb_id,
|
||||||
)}
|
// )}
|
||||||
>
|
>
|
||||||
<FileIcon name={row.original.fileName}></FileIcon>
|
<FileIcon name={row.original.fileName}></FileIcon>
|
||||||
{row.original.fileName}
|
{row.original.fileName}
|
||||||
@ -108,47 +108,51 @@ export const getFileLogsTableColumns = (
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'source',
|
accessorKey: 'source_from',
|
||||||
header: t('source'),
|
header: t('source'),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="text-text-primary">{row.original.source}</div>
|
<div className="text-text-primary">{row.original.source_from}</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'pipeline',
|
accessorKey: 'pipeline_title',
|
||||||
header: t('dataPipeline'),
|
header: t('dataPipeline'),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="flex items-center gap-2 text-text-primary">
|
<div className="flex items-center gap-2 text-text-primary">
|
||||||
<RAGFlowAvatar
|
<RAGFlowAvatar
|
||||||
avatar={null}
|
avatar={row.original.avatar}
|
||||||
name={row.original.pipeline}
|
name={row.original.pipeline_title}
|
||||||
className="size-4"
|
className="size-4"
|
||||||
/>
|
/>
|
||||||
{row.original.pipeline}
|
{row.original.pipeline_title}
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'startDate',
|
accessorKey: 'process_begin_at',
|
||||||
header: t('startDate'),
|
header: t('startDate'),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="text-text-primary">{row.original.startDate}</div>
|
<div className="text-text-primary">
|
||||||
|
{formatDate(row.original.process_begin_at)}
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'task',
|
accessorKey: 'task_type',
|
||||||
header: t('task'),
|
header: t('task'),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<div className="text-text-primary">{row.original.task}</div>
|
<div className="text-text-primary">{row.original.task_type}</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'status',
|
accessorKey: 'operation_status',
|
||||||
header: t('status'),
|
header: t('status'),
|
||||||
cell: ({ row }) => (
|
cell: ({ row }) => (
|
||||||
<FileStatusBadge
|
<FileStatusBadge
|
||||||
status={row.original.status}
|
status={row.original.operation_status as RunningStatus}
|
||||||
name={row.original.statusName}
|
name={
|
||||||
|
RunningStatusMap[row.original.operation_status as RunningStatus]
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -162,7 +166,7 @@ export const getFileLogsTableColumns = (
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="p-1"
|
className="p-1"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsModalVisible(true);
|
showLog(row, LogTabs.FILE_LOGS);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Eye />
|
<Eye />
|
||||||
@ -185,10 +189,10 @@ export const getFileLogsTableColumns = (
|
|||||||
|
|
||||||
export const getDatasetLogsTableColumns = (
|
export const getDatasetLogsTableColumns = (
|
||||||
t: TFunction<'translation', string>,
|
t: TFunction<'translation', string>,
|
||||||
showLog: (row: Row<DocumentLog>, active: LogTabs) => void,
|
showLog: (row: Row<IFileLogItem & DocumentLog>, active: LogTabs) => void,
|
||||||
) => {
|
) => {
|
||||||
// const { t } = useTranslate('knowledgeDetails');
|
// const { t } = useTranslate('knowledgeDetails');
|
||||||
const columns: ColumnDef<DocumentLog>[] = [
|
const columns: ColumnDef<IFileLogItem & DocumentLog>[] = [
|
||||||
// {
|
// {
|
||||||
// id: 'select',
|
// id: 'select',
|
||||||
// header: ({ table }) => (
|
// header: ({ table }) => (
|
||||||
@ -270,18 +274,6 @@ export const getDatasetLogsTableColumns = (
|
|||||||
return columns;
|
return columns;
|
||||||
};
|
};
|
||||||
|
|
||||||
const taskInfo = {
|
|
||||||
taskId: '#9527',
|
|
||||||
fileName: 'PRD for DealBees 1.2 (1).text',
|
|
||||||
fileSize: '2.4G',
|
|
||||||
source: 'Github',
|
|
||||||
task: 'Parse',
|
|
||||||
state: 'Running',
|
|
||||||
startTime: '14/03/2025 14:53:39',
|
|
||||||
duration: '800',
|
|
||||||
details:
|
|
||||||
'\n17:43:21 Task has been received.\n17:43:25 Page(1~100000001): Start to parse.\n17:43:25 Page(1~100000001): Start to tag for every chunk ...\n17:43:45 Page(1~100000001): Tagging 2 chunks completed in 18.99s\n17:43:45 Page(1~100000001): Generate 2 chunks\n17:43:55 Page(1~100000001): Embedding chunks (10.60s)\n17:43:55 Page(1~100000001): Indexing done (0.07s). Task done (33.97s)\n17:43:58 created task raptor\n17:43:58 Task has been received.\n17:44:36 Cluster one layer: 2 -> 1\n17:44:36 Indexing done (0.05s). Task done (37.88s)\n17:44:40 created task graphrag\n17:44:41 Task has been received.\n17:50:57 Entities extraction of chunk 0 1/3 done, 25 nodes, 26 edges, 14893 tokens.\n17:56:01 [ERROR][Exception]: Operation timed out after 7200 seconds and 1 attempts.',
|
|
||||||
};
|
|
||||||
const FileLogsTable: FC<FileLogsTableProps> = ({
|
const FileLogsTable: FC<FileLogsTableProps> = ({
|
||||||
data,
|
data,
|
||||||
pagination,
|
pagination,
|
||||||
@ -295,15 +287,26 @@ const FileLogsTable: FC<FileLogsTableProps> = ({
|
|||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||||
const { navigateToDataflowResult } = useNavigatePage();
|
const { navigateToDataflowResult } = useNavigatePage();
|
||||||
const [logInfo, setLogInfo] = useState(taskInfo);
|
const [logInfo, setLogInfo] = useState<IFileLogItem>({});
|
||||||
const showLog = (row: Row<DocumentLog>, active: LogTabs) => {
|
const showLog = (row: Row<IFileLogItem & DocumentLog>, active: LogTabs) => {
|
||||||
setLogInfo(row.original);
|
const logDetail = {
|
||||||
|
taskId: row.original.id,
|
||||||
|
fileName: row.original.document_name,
|
||||||
|
source: row.original.source_from,
|
||||||
|
task: row.original.dsl.task_id,
|
||||||
|
status: row.original.statusName,
|
||||||
|
startDate: formatDate(row.original.process_begin_at),
|
||||||
|
duration: (row.original.process_duration || 0) + 's',
|
||||||
|
details: row.original.progress_msg,
|
||||||
|
};
|
||||||
|
console.log('logDetail', logDetail);
|
||||||
|
setLogInfo(logDetail);
|
||||||
setIsModalVisible(true);
|
setIsModalVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const columns = useMemo(() => {
|
const columns = useMemo(() => {
|
||||||
return active === LogTabs.FILE_LOGS
|
return active === LogTabs.FILE_LOGS
|
||||||
? getFileLogsTableColumns(t, setIsModalVisible, navigateToDataflowResult)
|
? getFileLogsTableColumns(t, showLog, navigateToDataflowResult)
|
||||||
: getDatasetLogsTableColumns(t, showLog);
|
: getDatasetLogsTableColumns(t, showLog);
|
||||||
}, [active, t]);
|
}, [active, t]);
|
||||||
|
|
||||||
@ -316,7 +319,7 @@ const FileLogsTable: FC<FileLogsTableProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data: data || [],
|
||||||
columns,
|
columns,
|
||||||
manualPagination: true,
|
manualPagination: true,
|
||||||
getCoreRowModel: getCoreRowModel(),
|
getCoreRowModel: getCoreRowModel(),
|
||||||
@ -354,7 +357,7 @@ const FileLogsTable: FC<FileLogsTableProps> = ({
|
|||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody className="relative">
|
<TableBody className="relative">
|
||||||
{table.getRowModel().rows.length ? (
|
{table.getRowModel().rows?.length ? (
|
||||||
table.getRowModel().rows.map((row) => (
|
table.getRowModel().rows.map((row) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export const RunningStatusMap = {
|
|||||||
},
|
},
|
||||||
[RunningStatus.CANCEL]: { label: 'CANCEL', color: 'var(--state-warning)' },
|
[RunningStatus.CANCEL]: { label: 'CANCEL', color: 'var(--state-warning)' },
|
||||||
[RunningStatus.DONE]: { label: 'SUCCESS', color: 'var(--state-success)' },
|
[RunningStatus.DONE]: { label: 'SUCCESS', color: 'var(--state-success)' },
|
||||||
[RunningStatus.FAIL]: { label: 'FAIL', color: 'var(--state-error' },
|
[RunningStatus.FAIL]: { label: 'FAIL', color: 'rgba(var(--state-error))' },
|
||||||
};
|
};
|
||||||
|
|
||||||
export * from '@/constants/knowledge';
|
export * from '@/constants/knowledge';
|
||||||
|
|||||||
@ -19,6 +19,7 @@ export const useChangeDocumentParser = () => {
|
|||||||
if (record?.id) {
|
if (record?.id) {
|
||||||
const ret = await setDocumentParser({
|
const ret = await setDocumentParser({
|
||||||
parserId: parserConfigInfo.parser_id,
|
parserId: parserConfigInfo.parser_id,
|
||||||
|
pipelineId: parserConfigInfo.pipeline_id,
|
||||||
documentId: record?.id,
|
documentId: record?.id,
|
||||||
parserConfig: parserConfigInfo.parser_config,
|
parserConfig: parserConfigInfo.parser_config,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
import FileStatusBadge from '@/components/file-status-badge';
|
import FileStatusBadge from '@/components/file-status-badge';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Modal } from '@/components/ui/modal/modal';
|
import { Modal } from '@/components/ui/modal/modal';
|
||||||
|
import { RunningStatusMap } from '@/constants/knowledge';
|
||||||
import { useTranslate } from '@/hooks/common-hooks';
|
import { useTranslate } from '@/hooks/common-hooks';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import reactStringReplace from 'react-string-replace';
|
import reactStringReplace from 'react-string-replace';
|
||||||
|
import { RunningStatus } from './dataset/constant';
|
||||||
export interface ILogInfo {
|
export interface ILogInfo {
|
||||||
taskId?: string;
|
taskId?: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
fileSize?: string;
|
fileSize?: string;
|
||||||
source?: string;
|
source?: string;
|
||||||
task?: string;
|
task?: string;
|
||||||
state?: 'Running' | 'Success' | 'Failed' | 'Pending';
|
status?: RunningStatus;
|
||||||
startTime?: string;
|
startTime?: string;
|
||||||
endTime?: string;
|
endTime?: string;
|
||||||
duration?: string;
|
duration?: string;
|
||||||
@ -76,7 +78,10 @@ const ProcessLogModal: React.FC<ProcessLogModalProps> = ({
|
|||||||
<div className=" rounded-lg">
|
<div className=" rounded-lg">
|
||||||
<div className="flex flex-wrap ">
|
<div className="flex flex-wrap ">
|
||||||
{Object.keys(logInfo).map((key) => {
|
{Object.keys(logInfo).map((key) => {
|
||||||
if (blackKeyList.includes(key)) {
|
if (
|
||||||
|
blackKeyList.includes(key) ||
|
||||||
|
!logInfo[key as keyof typeof logInfo]
|
||||||
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (key === 'details') {
|
if (key === 'details') {
|
||||||
@ -93,12 +98,17 @@ const ProcessLogModal: React.FC<ProcessLogModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (key === 'Status') {
|
if (key === 'status') {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col" key={key}>
|
<div className="flex flex-col w-1/2" key={key}>
|
||||||
<span className="text-text-secondary text-sm">Status</span>
|
<span className="text-text-secondary text-sm">
|
||||||
|
{t('status')}
|
||||||
|
</span>
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<FileStatusBadge status={logInfo.state} />
|
<FileStatusBadge
|
||||||
|
status={logInfo.status as RunningStatus}
|
||||||
|
name={RunningStatusMap[logInfo.status as RunningStatus]}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -9,7 +9,13 @@ import { cn, formatBytes } from '@/lib/utils';
|
|||||||
import { Routes } from '@/routes';
|
import { Routes } from '@/routes';
|
||||||
import { formatPureDate } from '@/utils/date';
|
import { formatPureDate } from '@/utils/date';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import { Banknote, FileSearch2, FolderOpen, GitGraph } from 'lucide-react';
|
import {
|
||||||
|
Banknote,
|
||||||
|
DatabaseZap,
|
||||||
|
FileSearch2,
|
||||||
|
FolderOpen,
|
||||||
|
GitGraph,
|
||||||
|
} from 'lucide-react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHandleMenuClick } from './hooks';
|
import { useHandleMenuClick } from './hooks';
|
||||||
@ -28,11 +34,11 @@ export function SideBar({ refreshCount }: PropType) {
|
|||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
const list = [
|
const list = [
|
||||||
// {
|
{
|
||||||
// icon: DatabaseZap,
|
icon: DatabaseZap,
|
||||||
// label: t(`knowledgeDetails.overview`),
|
label: t(`knowledgeDetails.overview`),
|
||||||
// key: Routes.DataSetOverview,
|
key: Routes.DataSetOverview,
|
||||||
// },
|
},
|
||||||
{
|
{
|
||||||
icon: FolderOpen,
|
icon: FolderOpen,
|
||||||
label: t(`knowledgeDetails.subbarFiles`),
|
label: t(`knowledgeDetails.subbarFiles`),
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import { Input } from '@/components/ui/input';
|
|||||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||||
import { IModalProps } from '@/interfaces/common';
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ export function InputForm({ onOk }: IModalProps<any>) {
|
|||||||
})
|
})
|
||||||
.trim(),
|
.trim(),
|
||||||
parser_id: z.string().optional(),
|
parser_id: z.string().optional(),
|
||||||
pipline_id: z.string().optional(),
|
pipeline_id: z.string().optional(),
|
||||||
})
|
})
|
||||||
.superRefine((data, ctx) => {
|
.superRefine((data, ctx) => {
|
||||||
// When parseType === 1, parser_id is required
|
// When parseType === 1, parser_id is required
|
||||||
@ -67,11 +67,11 @@ export function InputForm({ onOk }: IModalProps<any>) {
|
|||||||
|
|
||||||
console.log('form-data', data);
|
console.log('form-data', data);
|
||||||
// When parseType === 1, pipline_id required
|
// When parseType === 1, pipline_id required
|
||||||
if (data.parseType === 2 && !data.pipline_id) {
|
if (data.parseType === 2 && !data.pipeline_id) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
message: t('knowledgeList.dataFlowRequired'),
|
message: t('knowledgeList.dataFlowRequired'),
|
||||||
path: ['pipline_id'],
|
path: ['pipeline_id'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -126,19 +126,13 @@ export function InputForm({ onOk }: IModalProps<any>) {
|
|||||||
|
|
||||||
<EmbeddingModelItem line={2} isEdit={false} />
|
<EmbeddingModelItem line={2} isEdit={false} />
|
||||||
<ParseTypeItem />
|
<ParseTypeItem />
|
||||||
{parseType === 1 && (
|
{parseType === 1 && <ChunkMethodItem></ChunkMethodItem>}
|
||||||
<>
|
|
||||||
<ChunkMethodItem></ChunkMethodItem>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{parseType === 2 && (
|
{parseType === 2 && (
|
||||||
<>
|
|
||||||
<DataFlowSelect
|
<DataFlowSelect
|
||||||
isMult={false}
|
isMult={false}
|
||||||
toDataPipeline={navigateToAgents}
|
toDataPipeline={navigateToAgents}
|
||||||
formFieldName="pipline_id"
|
formFieldName="pipeline_id"
|
||||||
/>
|
/>
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@ -40,6 +40,7 @@ const {
|
|||||||
getMeta,
|
getMeta,
|
||||||
retrievalTestShare,
|
retrievalTestShare,
|
||||||
getKnowledgeBasicInfo,
|
getKnowledgeBasicInfo,
|
||||||
|
fetchDataPipelineLog,
|
||||||
} = api;
|
} = api;
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
@ -174,6 +175,14 @@ const methods = {
|
|||||||
url: getKnowledgeBasicInfo,
|
url: getKnowledgeBasicInfo,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
|
fetchDataPipelineLog: {
|
||||||
|
url: fetchDataPipelineLog,
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
get_pipeline_detail: {
|
||||||
|
url: api.get_pipeline_detail,
|
||||||
|
method: 'get',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const kbService = registerServer<keyof typeof methods>(methods, request);
|
const kbService = registerServer<keyof typeof methods>(methods, request);
|
||||||
@ -210,4 +219,9 @@ export const listDocument = (
|
|||||||
export const documentFilter = (kb_id: string) =>
|
export const documentFilter = (kb_id: string) =>
|
||||||
request.post(api.get_dataset_filter, { kb_id });
|
request.post(api.get_dataset_filter, { kb_id });
|
||||||
|
|
||||||
|
export const listDataPipelineLogDocument = (
|
||||||
|
params?: IFetchKnowledgeListRequestParams,
|
||||||
|
body?: IFetchDocumentListRequestBody,
|
||||||
|
) => request.post(api.fetchDataPipelineLog, { data: body || {}, params });
|
||||||
|
|
||||||
export default kbService;
|
export default kbService;
|
||||||
|
|||||||
@ -46,6 +46,9 @@ export default {
|
|||||||
`${api_host}/kb/${knowledgeId}/knowledge_graph`,
|
`${api_host}/kb/${knowledgeId}/knowledge_graph`,
|
||||||
getMeta: `${api_host}/kb/get_meta`,
|
getMeta: `${api_host}/kb/get_meta`,
|
||||||
getKnowledgeBasicInfo: `${api_host}/kb/basic_info`,
|
getKnowledgeBasicInfo: `${api_host}/kb/basic_info`,
|
||||||
|
// data pipeline log
|
||||||
|
fetchDataPipelineLog: `${api_host}/kb/list_pipeline_logs`,
|
||||||
|
get_pipeline_detail: `${api_host}/kb/pipeline_log_detail`,
|
||||||
|
|
||||||
// tags
|
// tags
|
||||||
listTag: (knowledgeId: string) => `${api_host}/kb/${knowledgeId}/tags`,
|
listTag: (knowledgeId: string) => `${api_host}/kb/${knowledgeId}/tags`,
|
||||||
|
|||||||
Reference in New Issue
Block a user