diff --git a/web/public/iconfont.js b/web/public/iconfont.js index 12cb9978c..bbb539fea 100644 --- a/web/public/iconfont.js +++ b/web/public/iconfont.js @@ -1,5 +1,6 @@ (window._iconfont_svg_string_4909832 = '' + + '' + '' + '' + '' + diff --git a/web/src/components/data-pipeline-select/index.tsx b/web/src/components/data-pipeline-select/index.tsx index 523dbdef4..976ca6272 100644 --- a/web/src/components/data-pipeline-select/index.tsx +++ b/web/src/components/data-pipeline-select/index.tsx @@ -1,7 +1,10 @@ import { useTranslate } from '@/hooks/common-hooks'; +import { useFetchAgentList } from '@/hooks/use-agent-request'; import { buildSelectOptions } from '@/utils/component-util'; import { ArrowUpRight } from 'lucide-react'; +import { useMemo } from 'react'; import { useFormContext } from 'react-hook-form'; +import { SelectWithSearch } from '../originui/select-with-search'; import { FormControl, FormField, @@ -9,11 +12,12 @@ import { FormLabel, FormMessage, } from '../ui/form'; -import { RAGFlowSelect } from '../ui/select'; +import { MultiSelect } from '../ui/multi-select'; interface IProps { toDataPipeline?: () => void; formFieldName: string; + isMult?: boolean; } const data = [ @@ -22,16 +26,25 @@ const data = [ { id: '3', name: 'data-pipeline-3' }, { id: '4', name: 'data-pipeline-4' }, ]; -export function DataFlowItem(props: IProps) { - const { toDataPipeline, formFieldName } = props; +export function DataFlowSelect(props: IProps) { + const { toDataPipeline, formFieldName, isMult = true } = props; const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); + console.log('data-pipline form', form); const toDataPipLine = () => { - // window.open('/data-pipeline'); - toDataPipeline?.(); }; - const options = buildSelectOptions(data, 'id', 'name'); + const { data: dataPipelineOptions, loading } = useFetchAgentList({ + canvas_category: 'dataflow_canvas', + }); + const options = useMemo(() => { + const option = buildSelectOptions( + dataPipelineOptions?.canvas, + 'id', + 'title', + ); + return option || []; + }, [dataPipelineOptions]); return ( - + <> + {!isMult && ( + + )} + {isMult && ( + + )} +
-
diff --git a/web/src/components/entity-types-form-field.tsx b/web/src/components/entity-types-form-field.tsx index 6008b20b0..0cc6b9f07 100644 --- a/web/src/components/entity-types-form-field.tsx +++ b/web/src/components/entity-types-form-field.tsx @@ -26,7 +26,7 @@ export function EntityTypesFormField({ return (
- + * {t('entityTypes')}
diff --git a/web/src/components/home-card.tsx b/web/src/components/home-card.tsx index c112c2ec2..ff355dae2 100644 --- a/web/src/components/home-card.tsx +++ b/web/src/components/home-card.tsx @@ -39,8 +39,8 @@ export function HomeCard({ />
-
-
+
+
{data.name}
diff --git a/web/src/components/originui/select-with-search.tsx b/web/src/components/originui/select-with-search.tsx index 899fb529c..cffe160e5 100644 --- a/web/src/components/originui/select-with-search.tsx +++ b/web/src/components/originui/select-with-search.tsx @@ -45,6 +45,8 @@ export type SelectWithSearchFlagProps = { onChange?(value: string): void; triggerClassName?: string; allowClear?: boolean; + disabled?: boolean; + placeholder?: string; }; export const SelectWithSearch = forwardRef< @@ -58,6 +60,8 @@ export const SelectWithSearch = forwardRef< options = [], triggerClassName, allowClear = false, + disabled = false, + placeholder = t('common.selectPlaceholder'), }, ref, ) => { @@ -105,6 +109,7 @@ export const SelectWithSearch = forwardRef< role="combobox" aria-expanded={open} ref={ref} + disabled={disabled} className={cn( 'bg-background hover:bg-background border-input w-full justify-between px-3 font-normal outline-offset-0 outline-none focus-visible:outline-[3px] [&_svg]:pointer-events-auto', triggerClassName, @@ -115,9 +120,7 @@ export const SelectWithSearch = forwardRef< {selectLabel} ) : ( - - {t('common.selectPlaceholder')} - + {placeholder} )}
{value && allowClear && ( diff --git a/web/src/components/parse-configuration/graph-rag-form-fields.tsx b/web/src/components/parse-configuration/graph-rag-form-fields.tsx index 21a239938..8d40b2a66 100644 --- a/web/src/components/parse-configuration/graph-rag-form-fields.tsx +++ b/web/src/components/parse-configuration/graph-rag-form-fields.tsx @@ -62,7 +62,7 @@ export function UseGraphRagFormField() {
{t('useGraphRag')} @@ -125,7 +125,7 @@ const GraphRagItems = ({
{t('resolution')} @@ -190,7 +190,7 @@ const GraphRagItems = ({
{t('community')} diff --git a/web/src/components/parse-configuration/raptor-form-fields.tsx b/web/src/components/parse-configuration/raptor-form-fields.tsx index 9f3fb2061..5f1606b92 100644 --- a/web/src/components/parse-configuration/raptor-form-fields.tsx +++ b/web/src/components/parse-configuration/raptor-form-fields.tsx @@ -2,11 +2,10 @@ import { FormLayout } from '@/constants/form'; import { DocumentParserType } from '@/constants/knowledge'; import { useTranslate } from '@/hooks/common-hooks'; import random from 'lodash/random'; -import { Plus } from 'lucide-react'; +import { Shuffle } from 'lucide-react'; import { useCallback } from 'react'; import { useFormContext, useWatch } from 'react-hook-form'; import { SliderInputFormField } from '../slider-input-form-field'; -import { Button } from '../ui/button'; import { FormControl, FormField, @@ -14,7 +13,7 @@ import { FormLabel, FormMessage, } from '../ui/form'; -import { Input } from '../ui/input'; +import { ExpandedInput } from '../ui/input'; import { Switch } from '../ui/switch'; import { Textarea } from '../ui/textarea'; @@ -93,7 +92,7 @@ const RaptorFormFields = () => {
{t('useRaptor')} @@ -130,7 +129,7 @@ const RaptorFormFields = () => {
{t('prompt')} @@ -185,21 +184,23 @@ const RaptorFormFields = () => { render={({ field }) => (
- + {t('randomSeed')}
-
- - -
+ + } + />
diff --git a/web/src/components/slider-input-form-field.tsx b/web/src/components/slider-input-form-field.tsx index c31408192..b8d408ad9 100644 --- a/web/src/components/slider-input-form-field.tsx +++ b/web/src/components/slider-input-form-field.tsx @@ -54,8 +54,7 @@ export function SliderInputFormField({ {label} diff --git a/web/src/hooks/logic-hooks/navigate-hooks.ts b/web/src/hooks/logic-hooks/navigate-hooks.ts index c86822edf..eacb331d2 100644 --- a/web/src/hooks/logic-hooks/navigate-hooks.ts +++ b/web/src/hooks/logic-hooks/navigate-hooks.ts @@ -18,7 +18,7 @@ export const useNavigatePage = () => { const navigateToDataset = useCallback( (id: string) => () => { - navigate(`${Routes.Dataset}/${id}`); + navigate(`${Routes.DatasetBase}${Routes.DataSetOverview}/${id}`); }, [navigate], ); diff --git a/web/src/hooks/use-agent-request.ts b/web/src/hooks/use-agent-request.ts index 965f8cebf..9629e610c 100644 --- a/web/src/hooks/use-agent-request.ts +++ b/web/src/hooks/use-agent-request.ts @@ -7,6 +7,7 @@ import { IAgentLogsResponse, IFlow, IFlowTemplate, + IPipeLineListRequest, ITraceData, } from '@/interfaces/database/agent'; import { IDebugSingleRequestBody } from '@/interfaces/request/agent'; @@ -16,6 +17,7 @@ import { IInputs } from '@/pages/agent/interface'; import { useGetSharedChatSearchParams } from '@/pages/chat/shared-hooks'; import agentService, { fetchAgentLogsByCanvasId, + fetchPipeLineList, fetchTrace, } from '@/services/agent-service'; import api from '@/utils/api'; @@ -648,3 +650,26 @@ export const useFetchPrompt = () => { return { data, loading, refetch }; }; + +export const useFetchAgentList = ({ + canvas_category = 'agent_canvas', +}: IPipeLineListRequest): { + data: { + canvas: IFlow[]; + total: number; + }; + loading: boolean; +} => { + const { data, isFetching: loading } = useQuery({ + queryKey: ['fetchPipeLineList'], + initialData: [], + gcTime: 0, + queryFn: async () => { + const { data } = await fetchPipeLineList({ canvas_category }); + + return data?.data ?? []; + }, + }); + + return { data, loading }; +}; diff --git a/web/src/hooks/use-knowledge-request.ts b/web/src/hooks/use-knowledge-request.ts index 3251afe79..e8b7cbe87 100644 --- a/web/src/hooks/use-knowledge-request.ts +++ b/web/src/hooks/use-knowledge-request.ts @@ -236,7 +236,11 @@ export const useUpdateKnowledge = (shouldFetchList = false) => { return { data, loading, saveKnowledgeConfiguration: mutateAsync }; }; -export const useFetchKnowledgeBaseConfiguration = (refreshCount?: number) => { +export const useFetchKnowledgeBaseConfiguration = (props?: { + isEdit?: boolean; + refreshCount?: number; +}) => { + const { isEdit = true, refreshCount } = props || { isEdit: true }; const { id } = useParams(); const [searchParams] = useSearchParams(); const knowledgeBaseId = searchParams.get('id') || id; @@ -253,10 +257,14 @@ export const useFetchKnowledgeBaseConfiguration = (refreshCount?: number) => { initialData: {} as IKnowledge, gcTime: 0, queryFn: async () => { - const { data } = await kbService.get_kb_detail({ - kb_id: knowledgeBaseId, - }); - return data?.data ?? {}; + if (isEdit) { + const { data } = await kbService.get_kb_detail({ + kb_id: knowledgeBaseId, + }); + return data?.data ?? {}; + } else { + return {}; + } }, }); diff --git a/web/src/interfaces/database/agent.ts b/web/src/interfaces/database/agent.ts index 76947a92a..32014ea6a 100644 --- a/web/src/interfaces/database/agent.ts +++ b/web/src/interfaces/database/agent.ts @@ -266,3 +266,12 @@ export interface IAgentLogMessage { role: 'user' | 'assistant'; id: string; } + +export interface IPipeLineListRequest { + page?: number; + page_size?: number; + keywords?: string; + orderby?: string; + desc?: boolean; + canvas_category?: 'agent_canvas' | 'dataflow_canvas'; +} diff --git a/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx b/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx index 07a36e1e7..358f26603 100644 --- a/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx +++ b/web/src/pages/dataset/dataset-setting/components/link-data-pipeline.tsx @@ -1,17 +1,21 @@ +import { IconFont } from '@/components/icon-font'; import { RAGFlowAvatar } from '@/components/ragflow-avatar'; import { Button } from '@/components/ui/button'; -import { Link, Route, Settings2, Unlink } from 'lucide-react'; +import { Link, Settings2, Unlink } from 'lucide-react'; +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; +import LinkDataPipelineModal from './link-data-pipline-modal'; interface DataPipelineItemProps { name: string; avatar?: string; isDefault?: boolean; linked?: boolean; + openLinkModalFunc?: (open: boolean) => void; } const DataPipelineItem = (props: DataPipelineItemProps) => { const { t } = useTranslation(); - const { name, avatar, isDefault, linked } = props; + const { name, avatar, isDefault, linked, openLinkModalFunc } = props; return (
@@ -27,15 +31,24 @@ const DataPipelineItem = (props: DataPipelineItemProps) => { - + {!isDefault && ( + + )}
); }; const LinkDataPipeline = () => { const { t } = useTranslation(); + const [openLinkModal, setOpenLinkModal] = useState(false); const testNode = [ { name: 'Data Pipeline 1', @@ -49,11 +62,14 @@ const LinkDataPipeline = () => { linked: false, }, ]; + const openLinkModalFunc = (open: boolean) => { + setOpenLinkModal(open); + }; return (
- + {t('knowledgeConfiguration.dataPipeline')}
@@ -70,9 +86,19 @@ const LinkDataPipeline = () => {
{testNode.map((item) => ( - + ))}
+ { + openLinkModalFunc(open); + }} + />
); }; diff --git a/web/src/pages/dataset/dataset-setting/components/link-data-pipline-modal.tsx b/web/src/pages/dataset/dataset-setting/components/link-data-pipline-modal.tsx new file mode 100644 index 000000000..d84f1562f --- /dev/null +++ b/web/src/pages/dataset/dataset-setting/components/link-data-pipline-modal.tsx @@ -0,0 +1,95 @@ +import { DataFlowSelect } from '@/components/data-pipeline-select'; +import Input from '@/components/originui/input'; +import { Button } from '@/components/ui/button'; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { Modal } from '@/components/ui/modal/modal'; +import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { t } from 'i18next'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { linkPiplineFormSchema } from '../form-schema'; + +const LinkDataPipelineModal = ({ + open, + setOpen, +}: { + open: boolean; + setOpen: (open: boolean) => void; +}) => { + const form = useForm>({ + resolver: zodResolver(linkPiplineFormSchema), + defaultValues: { data_flow: ['888'], file_filter: '' }, + }); + // const [open, setOpen] = useState(false); + const { navigateToAgents } = useNavigatePage(); + const handleFormSubmit = (values: any) => { + console.log(values); + }; + return ( + +
+ +
+ + ( + +
+
+ + {t('knowledgeConfiguration.fileFilter')} + +
+ +
+ + + +
+
+
+
+ +
+
+ )} + /> +
+ + +
+
+
+ +
+ ); +}; +export default LinkDataPipelineModal; diff --git a/web/src/pages/dataset/dataset-setting/configuration-form-container.tsx b/web/src/pages/dataset/dataset-setting/configuration-form-container.tsx index 93e30ffb7..f262e3ea8 100644 --- a/web/src/pages/dataset/dataset-setting/configuration-form-container.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration-form-container.tsx @@ -9,6 +9,9 @@ export function ConfigurationFormContainer({ return
{children}
; } -export function MainContainer({ children }: PropsWithChildren) { - return
{children}
; +export function MainContainer({ + children, + className, +}: PropsWithChildren & { className?: string }) { + return
{children}
; } diff --git a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx index 6c36f1801..973ba320c 100644 --- a/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx +++ b/web/src/pages/dataset/dataset-setting/configuration/common-item.tsx @@ -1,3 +1,4 @@ +import { SelectWithSearch } from '@/components/originui/select-with-search'; import { FormControl, FormField, @@ -16,8 +17,12 @@ import { useSelectChunkMethodList, useSelectEmbeddingModelOptions, } from '../hooks'; - -export function ChunkMethodItem() { +interface IProps { + line?: 1 | 2; + isEdit?: boolean; +} +export function ChunkMethodItem(props: IProps) { + const { line } = props; const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); // const handleChunkMethodSelectChange = useHandleChunkMethodSelectChange(form); @@ -28,28 +33,29 @@ export function ChunkMethodItem() { control={form.control} name={'parser_id'} render={({ field }) => ( - -
+ +
{t('chunkMethod')} -
+
-
+
@@ -57,54 +63,55 @@ export function ChunkMethodItem() { /> ); } - -export function EmbeddingModelItem({ line = 1 }: { line?: 1 | 2 }) { +export function EmbeddingModelItem({ line = 1, isEdit = true }: IProps) { const { t } = useTranslate('knowledgeConfiguration'); const form = useFormContext(); const embeddingModelOptions = useSelectEmbeddingModelOptions(); - const disabled = useHasParsedDocument(); - + const disabled = useHasParsedDocument(isEdit); return ( - ( - -
- + ( + +
- {t('embeddingModel')} - -
- - - + + {t('embeddingModel')} + +
+ + + +
-
-
-
- -
-
- )} - /> +
+
+ +
+ + )} + /> + ); } diff --git a/web/src/pages/dataset/dataset-setting/form-schema.ts b/web/src/pages/dataset/dataset-setting/form-schema.ts index 1594ba362..d0c669b14 100644 --- a/web/src/pages/dataset/dataset-setting/form-schema.ts +++ b/web/src/pages/dataset/dataset-setting/form-schema.ts @@ -71,3 +71,8 @@ export const formSchema = z.object({ pagerank: z.number(), // icon: z.array(z.instanceof(File)), }); + +export const linkPiplineFormSchema = z.object({ + data_flow: z.array(z.string()), + file_filter: z.string().optional(), +}); diff --git a/web/src/pages/dataset/dataset-setting/general-form.tsx b/web/src/pages/dataset/dataset-setting/general-form.tsx index 10aa31d82..069b3dbfa 100644 --- a/web/src/pages/dataset/dataset-setting/general-form.tsx +++ b/web/src/pages/dataset/dataset-setting/general-form.tsx @@ -24,7 +24,7 @@ export function GeneralForm() { render={({ field }) => (
- + * {t('common.name')} @@ -45,7 +45,7 @@ export function GeneralForm() { render={({ field }) => (
- + {t('setting.avatar')} @@ -70,7 +70,7 @@ export function GeneralForm() { return (
- + {t('flow.description')} diff --git a/web/src/pages/dataset/dataset-setting/hooks.ts b/web/src/pages/dataset/dataset-setting/hooks.ts index 3332ca3f5..9fdcb9981 100644 --- a/web/src/pages/dataset/dataset-setting/hooks.ts +++ b/web/src/pages/dataset/dataset-setting/hooks.ts @@ -25,8 +25,10 @@ export function useSelectEmbeddingModelOptions() { return allOptions[LlmModelType.Embedding]; } -export function useHasParsedDocument() { - const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration(); +export function useHasParsedDocument(isEdit?: boolean) { + const { data: knowledgeDetails } = useFetchKnowledgeBaseConfiguration({ + isEdit, + }); return knowledgeDetails.chunk_num > 0; } @@ -52,7 +54,7 @@ export const useFetchKnowledgeConfigurationOnMount = ( 'pagerank', 'avatar', ]), - }; + } as z.infer; form.reset(formValues); }, [form, knowledgeDetails]); diff --git a/web/src/pages/dataset/dataset-setting/index.tsx b/web/src/pages/dataset/dataset-setting/index.tsx index 0d24a79d5..3e5172171 100644 --- a/web/src/pages/dataset/dataset-setting/index.tsx +++ b/web/src/pages/dataset/dataset-setting/index.tsx @@ -82,7 +82,7 @@ export default function DatasetSettings() { className="space-y-6 flex-1" >
- + diff --git a/web/src/pages/dataset/sidebar/index.tsx b/web/src/pages/dataset/sidebar/index.tsx index bcc160e22..dbced0871 100644 --- a/web/src/pages/dataset/sidebar/index.tsx +++ b/web/src/pages/dataset/sidebar/index.tsx @@ -28,7 +28,7 @@ export function SideBar({ refreshCount }: PropType) { const pathName = useSecondPathName(); const { handleMenuClick } = useHandleMenuClick(); // refreshCount: be for avatar img sync update on top left - const { data } = useFetchKnowledgeBaseConfiguration(refreshCount); + const { data } = useFetchKnowledgeBaseConfiguration({ refreshCount }); const { data: routerData } = useFetchKnowledgeGraph(); const { t } = useTranslation(); @@ -52,7 +52,7 @@ export function SideBar({ refreshCount }: PropType) { { icon: Banknote, label: t(`knowledgeDetails.configuration`), - key: Routes.DatasetSetting, + key: Routes.DataSetSetting, }, ]; if (!isEmpty(routerData?.graph)) { diff --git a/web/src/pages/datasets/dataset-creating-dialog.tsx b/web/src/pages/datasets/dataset-creating-dialog.tsx index d320a924e..904e25270 100644 --- a/web/src/pages/datasets/dataset-creating-dialog.tsx +++ b/web/src/pages/datasets/dataset-creating-dialog.tsx @@ -1,4 +1,4 @@ -import { DataFlowItem } from '@/components/data-pipeline-select'; +import { DataFlowSelect } from '@/components/data-pipeline-select'; import { ButtonLoading } from '@/components/ui/button'; import { Dialog, @@ -23,6 +23,7 @@ import { useForm, useWatch } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { z } from 'zod'; import { + ChunkMethodItem, EmbeddingModelItem, ParseTypeItem, } from '../dataset/dataset-setting/configuration/common-item'; @@ -32,32 +33,68 @@ const FormId = 'dataset-creating-form'; export function InputForm({ onOk }: IModalProps) { const { t } = useTranslation(); - const FormSchema = z.object({ - name: z - .string() - .min(1, { - message: t('knowledgeList.namePlaceholder'), - }) - .trim(), - parseType: z.number().optional(), - }); + const FormSchema = z + .object({ + name: z + .string() + .min(1, { + message: t('knowledgeList.namePlaceholder'), + }) + .trim(), + parseType: z.number().optional(), + embd_id: z + .string() + .min(1, { + message: t('knowledgeConfiguration.embeddingModelPlaceholder'), + }) + .trim(), + parser_id: z.string().optional(), + pipline_id: z.string().optional(), + }) + .superRefine((data, ctx) => { + // When parseType === 1, parser_id is required + if ( + data.parseType === 1 && + (!data.parser_id || data.parser_id.trim() === '') + ) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: t('knowledgeList.parserRequired'), + path: ['parser_id'], + }); + } + + console.log('form-data', data); + // When parseType === 1, pipline_id required + if (data.parseType === 2 && !data.pipline_id) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: t('knowledgeList.dataFlowRequired'), + path: ['pipline_id'], + }); + } + }); const form = useForm>({ resolver: zodResolver(FormSchema), defaultValues: { name: '', parseType: 1, + parser_id: '', + embd_id: '', }, }); function onSubmit(data: z.infer) { - onOk?.(data.name); + console.log('submit', data); + onOk?.(data); } const parseType = useWatch({ control: form.control, name: 'parseType', }); const { navigateToAgents } = useNavigatePage(); + return (
) { )} /> - + + {parseType === 1 && ( + <> + + + )} {parseType === 2 && ( <> - )} @@ -108,7 +151,7 @@ export function DatasetCreatingDialog({ return ( - + {t('knowledgeList.createKnowledgeBase')} diff --git a/web/src/pages/datasets/hooks.ts b/web/src/pages/datasets/hooks.ts index 81f9d74f7..d194af9e1 100644 --- a/web/src/pages/datasets/hooks.ts +++ b/web/src/pages/datasets/hooks.ts @@ -2,7 +2,6 @@ import { useSetModalState } from '@/hooks/common-hooks'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { useCreateKnowledge } from '@/hooks/use-knowledge-request'; import { useCallback, useState } from 'react'; - export const useSearchKnowledge = () => { const [searchString, setSearchString] = useState(''); @@ -15,16 +14,19 @@ export const useSearchKnowledge = () => { }; }; +export interface Iknowledge { + name: string; + embd_id: string; + parser_id: string; +} export const useSaveKnowledge = () => { const { visible: visible, hideModal, showModal } = useSetModalState(); const { loading, createKnowledge } = useCreateKnowledge(); const { navigateToDataset } = useNavigatePage(); const onCreateOk = useCallback( - async (name: string) => { - const ret = await createKnowledge({ - name, - }); + async (data: Iknowledge) => { + const ret = await createKnowledge(data); if (ret?.code === 0) { hideModal(); diff --git a/web/src/services/agent-service.ts b/web/src/services/agent-service.ts index 6c0b3aceb..367cfa8be 100644 --- a/web/src/services/agent-service.ts +++ b/web/src/services/agent-service.ts @@ -1,4 +1,7 @@ -import { IAgentLogsRequest } from '@/interfaces/database/agent'; +import { + IAgentLogsRequest, + IPipeLineListRequest, +} from '@/interfaces/database/agent'; import api from '@/utils/api'; import { registerNextServer } from '@/utils/register-server'; import request from '@/utils/request'; @@ -131,4 +134,8 @@ export const fetchAgentLogsByCanvasId = ( return request.get(methods.fetchAgentLogs.url(canvasId), { params: params }); }; +export const fetchPipeLineList = (params: IPipeLineListRequest) => { + return request.get(api.listCanvas, { params: params }); +}; + export default agentService; diff --git a/web/src/utils/component-util.ts b/web/src/utils/component-util.ts index 954b721a3..a28d3996d 100644 --- a/web/src/utils/component-util.ts +++ b/web/src/utils/component-util.ts @@ -3,6 +3,9 @@ export function buildSelectOptions( keyName?: string, valueName?: string, ) { + if (!Array.isArray(list) || !list.length) { + return []; + } if (keyName && valueName) { return list.map((x) => ({ label: x[valueName], value: x[keyName] })); }