瀏覽代碼

refactor: rename selectedFileKeys to selectedFileIds and update related logic in online drive components

tags/2.0.0-beta.1
twwu 2 月之前
父節點
當前提交
9893b8110d

+ 6
- 6
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/file-list/header/breadcrumbs/index.tsx 查看文件

}, [displayBreadcrumbNum, prefix]) }, [displayBreadcrumbNum, prefix])


const handleBackToBucketList = useCallback(() => { const handleBackToBucketList = useCallback(() => {
const { setFileList, setSelectedFileKeys, setPrefix, setBucket } = dataSourceStore.getState()
const { setFileList, setSelectedFileIds, setPrefix, setBucket } = dataSourceStore.getState()
setFileList([]) setFileList([])
setSelectedFileKeys([])
setSelectedFileIds([])
setBucket('') setBucket('')
setPrefix([]) setPrefix([])
}, [dataSourceStore]) }, [dataSourceStore])


const handleClickBucketName = useCallback(() => { const handleClickBucketName = useCallback(() => {
const { setFileList, setSelectedFileKeys, setPrefix } = dataSourceStore.getState()
const { setFileList, setSelectedFileIds, setPrefix } = dataSourceStore.getState()
setFileList([]) setFileList([])
setSelectedFileKeys([])
setSelectedFileIds([])
setPrefix([]) setPrefix([])
}, [dataSourceStore]) }, [dataSourceStore])


const handleClickBreadcrumb = useCallback((index: number) => { const handleClickBreadcrumb = useCallback((index: number) => {
const { prefix, setFileList, setSelectedFileKeys, setPrefix } = dataSourceStore.getState()
const { prefix, setFileList, setSelectedFileIds, setPrefix } = dataSourceStore.getState()
const newPrefix = prefix.slice(0, index + 1) const newPrefix = prefix.slice(0, index + 1)
setFileList([]) setFileList([])
setSelectedFileKeys([])
setSelectedFileIds([])
setPrefix(newPrefix) setPrefix(newPrefix)
}, [dataSourceStore]) }, [dataSourceStore])



+ 3
- 3
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/file-list/index.tsx 查看文件



