diff --git a/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/index.tsx b/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/index.tsx
index 6b843b499e..bbc87cc650 100644
--- a/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/index.tsx
+++ b/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/index.tsx
@@ -1,43 +1,25 @@
-import { useDataSources } from '@/service/use-common'
-import { useCallback, useMemo } from 'react'
-import { NotionPageSelector } from '@/app/components/base/notion-page-selector'
import type { NotionPage } from '@/models/common'
-import NotionConnector from '@/app/components/base/notion-connector'
-import { useModalContextSelector } from '@/context/modal-context'
+import NotionPageSelector from './notion-page-selector'
type NotionProps = {
+ nodeId: string
notionPages: NotionPage[]
updateNotionPages: (value: NotionPage[]) => void
}
const Notion = ({
+ nodeId,
notionPages,
updateNotionPages,
}: NotionProps) => {
- const { data: dataSources } = useDataSources()
- const setShowAccountSettingModal = useModalContextSelector(state => state.setShowAccountSettingModal)
-
- const hasConnection = useMemo(() => {
- const notionDataSources = dataSources?.data.filter(item => item.provider === 'notion') || []
- return notionDataSources.length > 0
- }, [dataSources])
-
- const handleConnect = useCallback(() => {
- setShowAccountSettingModal({ payload: 'data-source' })
- }, [setShowAccountSettingModal])
-
return (
- <>
- {!hasConnection && }
- {hasConnection && (
- page.page_id)}
- onSelect={updateNotionPages}
- canPreview={false}
- isInPipeline
- />
- )}
- >
+ page.page_id)}
+ onSelect={updateNotionPages}
+ canPreview={false}
+ isInPipeline
+ />
)
}
diff --git a/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/notion-page-selector.tsx b/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/notion-page-selector.tsx
new file mode 100644
index 0000000000..8d759def6b
--- /dev/null
+++ b/web/app/components/rag-pipeline/components/panel/test-run/data-source/notion/notion-page-selector.tsx
@@ -0,0 +1,146 @@
+import { useCallback, useEffect, useMemo, useState } from 'react'
+import WorkspaceSelector from '@/app/components/base/notion-page-selector/workspace-selector'
+import SearchInput from '@/app/education-apply/search-input'
+import PageSelector from '@/app/components/base/notion-page-selector/page-selector'
+import type { DataSourceNotionPageMap, DataSourceNotionWorkspace, NotionPage } from '@/models/common'
+import Header from '@/app/components/datasets/create/website/base/header'
+import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
+import { useDatasourceNodeRun } from '@/service/use-pipeline'
+import { useTranslation } from 'react-i18next'
+
+type NotionPageSelectorProps = {
+ value?: string[]
+ onSelect: (selectedPages: NotionPage[]) => void
+ canPreview?: boolean
+ previewPageId?: string
+ onPreview?: (selectedPage: NotionPage) => void
+ isInPipeline?: boolean
+ nodeId: string
+}
+
+const NotionPageSelector = ({
+ value,
+ onSelect,
+ canPreview,
+ previewPageId,
+ onPreview,
+ isInPipeline = false,
+ nodeId,
+}: NotionPageSelectorProps) => {
+ const { t } = useTranslation()
+ const pipeline_id = useDatasetDetailContextWithSelector(s => s.dataset?.pipeline_id)
+ const { mutateAsync: getNotionPages } = useDatasourceNodeRun()
+ const [notionData, setNotionData] = useState()
+ const [searchValue, setSearchValue] = useState('')
+ const [currentWorkspaceId, setCurrentWorkspaceId] = useState('')
+
+ const getNotionData = useCallback(async () => {
+ if (pipeline_id) {
+ const notionData = await getNotionPages({
+ pipeline_id,
+ node_id: nodeId,
+ inputs: {},
+ }) as DataSourceNotionWorkspace[]
+ setNotionData(notionData)
+ }
+ }, [getNotionPages, nodeId, pipeline_id])
+
+ useEffect(() => {
+ getNotionData()
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
+
+ const notionWorkspaces = useMemo(() => {
+ return notionData || []
+ }, [notionData])
+
+ const firstWorkspaceId = notionWorkspaces[0]?.workspace_id
+ const currentWorkspace = notionWorkspaces.find(workspace => workspace.workspace_id === currentWorkspaceId)
+
+ const PagesMapAndSelectedPagesId: [DataSourceNotionPageMap, Set, Set] = useMemo(() => {
+ const selectedPagesId = new Set()
+ const boundPagesId = new Set()
+ const pagesMap = notionWorkspaces.reduce((prev: DataSourceNotionPageMap, next: DataSourceNotionWorkspace) => {
+ next.pages.forEach((page) => {
+ if (page.is_bound) {
+ selectedPagesId.add(page.page_id)
+ boundPagesId.add(page.page_id)
+ }
+ prev[page.page_id] = {
+ ...page,
+ workspace_id: next.workspace_id,
+ }
+ })
+
+ return prev
+ }, {})
+ return [pagesMap, selectedPagesId, boundPagesId]
+ }, [notionWorkspaces])
+ const defaultSelectedPagesId = [...Array.from(PagesMapAndSelectedPagesId[1]), ...(value || [])]
+ const [selectedPagesId, setSelectedPagesId] = useState>(new Set(defaultSelectedPagesId))
+
+ const handleSearchValueChange = useCallback((value: string) => {
+ setSearchValue(value)
+ }, [])
+ const handleSelectWorkspace = useCallback((workspaceId: string) => {
+ setCurrentWorkspaceId(workspaceId)
+ }, [])
+ const handleSelectPages = (newSelectedPagesId: Set) => {
+ const selectedPages = Array.from(newSelectedPagesId).map(pageId => PagesMapAndSelectedPagesId[0][pageId])
+
+ setSelectedPagesId(new Set(Array.from(newSelectedPagesId)))
+ onSelect(selectedPages)
+ }
+ const handlePreviewPage = (previewPageId: string) => {
+ if (onPreview)
+ onPreview(PagesMapAndSelectedPagesId[0][previewPageId])
+ }
+
+ useEffect(() => {
+ setCurrentWorkspaceId(firstWorkspaceId)
+ }, [firstWorkspaceId])
+
+ if (!notionData?.length)
+ return null
+
+ return (
+
+ )
+}
+
+export default NotionPageSelector
diff --git a/web/app/components/rag-pipeline/components/panel/test-run/index.tsx b/web/app/components/rag-pipeline/components/panel/test-run/index.tsx
index fac5005b94..ac053853a4 100644
--- a/web/app/components/rag-pipeline/components/panel/test-run/index.tsx
+++ b/web/app/components/rag-pipeline/components/panel/test-run/index.tsx
@@ -49,7 +49,7 @@ const TestRunPanel = () => {
}, [fileList, isShowVectorSpaceFull])
const nextBtnDisabled = useMemo(() => {
- if (!datasource) return false
+ if (!datasource) return true
if (datasource.type === DataSourceType.FILE)
return nextDisabled
if (datasource.type === DataSourceType.NOTION)
@@ -98,9 +98,13 @@ const TestRunPanel = () => {
if (!datasource)
return
const datasourceInfo: Record = {}
- if (datasource.type === DataSourceType.FILE)
+ let datasource_type = ''
+ if (datasource.type === DataSourceType.FILE) {
+ datasource_type = 'local_file'
datasourceInfo.fileId = fileList.map(file => file.fileID)
+ }
if (datasource.type === DataSourceType.NOTION) {
+ datasource_type = 'online_document'
datasourceInfo.workspaceId = notionPages[0].workspace_id
datasourceInfo.page = notionPages.map((page) => {
const { workspace_id, ...rest } = page
@@ -110,13 +114,13 @@ const TestRunPanel = () => {
if (datasource.type === DataSourceProvider.fireCrawl
|| datasource.type === DataSourceProvider.jinaReader
|| datasource.type === DataSourceProvider.waterCrawl) {
+ datasource_type = 'website_crawl'
datasourceInfo.jobId = websiteCrawlJobId
datasourceInfo.result = websitePages
}
- // todo: TBD
handleRun({
inputs: data,
- datasource_type: datasource,
+ datasource_type,
datasource_info: datasourceInfo,
})
}, [datasource, fileList, handleRun, notionPages, websiteCrawlJobId, websitePages])
diff --git a/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts b/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
index 7a70d28e97..056dcbe909 100644
--- a/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
+++ b/web/app/components/rag-pipeline/hooks/use-pipeline-run.ts
@@ -128,7 +128,7 @@ export const usePipelineRun = () => {
clientHeight,
} = workflowContainer!
- const url = `/rag/pipeline/${pipelineId}/workflows/draft/run`
+ const url = `/rag/pipelines/${pipelineId}/workflows/draft/run`
const {
setWorkflowRunningData,
@@ -253,25 +253,25 @@ export const usePipelineRun = () => {
},
)
}, [
- store,
- workflowStore,
- doSyncWorkflowDraft,
- handleWorkflowStarted,
- handleWorkflowFinished,
- handleWorkflowFailed,
- handleWorkflowNodeStarted,
- handleWorkflowNodeFinished,
- handleWorkflowNodeIterationStarted,
- handleWorkflowNodeIterationNext,
- handleWorkflowNodeIterationFinished,
- handleWorkflowNodeLoopStarted,
- handleWorkflowNodeLoopNext,
- handleWorkflowNodeLoopFinished,
- handleWorkflowNodeRetry,
- handleWorkflowTextChunk,
- handleWorkflowTextReplace,
- handleWorkflowAgentLog,
- ],
+ store,
+ workflowStore,
+ doSyncWorkflowDraft,
+ handleWorkflowStarted,
+ handleWorkflowFinished,
+ handleWorkflowFailed,
+ handleWorkflowNodeStarted,
+ handleWorkflowNodeFinished,
+ handleWorkflowNodeIterationStarted,
+ handleWorkflowNodeIterationNext,
+ handleWorkflowNodeIterationFinished,
+ handleWorkflowNodeLoopStarted,
+ handleWorkflowNodeLoopNext,
+ handleWorkflowNodeLoopFinished,
+ handleWorkflowNodeRetry,
+ handleWorkflowTextChunk,
+ handleWorkflowTextReplace,
+ handleWorkflowAgentLog,
+ ],
)
const handleStopRun = useCallback((taskId: string) => {
diff --git a/web/i18n/en-US/dataset-pipeline.ts b/web/i18n/en-US/dataset-pipeline.ts
index 7a7dd8fb25..5665d42d0b 100644
--- a/web/i18n/en-US/dataset-pipeline.ts
+++ b/web/i18n/en-US/dataset-pipeline.ts
@@ -54,6 +54,10 @@ const translation = {
dataSource: {
localFiles: 'Local Files',
},
+ notion: {
+ title: 'Choose Notion Pages',
+ docTitle: 'Notion docs',
+ },
},
inputField: 'Input Field',
inputFieldPanel: {
diff --git a/web/i18n/zh-Hans/dataset-pipeline.ts b/web/i18n/zh-Hans/dataset-pipeline.ts
index cedd736124..aae121bcaf 100644
--- a/web/i18n/zh-Hans/dataset-pipeline.ts
+++ b/web/i18n/zh-Hans/dataset-pipeline.ts
@@ -54,18 +54,22 @@ const translation = {
dataSource: {
localFiles: '本地文件',
},
- inputField: '输入字段',
- inputFieldPanel: {
- title: '用户输入字段',
- description: '用户输入字段用于定义和收集流水线执行过程中所需的变量,用户可以自定义字段类型,并灵活配置输入,以满足不同数据源或文档处理的需求。',
- sharedInputs: {
- title: '共享输入',
- tooltip: '共享输入可被数据源中的所有下游节点使用。例如,在处理来自多个来源的文档时,delimiter(分隔符)和 maximum chunk length(最大分块长度)等变量可以统一应用。',
- },
- addInputField: '添加输入字段',
- editInputField: '编辑输入字段',
+ notion: {
+ title: '选择 Notion 页面',
+ docTitle: 'Notion 文档',
},
},
+ inputField: '输入字段',
+ inputFieldPanel: {
+ title: '用户输入字段',
+ description: '用户输入字段用于定义和收集流水线执行过程中所需的变量,用户可以自定义字段类型,并灵活配置输入,以满足不同数据源或文档处理的需求。',
+ sharedInputs: {
+ title: '共享输入',
+ tooltip: '共享输入可被数据源中的所有下游节点使用。例如,在处理来自多个来源的文档时,delimiter(分隔符)和 maximum chunk length(最大分块长度)等变量可以统一应用。',
+ },
+ addInputField: '添加输入字段',
+ editInputField: '编辑输入字段',
+ },
}
export default translation