type FileListProps = { type FileListProps = {
fileList: OnlineDriveFile[] fileList: OnlineDriveFile[]
selectedFileKeys: string[]
selectedFileIds: string[]
prefix: string[] prefix: string[]
keywords: string keywords: string
bucket: string bucket: string


const FileList = ({ const FileList = ({
fileList, fileList,
selectedFileKeys,
selectedFileIds,
prefix, prefix,
keywords, keywords,
bucket, bucket,
/> />
<List <List
fileList={fileList} fileList={fileList}
selectedFileKeys={selectedFileKeys}
selectedFileIds={selectedFileIds}
keywords={keywords} keywords={keywords}
handleResetKeywords={handleResetKeywords} handleResetKeywords={handleResetKeywords}
handleOpenFolder={handleOpenFolder} handleOpenFolder={handleOpenFolder}

+ 6
- 6
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/file-list/list/index.tsx 查看文件



type FileListProps = { type FileListProps = {
fileList: OnlineDriveFile[] fileList: OnlineDriveFile[]
selectedFileKeys: string[]
selectedFileIds: string[]
keywords: string keywords: string
isInPipeline: boolean isInPipeline: boolean
isLoading: boolean isLoading: boolean


const List = ({ const List = ({
fileList, fileList,
selectedFileKeys,
selectedFileIds,
keywords, keywords,
handleResetKeywords, handleResetKeywords,
handleSelectFile, handleSelectFile,
useEffect(() => { useEffect(() => {
if (anchorRef.current) { if (anchorRef.current) {
observerRef.current = new IntersectionObserver((entries) => { observerRef.current = new IntersectionObserver((entries) => {
const { setStartAfter, isTruncated } = dataSourceStore.getState()
const { setNextPageParameters, currentNextPageParametersRef, isTruncated } = dataSourceStore.getState()
if (entries[0].isIntersecting && isTruncated.current && !isLoading) if (entries[0].isIntersecting && isTruncated.current && !isLoading)
setStartAfter(fileList[fileList.length - 1].key)
setNextPageParameters(currentNextPageParametersRef.current)
}, { }, {
rootMargin: '100px', rootMargin: '100px',
}) })
<div className='flex h-full flex-col gap-y-px overflow-y-auto rounded-[10px] bg-background-section px-1 py-1.5'> <div className='flex h-full flex-col gap-y-px overflow-y-auto rounded-[10px] bg-background-section px-1 py-1.5'>
{ {
fileList.map((file) => { fileList.map((file) => {
const isSelected = selectedFileKeys.includes(file.key)
const isSelected = selectedFileIds.includes(file.id)
return ( return (
<Item <Item
key={file.key}
key={file.id}
file={file} file={file}
isSelected={isSelected} isSelected={isSelected}
onSelect={handleSelectFile} onSelect={handleSelectFile}

+ 10
- 9
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/file-list/list/item.tsx 查看文件

import Checkbox from '@/app/components/base/checkbox' import Checkbox from '@/app/components/base/checkbox'
import Radio from '@/app/components/base/radio/ui' import Radio from '@/app/components/base/radio/ui'
import type { OnlineDriveFile } from '@/models/pipeline' import type { OnlineDriveFile } from '@/models/pipeline'
import React, { useCallback } from 'react'
import React, { useCallback, useMemo } from 'react'
import FileIcon from './file-icon' import FileIcon from './file-icon'
import { formatFileSize } from '@/utils/format' import { formatFileSize } from '@/utils/format'
import Tooltip from '@/app/components/base/tooltip' import Tooltip from '@/app/components/base/tooltip'
onOpen, onOpen,
}: ItemProps) => { }: ItemProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const isBucket = file.type === 'bucket'
const isFolder = file.type === 'folder'
const { id, name, type, size } = file
const isBucket = useMemo(() => type === 'bucket', [type])
const isFolder = useMemo(() => type === 'folder', [type])


const Wrapper = disabled ? Tooltip : React.Fragment const Wrapper = disabled ? Tooltip : React.Fragment


<Checkbox <Checkbox
className='shrink-0' className='shrink-0'
disabled={disabled} disabled={disabled}
id={file.key}
id={id}
checked={isSelected} checked={isSelected}
onCheck={handleSelect} onCheck={handleSelect}
/> />
'flex grow items-center gap-x-1 overflow-hidden py-0.5', 'flex grow items-center gap-x-1 overflow-hidden py-0.5',
disabled && 'opacity-30', disabled && 'opacity-30',
)}> )}>
<FileIcon type={file.type} fileName={file.displayName} className='shrink-0' />
<FileIcon type={type} fileName={name} className='shrink-0' />
<span <span
className='system-sm-medium grow truncate text-text-secondary' className='system-sm-medium grow truncate text-text-secondary'
title={file.displayName}
title={name}
> >
{file.displayName}
{name}
</span> </span>
{!isFolder && typeof file.size === 'number' && (
<span className='system-xs-regular shrink-0 text-text-tertiary'>{formatFileSize(file.size)}</span>
{!isFolder && typeof size === 'number' && (
<span className='system-xs-regular shrink-0 text-text-tertiary'>{formatFileSize(size)}</span>
)} )}
</div> </div>
</Wrapper> </Wrapper>

+ 26
- 22
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/index.tsx 查看文件

const pipelineId = useDatasetDetailContextWithSelector(s => s.dataset?.pipeline_id) const pipelineId = useDatasetDetailContextWithSelector(s => s.dataset?.pipeline_id)
const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal) const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal)
const { const {
startAfter,
nextPageParameters,
prefix, prefix,
keywords, keywords,
bucket, bucket,
selectedFileKeys,
selectedFileIds,
fileList, fileList,
currentCredentialId, currentCredentialId,
} = useDataSourceStoreWithSelector(useShallow(state => ({ } = useDataSourceStoreWithSelector(useShallow(state => ({
startAfter: state.startAfter,
nextPageParameters: state.nextPageParameters,
prefix: state.prefix, prefix: state.prefix,
keywords: state.keywords, keywords: state.keywords,
bucket: state.bucket, bucket: state.bucket,
selectedFileKeys: state.selectedFileKeys,
selectedFileIds: state.selectedFileIds,
fileList: state.fileList, fileList: state.fileList,
currentCredentialId: state.currentCredentialId, currentCredentialId: state.currentCredentialId,
}))) })))
: `/rag/pipelines/${pipelineId}/workflows/draft/datasource/nodes/${nodeId}/run` : `/rag/pipelines/${pipelineId}/workflows/draft/datasource/nodes/${nodeId}/run`


const getOnlineDriveFiles = useCallback(async () => { const getOnlineDriveFiles = useCallback(async () => {
const { startAfter, prefix, bucket, fileList, currentCredentialId } = dataSourceStore.getState()
const { nextPageParameters, prefix, bucket, fileList, currentCredentialId } = dataSourceStore.getState()
const prefixString = prefix.length > 0 ? `${prefix.join('/')}/` : '' const prefixString = prefix.length > 0 ? `${prefix.join('/')}/` : ''
setIsLoading(true) setIsLoading(true)
ssePost( ssePost(
inputs: { inputs: {
prefix: prefixString, prefix: prefixString,
bucket, bucket,
start_after: startAfter,
next_page_parameters: nextPageParameters,
max_keys: 30, // Adjust as needed max_keys: 30, // Adjust as needed
}, },
datasource_type: DatasourceType.onlineDrive, datasource_type: DatasourceType.onlineDrive,
}, },
{ {
onDataSourceNodeCompleted: (documentsData: DataSourceNodeCompletedResponse) => { onDataSourceNodeCompleted: (documentsData: DataSourceNodeCompletedResponse) => {
const { setFileList, isTruncated } = dataSourceStore.getState()
const { fileList: newFileList, isTruncated: newIsTruncated } = convertOnlineDriveData(documentsData.data, prefix, bucket)
const { setFileList, isTruncated, currentNextPageParametersRef } = dataSourceStore.getState()
const {
fileList: newFileList,
isTruncated: newIsTruncated,
nextPageParameters: newNextPageParameters,
} = convertOnlineDriveData(documentsData.data, prefix, bucket)
setFileList([...fileList, ...newFileList]) setFileList([...fileList, ...newFileList])
isTruncated.current = newIsTruncated isTruncated.current = newIsTruncated
currentNextPageParametersRef.current = newNextPageParameters
setIsLoading(false) setIsLoading(false)
}, },
onDataSourceNodeError: (error: DataSourceNodeErrorResponse) => { onDataSourceNodeError: (error: DataSourceNodeErrorResponse) => {
else { else {
getOnlineDriveFiles() getOnlineDriveFiles()
} }
}, [startAfter, prefix, bucket, currentCredentialId])
}, [nextPageParameters, prefix, bucket, currentCredentialId])


const onlineDriveFileList = useMemo(() => { const onlineDriveFileList = useMemo(() => {
if (keywords) if (keywords)
return fileList.filter(file => file.key.toLowerCase().includes(keywords.toLowerCase()))
return fileList.filter(file => file.name.toLowerCase().includes(keywords.toLowerCase()))
return fileList return fileList
}, [fileList, keywords]) }, [fileList, keywords])


}, [dataSourceStore]) }, [dataSourceStore])


const handleSelectFile = useCallback((file: OnlineDriveFile) => { const handleSelectFile = useCallback((file: OnlineDriveFile) => {
const { selectedFileKeys, setSelectedFileKeys } = dataSourceStore.getState()
const { selectedFileIds, setSelectedFileIds } = dataSourceStore.getState()
if (file.type === OnlineDriveFileType.bucket) return if (file.type === OnlineDriveFileType.bucket) return
const newSelectedFileList = produce(selectedFileKeys, (draft) => {
if (draft.includes(file.key)) {
const index = draft.indexOf(file.key)
const newSelectedFileList = produce(selectedFileIds, (draft) => {
if (draft.includes(file.id)) {
const index = draft.indexOf(file.id)
draft.splice(index, 1) draft.splice(index, 1)
} }
else { else {
if (isInPipeline && draft.length >= 1) return if (isInPipeline && draft.length >= 1) return
draft.push(file.key)
draft.push(file.id)
} }
}) })
setSelectedFileKeys(newSelectedFileList)
setSelectedFileIds(newSelectedFileList)
}, [dataSourceStore, isInPipeline]) }, [dataSourceStore, isInPipeline])


const handleOpenFolder = useCallback((file: OnlineDriveFile) => { const handleOpenFolder = useCallback((file: OnlineDriveFile) => {
const { prefix, setPrefix, setBucket, setFileList, setSelectedFileKeys } = dataSourceStore.getState()
const { prefix, setPrefix, setBucket, setFileList, setSelectedFileIds } = dataSourceStore.getState()
if (file.type === OnlineDriveFileType.file) return if (file.type === OnlineDriveFileType.file) return
setFileList([]) setFileList([])
if (file.type === OnlineDriveFileType.bucket) { if (file.type === OnlineDriveFileType.bucket) {
setBucket(file.displayName)
setBucket(file.name)
} }
else { else {
setSelectedFileKeys([])
const displayName = file.displayName.endsWith('/') ? file.displayName.slice(0, -1) : file.displayName
setSelectedFileIds([])
const newPrefix = produce(prefix, (draft) => { const newPrefix = produce(prefix, (draft) => {
draft.push(displayName)
draft.push(file.name)
}) })
setPrefix(newPrefix) setPrefix(newPrefix)
} }
/> />
<FileList <FileList
fileList={onlineDriveFileList} fileList={onlineDriveFileList}
selectedFileKeys={selectedFileKeys}
selectedFileIds={selectedFileIds}
prefix={prefix} prefix={prefix}
keywords={keywords} keywords={keywords}
bucket={bucket} bucket={bucket}

+ 18
- 14
web/app/components/datasets/documents/create-from-pipeline/data-source/online-drive/utils.ts 查看文件

import { type OnlineDriveFile, OnlineDriveFileType } from '@/models/pipeline' import { type OnlineDriveFile, OnlineDriveFileType } from '@/models/pipeline'
import type { OnlineDriveData } from '@/types/pipeline' import type { OnlineDriveData } from '@/types/pipeline'


const filePathRegex = /^(?:.*\/)?[^\/]+\.[^\/\.]+$/

export const isFile = (path: string): boolean => {
return filePathRegex.test(path)
export const isFile = (type: 'file' | 'folder'): boolean => {
return type === 'file'
} }


export const isBucketListInitiation = (data: OnlineDriveData[], prefix: string[], bucket: string): boolean => { export const isBucketListInitiation = (data: OnlineDriveData[], prefix: string[], bucket: string): boolean => {
return data.length > 1 || (data.length === 1 && !!data[0].bucket && data[0].files.length === 0) return data.length > 1 || (data.length === 1 && !!data[0].bucket && data[0].files.length === 0)
} }


export const convertOnlineDriveData = (data: OnlineDriveData[], prefix: string[], bucket: string): { fileList: OnlineDriveFile[], isTruncated: boolean } => {
export const convertOnlineDriveData = (data: OnlineDriveData[], prefix: string[], bucket: string): {
fileList: OnlineDriveFile[],
isTruncated: boolean,
nextPageParameters: Record<string, any>
} => {
const fileList: OnlineDriveFile[] = [] const fileList: OnlineDriveFile[] = []
let isTruncated = false let isTruncated = false
let nextPageParameters: Record<string, any> = {}


if (data.length === 0) if (data.length === 0)
return { fileList, isTruncated }
return { fileList, isTruncated, nextPageParameters }


if (isBucketListInitiation(data, prefix, bucket)) { if (isBucketListInitiation(data, prefix, bucket)) {
data.forEach((item) => { data.forEach((item) => {
fileList.push({ fileList.push({
key: item.bucket,
displayName: item.bucket,
id: item.bucket,
name: item.bucket,
type: OnlineDriveFileType.bucket, type: OnlineDriveFileType.bucket,
}) })
}) })
} }
else { else {
data[0].files.forEach((file) => { data[0].files.forEach((file) => {
const isFileType = isFile(file.key)
const filePathList = file.key.split('/')
const { id, name, size, type } = file
const isFileType = isFile(type)
fileList.push({ fileList.push({
key: file.key,
displayName: `${isFileType ? filePathList.pop() : filePathList[filePathList.length - 2]}${isFileType ? '' : '/'}`,
size: isFileType ? file.size : undefined,
id,
name,
size: isFileType ? size : undefined,
type: isFileType ? OnlineDriveFileType.file : OnlineDriveFileType.folder, type: isFileType ? OnlineDriveFileType.file : OnlineDriveFileType.folder,
}) })
}) })
isTruncated = data[0].is_truncated ?? false isTruncated = data[0].is_truncated ?? false
nextPageParameters = data[0].next_page_parameters ?? {}
} }
return { fileList, isTruncated }
return { fileList, isTruncated, nextPageParameters }
} }

+ 14
- 12
web/app/components/datasets/documents/create-from-pipeline/data-source/store/slices/online-drive.ts 查看文件

setPrefix: (prefix: string[]) => void setPrefix: (prefix: string[]) => void
keywords: string keywords: string
setKeywords: (keywords: string) => void setKeywords: (keywords: string) => void
selectedFileKeys: string[]
setSelectedFileKeys: (selectedFileKeys: string[]) => void
selectedFileIds: string[]
setSelectedFileIds: (selectedFileIds: string[]) => void
fileList: OnlineDriveFile[] fileList: OnlineDriveFile[]
setFileList: (fileList: OnlineDriveFile[]) => void setFileList: (fileList: OnlineDriveFile[]) => void
bucket: string bucket: string
setBucket: (bucket: string) => void setBucket: (bucket: string) => void
startAfter: string
setStartAfter: (startAfter: string) => void
nextPageParameters: Record<string, any>
currentNextPageParametersRef: React.RefObject<Record<string, any>>
setNextPageParameters: (nextPageParameters: Record<string, any>) => void
isTruncated: React.RefObject<boolean> isTruncated: React.RefObject<boolean>
previewOnlineDriveFileRef: React.RefObject<OnlineDriveFile | undefined> previewOnlineDriveFileRef: React.RefObject<OnlineDriveFile | undefined>
} }
setKeywords: (keywords: string) => set(() => ({ setKeywords: (keywords: string) => set(() => ({
keywords, keywords,
})), })),
selectedFileKeys: [],
setSelectedFileKeys: (selectedFileKeys: string[]) => {
selectedFileIds: [],
setSelectedFileIds: (selectedFileIds: string[]) => {
set(() => ({ set(() => ({
selectedFileKeys,
selectedFileIds,
})) }))
const key = selectedFileKeys[0]
const id = selectedFileIds[0]
const { fileList, previewOnlineDriveFileRef } = get() const { fileList, previewOnlineDriveFileRef } = get()
previewOnlineDriveFileRef.current = fileList.find(file => file.key === key)
previewOnlineDriveFileRef.current = fileList.find(file => file.id === id)
}, },
fileList: [], fileList: [],
setFileList: (fileList: OnlineDriveFile[]) => set(() => ({ setFileList: (fileList: OnlineDriveFile[]) => set(() => ({
setBucket: (bucket: string) => set(() => ({ setBucket: (bucket: string) => set(() => ({
bucket, bucket,
})), })),
startAfter: '',
setStartAfter: (startAfter: string) => set(() => ({
startAfter,
nextPageParameters: {},
currentNextPageParametersRef: { current: {} },
setNextPageParameters: (nextPageParameters: Record<string, any>) => set(() => ({
nextPageParameters,
})), })),
isTruncated: { current: false }, isTruncated: { current: false },
previewOnlineDriveFileRef: { current: undefined }, previewOnlineDriveFileRef: { current: undefined },

+ 7
- 7
web/app/components/datasets/documents/create-from-pipeline/hooks.ts 查看文件

export const useOnlineDrive = () => { export const useOnlineDrive = () => {
const { const {
fileList, fileList,
selectedFileKeys,
selectedFileIds,
} = useDataSourceStoreWithSelector(useShallow(state => ({ } = useDataSourceStoreWithSelector(useShallow(state => ({
fileList: state.fileList, fileList: state.fileList,
selectedFileKeys: state.selectedFileKeys,
selectedFileIds: state.selectedFileIds,
}))) })))
const dataSourceStore = useDataSourceStore() const dataSourceStore = useDataSourceStore()


const selectedOnlineDriveFileList = useMemo(() => { const selectedOnlineDriveFileList = useMemo(() => {
return selectedFileKeys.map(key => fileList.find(item => item.key === key)!)
}, [fileList, selectedFileKeys])
return selectedFileIds.map(key => fileList.find(item => item.key === key)!)
}, [fileList, selectedFileIds])


const clearOnlineDriveData = useCallback(() => { const clearOnlineDriveData = useCallback(() => {
const { const {
setBucket, setBucket,
setPrefix, setPrefix,
setKeywords, setKeywords,
setSelectedFileKeys,
setSelectedFileIds,
} = dataSourceStore.getState() } = dataSourceStore.getState()
setFileList([]) setFileList([])
setBucket('') setBucket('')
setPrefix([]) setPrefix([])
setKeywords('') setKeywords('')
setSelectedFileKeys([])
setSelectedFileIds([])
}, [dataSourceStore]) }, [dataSourceStore])


return { return {
fileList, fileList,
selectedFileKeys,
selectedFileIds,
selectedOnlineDriveFileList, selectedOnlineDriveFileList,
clearOnlineDriveData, clearOnlineDriveData,
} }

+ 15
- 15
web/app/components/datasets/documents/create-from-pipeline/index.tsx 查看文件

} = useWebsiteCrawl() } = useWebsiteCrawl()
const { const {
fileList: onlineDriveFileList, fileList: onlineDriveFileList,
selectedFileKeys,
selectedFileIds,
selectedOnlineDriveFileList, selectedOnlineDriveFileList,
clearOnlineDriveData, clearOnlineDriveData,
} = useOnlineDrive() } = useOnlineDrive()
if (datasourceType === DatasourceType.websiteCrawl) if (datasourceType === DatasourceType.websiteCrawl)
return isShowVectorSpaceFull || !websitePages.length return isShowVectorSpaceFull || !websitePages.length
if (datasourceType === DatasourceType.onlineDrive) if (datasourceType === DatasourceType.onlineDrive)
return isShowVectorSpaceFull || !selectedFileKeys.length
return isShowVectorSpaceFull || !selectedFileIds.length
return false return false
}, [datasource, datasourceType, isShowVectorSpaceFull, fileList.length, allFileLoaded, onlineDocuments.length, websitePages.length, selectedFileKeys.length])
}, [datasource, datasourceType, isShowVectorSpaceFull, fileList.length, allFileLoaded, onlineDocuments.length, websitePages.length, selectedFileIds.length])


const fileUploadConfig = useMemo(() => fileUploadConfigResponse ?? { const fileUploadConfig = useMemo(() => fileUploadConfigResponse ?? {
file_size_limit: 15, file_size_limit: 15,
if (datasourceType === DatasourceType.onlineDocument) if (datasourceType === DatasourceType.onlineDocument)
return onlineDocuments.length return onlineDocuments.length
if (datasourceType === DatasourceType.onlineDrive) if (datasourceType === DatasourceType.onlineDrive)
return selectedFileKeys.length
}, [datasourceType, onlineDocuments.length, selectedFileKeys.length])
return selectedFileIds.length
}, [datasourceType, onlineDocuments.length, selectedFileIds.length])


const tip = useMemo(() => { const tip = useMemo(() => {
if (datasourceType === DatasourceType.onlineDocument) if (datasourceType === DatasourceType.onlineDocument)
} }
if (datasourceType === DatasourceType.onlineDrive) { if (datasourceType === DatasourceType.onlineDrive) {
const { bucket } = dataSourceStore.getState() const { bucket } = dataSourceStore.getState()
const { key } = previewOnlineDriveFileRef.current!
const { id } = previewOnlineDriveFileRef.current!
datasourceInfoList.push({ datasourceInfoList.push({
bucket, bucket,
key,
id,
credential_id: currentCredentialId, credential_id: currentCredentialId,
}) })
} }
} }
if (datasourceType === DatasourceType.onlineDrive) { if (datasourceType === DatasourceType.onlineDrive) {
if (datasourceType === DatasourceType.onlineDrive) { if (datasourceType === DatasourceType.onlineDrive) {
selectedFileKeys.forEach((key) => {
selectedFileIds.forEach((key) => {
datasourceInfoList.push({ datasourceInfoList.push({
bucket, bucket,
key, key,
handleNextStep() handleNextStep()
}, },
}) })
}, [dataSourceStore, datasource, datasourceType, fileList, handleNextStep, onlineDocuments, pipelineId, runPublishedPipeline, selectedFileKeys, websitePages])
}, [dataSourceStore, datasource, datasourceType, fileList, handleNextStep, onlineDocuments, pipelineId, runPublishedPipeline, selectedFileIds, websitePages])


const onClickProcess = useCallback(() => { const onClickProcess = useCallback(() => {
isPreview.current = false isPreview.current = false
const { const {
onlineDocuments, onlineDocuments,
fileList: onlineDriveFileList, fileList: onlineDriveFileList,
selectedFileKeys,
selectedFileIds,
setOnlineDocuments, setOnlineDocuments,
setSelectedFileKeys,
setSelectedFileIds,
setSelectedPagesId, setSelectedPagesId,
} = dataSourceStore.getState() } = dataSourceStore.getState()
if (datasourceType === DatasourceType.onlineDocument) { if (datasourceType === DatasourceType.onlineDocument) {
if (datasourceType === DatasourceType.onlineDrive) { if (datasourceType === DatasourceType.onlineDrive) {
const allKeys = onlineDriveFileList.filter((item) => { const allKeys = onlineDriveFileList.filter((item) => {
return item.type !== 'bucket' return item.type !== 'bucket'
}).map(file => file.key)
if (selectedFileKeys.length < allKeys.length)
setSelectedFileKeys(allKeys)
}).map(file => file.id)
if (selectedFileIds.length < allKeys.length)
setSelectedFileIds(allKeys)
else else
setSelectedFileKeys([])
setSelectedFileIds([])
} }
}, [PagesMapAndSelectedPagesId, currentWorkspace?.pages, dataSourceStore, datasourceType]) }, [PagesMapAndSelectedPagesId, currentWorkspace?.pages, dataSourceStore, datasourceType])



+ 3
- 3
web/app/components/header/account-setting/data-source-page-new/configure.tsx 查看文件

<PortalToFollowElemContent className='z-[61]'> <PortalToFollowElemContent className='z-[61]'>
<div className='w-[240px] space-y-1.5 rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-2 shadow-lg'> <div className='w-[240px] space-y-1.5 rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-2 shadow-lg'>
{ {
canOAuth && (
!!canOAuth && (
<AddOAuthButton <AddOAuthButton
{...oAuthButtonProps} {...oAuthButtonProps}
onUpdate={onUpdate} onUpdate={onUpdate}
) )
} }
{ {
canApiKey && canOAuth && (
!!canApiKey && !!canOAuth && (
<div className='system-2xs-medium-uppercase flex h-4 items-center p-2 text-text-quaternary'> <div className='system-2xs-medium-uppercase flex h-4 items-center p-2 text-text-quaternary'>
<div className='mr-2 h-[1px] grow bg-gradient-to-l from-[rgba(16,24,40,0.08)]' /> <div className='mr-2 h-[1px] grow bg-gradient-to-l from-[rgba(16,24,40,0.08)]' />
OR OR
) )
} }
{ {
canApiKey && (
!!canApiKey && (
<AddApiKeyButton <AddApiKeyButton
{...apiKeyButtonProps} {...apiKeyButtonProps}
formSchemas={item.credential_schema} formSchemas={item.credential_schema}

+ 2
- 2
web/app/components/rag-pipeline/components/panel/test-run/hooks.ts 查看文件

setBucket, setBucket,
setPrefix, setPrefix,
setKeywords, setKeywords,
setSelectedFileKeys,
setSelectedFileIds,
} = dataSourceStore.getState() } = dataSourceStore.getState()
setFileList([]) setFileList([])
setBucket('') setBucket('')
setPrefix([]) setPrefix([])
setKeywords('') setKeywords('')
setSelectedFileKeys([])
setSelectedFileIds([])
}, [dataSourceStore]) }, [dataSourceStore])


return { return {

+ 6
- 6
web/app/components/rag-pipeline/components/panel/test-run/index.tsx 查看文件

localFileList: fileList, localFileList: fileList,
onlineDocuments, onlineDocuments,
websitePages, websitePages,
selectedFileKeys,
selectedFileIds,
} = useDataSourceStoreWithSelector(useShallow(state => ({ } = useDataSourceStoreWithSelector(useShallow(state => ({
localFileList: state.localFileList, localFileList: state.localFileList,
onlineDocuments: state.onlineDocuments, onlineDocuments: state.onlineDocuments,
websitePages: state.websitePages, websitePages: state.websitePages,
selectedFileKeys: state.selectedFileKeys,
selectedFileIds: state.selectedFileIds,
}))) })))
const dataSourceStore = useDataSourceStore() const dataSourceStore = useDataSourceStore()
const [datasource, setDatasource] = useState<Datasource>() const [datasource, setDatasource] = useState<Datasource>()
if (datasourceType === DatasourceType.websiteCrawl) if (datasourceType === DatasourceType.websiteCrawl)
return !websitePages.length return !websitePages.length
if (datasourceType === DatasourceType.onlineDrive) if (datasourceType === DatasourceType.onlineDrive)
return !selectedFileKeys.length
return !selectedFileIds.length
return false return false
}, [datasource, datasourceType, fileList, onlineDocuments.length, selectedFileKeys.length, websitePages.length])
}, [datasource, datasourceType, fileList, onlineDocuments.length, selectedFileIds.length, websitePages.length])


const handleClose = useCallback(() => { const handleClose = useCallback(() => {
setShowDebugAndPreviewPanel(false) setShowDebugAndPreviewPanel(false)
const { bucket } = dataSourceStore.getState() const { bucket } = dataSourceStore.getState()
datasourceInfoList.push({ datasourceInfoList.push({
bucket, bucket,
key: selectedFileKeys[0],
id: selectedFileIds[0],
credential_id: credentialId, credential_id: credentialId,
}) })
} }
datasource_type: datasourceType, datasource_type: datasourceType,
datasource_info_list: datasourceInfoList, datasource_info_list: datasourceInfoList,
}) })
}, [dataSourceStore, datasource, datasourceType, fileList, handleRun, onlineDocuments, selectedFileKeys, websitePages])
}, [dataSourceStore, datasource, datasourceType, fileList, handleRun, onlineDocuments, selectedFileIds, websitePages])


const clearDataSourceData = useCallback((dataSource: Datasource) => { const clearDataSourceData = useCallback((dataSource: Datasource) => {
if (dataSource.nodeData.provider_type === DatasourceType.onlineDocument) if (dataSource.nodeData.provider_type === DatasourceType.onlineDocument)

+ 2
- 2
web/models/pipeline.ts 查看文件

} }


export type OnlineDriveFile = { export type OnlineDriveFile = {
key: string
displayName: string
id: string
name: string
size?: number size?: number
type: OnlineDriveFileType type: OnlineDriveFileType
} }

+ 4
- 1
web/types/pipeline.tsx 查看文件

} }


export type OnlineDriveFile = { export type OnlineDriveFile = {
key: string
id: string
name: string
size: number size: number
type: 'file' | 'folder'
} }


export type OnlineDriveData = { export type OnlineDriveData = {
bucket: string bucket: string
files: OnlineDriveFile[] files: OnlineDriveFile[]
is_truncated: boolean is_truncated: boolean
next_page_parameters: Record<string, any>
} }


export type DataSourceNodeCompletedResponse = { export type DataSourceNodeCompletedResponse = {

Loading…
取消
儲存