diff --git a/web/app/components/base/notion-page-selector/base.tsx b/web/app/components/base/notion-page-selector/base.tsx index 4dd56d142e..88ce343c47 100644 --- a/web/app/components/base/notion-page-selector/base.tsx +++ b/web/app/components/base/notion-page-selector/base.tsx @@ -19,6 +19,7 @@ type NotionPageSelectorProps = { onPreview?: (selectedPage: NotionPage) => void datasetId?: string credentialList: DataSourceCredential[] + onSelectCredential?: (credentialId: string) => void } const NotionPageSelector = ({ @@ -29,10 +30,13 @@ const NotionPageSelector = ({ onPreview, datasetId = '', credentialList, + onSelectCredential, }: NotionPageSelectorProps) => { const [searchValue, setSearchValue] = useState('') const setShowAccountSettingModal = useModalContextSelector(s => s.setShowAccountSettingModal) + const invalidPreImportNotionPages = useInvalidPreImportNotionPages() + const notionCredentials = useMemo((): NotionCredential[] => { return credentialList.map((item) => { return { @@ -47,8 +51,16 @@ const NotionPageSelector = ({ useEffect(() => { const credential = notionCredentials.find(item => item.credentialId === currentCredential?.credentialId) - if (!credential) + if (!credential) { + const firstCredential = notionCredentials[0] + invalidPreImportNotionPages({ datasetId, credentialId: firstCredential.credentialId }) setCurrentCredential(notionCredentials[0]) + onSelect([]) // Clear selected pages when changing credential + onSelectCredential?.(firstCredential.credentialId) + } + else { + onSelectCredential?.(credential?.credentialId || '') + } }, [notionCredentials]) const { @@ -91,14 +103,13 @@ const NotionPageSelector = ({ setSearchValue(value) }, []) - const invalidPreImportNotionPages = useInvalidPreImportNotionPages() - const handleSelectCredential = useCallback((credentialId: string) => { const credential = notionCredentials.find(item => item.credentialId === credentialId)! invalidPreImportNotionPages({ datasetId, credentialId: credential.credentialId }) setCurrentCredential(credential) onSelect([]) // Clear selected pages when changing credential - }, [onSelect]) + onSelectCredential?.(credential.credentialId) + }, [invalidPreImportNotionPages, onSelect, onSelectCredential]) const handleSelectPages = useCallback((newSelectedPagesId: Set) => { const selectedPages = Array.from(newSelectedPagesId).map(pageId => pagesMapAndSelectedPagesId[0][pageId]) diff --git a/web/app/components/datasets/create/index.tsx b/web/app/components/datasets/create/index.tsx index 5e9d6ea522..0ee17b45bf 100644 --- a/web/app/components/datasets/create/index.tsx +++ b/web/app/components/datasets/create/index.tsx @@ -44,15 +44,26 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => { const [fileList, setFiles] = useState([]) const [result, setResult] = useState() const [notionPages, setNotionPages] = useState([]) + const [notionCredentialId, setNotionCredentialId] = useState('') const [websitePages, setWebsitePages] = useState([]) const [crawlOptions, setCrawlOptions] = useState(DEFAULT_CRAWL_OPTIONS) const [websiteCrawlProvider, setWebsiteCrawlProvider] = useState(DataSourceProvider.fireCrawl) const [websiteCrawlJobId, setWebsiteCrawlJobId] = useState('') + const { + data: dataSourceList, + isLoading: isLoadingAuthedDataSourceList, + isError: fetchingAuthedDataSourceListError, + } = useGetDefaultDataSourceListAuth() + const updateNotionPages = useCallback((value: NotionPage[]) => { setNotionPages(value) }, []) + const updateNotionCredentialId = useCallback((credentialId: string) => { + setNotionCredentialId(credentialId) + }, []) + const updateFileList = useCallback((preparedFiles: FileItem[]) => { setFiles(preparedFiles) }, []) @@ -88,12 +99,6 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => { setStep(step + delta) }, [step, setStep]) - const { - data: dataSourceList, - isLoading: isLoadingAuthedDataSourceList, - isError: fetchingAuthedDataSourceListError, - } = useGetDefaultDataSourceListAuth() - if (fetchingAuthedDataSourceListError) return @@ -121,7 +126,9 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => { updateFile={updateFile} updateFileList={updateFileList} notionPages={notionPages} + notionCredentialId={notionCredentialId} updateNotionPages={updateNotionPages} + updateNotionCredentialId={updateNotionCredentialId} onStepChange={nextStep} websitePages={websitePages} updateWebsitePages={setWebsitePages} @@ -140,6 +147,7 @@ const DatasetUpdateForm = ({ datasetId }: DatasetUpdateFormProps) => { dataSourceType={dataSourceType} files={fileList.map(file => file.file)} notionPages={notionPages} + notionCredentialId={notionCredentialId} websitePages={websitePages} websiteCrawlProvider={websiteCrawlProvider} websiteCrawlJobId={websiteCrawlJobId} diff --git a/web/app/components/datasets/create/notion-page-preview/index.tsx b/web/app/components/datasets/create/notion-page-preview/index.tsx index 5b56036327..cbfe366f0b 100644 --- a/web/app/components/datasets/create/notion-page-preview/index.tsx +++ b/web/app/components/datasets/create/notion-page-preview/index.tsx @@ -11,11 +11,13 @@ import { fetchNotionPagePreview } from '@/service/datasets' type IProps = { currentPage?: NotionPage + notionCredentialId: string hidePreview: () => void } const NotionPagePreview = ({ currentPage, + notionCredentialId, hidePreview, }: IProps) => { const { t } = useTranslation() @@ -29,7 +31,7 @@ const NotionPagePreview = ({ const res = await fetchNotionPagePreview({ workspaceID: currentPage.workspace_id, pageID: currentPage.page_id, - pageType: currentPage.type, + credentialID: notionCredentialId, }) setPreviewContent(res.content) setLoading(false) diff --git a/web/app/components/datasets/create/step-one/index.tsx b/web/app/components/datasets/create/step-one/index.tsx index a89322160a..cab1637661 100644 --- a/web/app/components/datasets/create/step-one/index.tsx +++ b/web/app/components/datasets/create/step-one/index.tsx @@ -32,7 +32,9 @@ type IStepOneProps = { updateFileList: (files: FileItem[]) => void updateFile: (fileItem: FileItem, progress: number, list: FileItem[]) => void notionPages?: NotionPage[] + notionCredentialId: string updateNotionPages: (value: NotionPage[]) => void + updateNotionCredentialId: (credentialId: string) => void onStepChange: () => void changeType: (type: DataSourceType) => void websitePages?: CrawlResultItem[] @@ -55,7 +57,9 @@ const StepOne = ({ updateFileList, updateFile, notionPages = [], + notionCredentialId, updateNotionPages, + updateNotionCredentialId, websitePages = [], updateWebsitePages, onWebsiteCrawlProviderChange, @@ -253,6 +257,7 @@ const StepOne = ({ onSelect={updateNotionPages} onPreview={updateCurrentPage} credentialList={notionCredentialList} + onSelectCredential={updateNotionCredentialId} datasetId={datasetId} /> @@ -317,7 +322,13 @@ const StepOne = ({
{currentFile && } - {currentNotionPage && } + {currentNotionPage && ( + + )} {currentWebsite && }
diff --git a/web/app/components/datasets/create/step-two/index.tsx b/web/app/components/datasets/create/step-two/index.tsx index 818da67b7e..ed63f26b1b 100644 --- a/web/app/components/datasets/create/step-two/index.tsx +++ b/web/app/components/datasets/create/step-two/index.tsx @@ -79,6 +79,7 @@ type StepTwoProps = { dataSourceType: DataSourceType files: CustomFile[] notionPages?: NotionPage[] + notionCredentialId: string websitePages?: CrawlResultItem[] crawlOptions?: CrawlOptions websiteCrawlProvider?: DataSourceProvider @@ -134,6 +135,7 @@ const StepTwo = ({ dataSourceType: inCreatePageDataSourceType, files, notionPages = [], + notionCredentialId, websitePages = [], crawlOptions, websiteCrawlProvider = DataSourceProvider.fireCrawl, @@ -282,6 +284,7 @@ const StepTwo = ({ indexingTechnique: getIndexing_technique() as any, processRule: getProcessRule(), dataset_id: datasetId || '', + credential_id: notionCredentialId, }) const websiteIndexingEstimateQuery = useFetchFileIndexingEstimateForWeb({ diff --git a/web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/index.tsx b/web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/index.tsx index 58da88af1e..99d26bf3e1 100644 --- a/web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/index.tsx +++ b/web/app/components/datasets/documents/create-from-pipeline/data-source/website-crawl/index.tsx @@ -1,9 +1,9 @@ 'use client' -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import React, { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import type { CrawlResultItem } from '@/models/datasets' import { CrawlStep } from '@/models/datasets' -import Header from '@/app/components/datasets/create/website/base/header' +import Header from '../base/header' import Options from './base/options' import Crawling from './base/crawling' import ErrorMessage from './base/error-message' @@ -24,6 +24,8 @@ import type { DataSourceNodeType } from '@/app/components/workflow/nodes/data-so import { useDataSourceStore, useDataSourceStoreWithSelector } from '../store' import { useShallow } from 'zustand/react/shallow' import { useModalContextSelector } from '@/context/modal-context' +import { CredentialTypeEnum } from '@/app/components/plugins/plugin-auth' +import { noop } from 'lodash-es' const I18N_PREFIX = 'datasetCreation.stepOne.website' @@ -157,14 +159,6 @@ const WebsiteCrawl = ({ handleRun(value) }, [handleRun]) - const headerInfo = useMemo(() => { - return { - title: nodeData.title, - docTitle: 'How to use?', - docLink: 'https://docs.dify.ai', - } - }, [nodeData]) - const handleSetting = useCallback(() => { setShowAccountSettingModal({ payload: 'data-source', @@ -174,9 +168,23 @@ const WebsiteCrawl = ({ return (
{ return ( -
+
Drag to adjust grouping
diff --git a/web/app/components/rag-pipeline/components/input-field/index.tsx b/web/app/components/rag-pipeline/components/input-field/index.tsx index ad4fef3639..811a72ff10 100644 --- a/web/app/components/rag-pipeline/components/input-field/index.tsx +++ b/web/app/components/rag-pipeline/components/input-field/index.tsx @@ -109,80 +109,80 @@ const InputFieldDialog = ({ -
-
-
- {t('datasetPipeline.inputFieldPanel.title')} -
- - - +
+
+ {t('datasetPipeline.inputFieldPanel.title')}
-
- {t('datasetPipeline.inputFieldPanel.description')} -
-
- {/* Unique Inputs for Each Entrance */} -
- - {t('datasetPipeline.inputFieldPanel.uniqueInputs.title')} - - -
-
- { - Object.keys(datasourceNodeDataMap).map((key) => { - const inputFields = inputFieldsMap.current[key] || [] - return ( - } - inputFields={inputFields} - readonly={readonly} - labelClassName='pt-1 pb-1' - handleInputFieldsChange={updateInputFields} - allVariableNames={allVariableNames} - /> - ) - }) - } -
- {/* Global Inputs */} - } - inputFields={inputFieldsMap.current.shared || []} - readonly={readonly} - labelClassName='pt-2 pb-1' - handleInputFieldsChange={updateInputFields} - allVariableNames={allVariableNames} + + + +
+
+ {t('datasetPipeline.inputFieldPanel.description')} +
+
+ {/* Unique Inputs for Each Entrance */} +
+ + {t('datasetPipeline.inputFieldPanel.uniqueInputs.title')} + +
- +
+ { + Object.keys(datasourceNodeDataMap).map((key) => { + const inputFields = inputFieldsMap.current[key] || [] + return ( + } + inputFields={inputFields} + readonly={readonly} + labelClassName='pt-1 pb-1' + handleInputFieldsChange={updateInputFields} + allVariableNames={allVariableNames} + /> + ) + }) + } +
+ {/* Global Inputs */} + } + inputFields={inputFieldsMap.current.shared || []} + readonly={readonly} + labelClassName='pt-2 pb-1' + handleInputFieldsChange={updateInputFields} + allVariableNames={allVariableNames} + />
+ {previewPanelOpen && ( diff --git a/web/app/components/workflow/nodes/_base/components/form-input-item.tsx b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx index 2b175d7765..b3fd6b4b84 100644 --- a/web/app/components/workflow/nodes/_base/components/form-input-item.tsx +++ b/web/app/components/workflow/nodes/_base/components/form-input-item.tsx @@ -31,6 +31,8 @@ type Props = { inPanel?: boolean currentTool?: Tool currentProvider?: ToolWithProvider + showManageInputField?: boolean + onManageInputField?: () => void } const FormInputItem: FC = ({ @@ -42,6 +44,8 @@ const FormInputItem: FC = ({ inPanel, currentTool, currentProvider, + showManageInputField, + onManageInputField, }) => { const language = useLanguage() @@ -192,6 +196,8 @@ const FormInputItem: FC = ({ onChange={handleValueChange} nodesOutputVars={availableVars} availableNodes={availableNodesWithParent} + showManageInputField={showManageInputField} + onManageInputField={onManageInputField} /> )} {isNumber && isConstant && ( diff --git a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx index 1961df3fa3..1af3b05b7a 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx @@ -146,6 +146,8 @@ const Editor: FC = ({ } const getVarType = useWorkflowVariableType() + const pipelineId = useStore(s => s.pipelineId) + const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog) return ( @@ -270,6 +272,8 @@ const Editor: FC = ({ } return acc }, {} as any), + showManageInputField: !!pipelineId, + onManageInputField: () => setShowInputFieldDialog?.(true), }} onChange={onChange} onBlur={setBlur} diff --git a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx index 6680c8ebb6..1e0d2b4724 100644 --- a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx +++ b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx @@ -17,6 +17,8 @@ type MixedVariableTextInputProps = { availableNodes?: Node[] value?: string onChange?: (text: string) => void + showManageInputField?: boolean + onManageInputField?: () => void } const MixedVariableTextInput = ({ readOnly = false, @@ -24,6 +26,8 @@ const MixedVariableTextInput = ({ availableNodes = [], value = '', onChange, + showManageInputField, + onManageInputField, }: MixedVariableTextInputProps) => { const { t } = useTranslation() return ( @@ -52,6 +56,8 @@ const MixedVariableTextInput = ({ } return acc }, {} as any), + showManageInputField, + onManageInputField, }} placeholder={} onChange={onChange} diff --git a/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx b/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx index a867797473..747790ac58 100644 --- a/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx +++ b/web/app/components/workflow/nodes/tool/components/tool-form/index.tsx @@ -16,6 +16,8 @@ type Props = { inPanel?: boolean currentTool?: Tool currentProvider?: ToolWithProvider + showManageInputField?: boolean + onManageInputField?: () => void } const ToolForm: FC = ({ @@ -27,6 +29,8 @@ const ToolForm: FC = ({ inPanel, currentTool, currentProvider, + showManageInputField, + onManageInputField, }) => { return (
@@ -42,6 +46,8 @@ const ToolForm: FC = ({ inPanel={inPanel} currentTool={currentTool} currentProvider={currentProvider} + showManageInputField={showManageInputField} + onManageInputField={onManageInputField} /> )) } diff --git a/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx b/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx index 11de42fe56..c70a039b5b 100644 --- a/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx +++ b/web/app/components/workflow/nodes/tool/components/tool-form/item.tsx @@ -24,6 +24,8 @@ type Props = { inPanel?: boolean currentTool?: Tool currentProvider?: ToolWithProvider + showManageInputField?: boolean + onManageInputField?: () => void } const ToolFormItem: FC = ({ @@ -35,6 +37,8 @@ const ToolFormItem: FC = ({ inPanel, currentTool, currentProvider, + showManageInputField, + onManageInputField, }) => { const language = useLanguage() const { name, label, type, required, tooltip, input_schema } = schema @@ -89,6 +93,8 @@ const ToolFormItem: FC = ({ inPanel={inPanel} currentTool={currentTool} currentProvider={currentProvider} + showManageInputField={showManageInputField} + onManageInputField={onManageInputField} /> {isShowSchema && ( diff --git a/web/app/components/workflow/nodes/tool/panel.tsx b/web/app/components/workflow/nodes/tool/panel.tsx index da8f708bb3..94db3d62b8 100644 --- a/web/app/components/workflow/nodes/tool/panel.tsx +++ b/web/app/components/workflow/nodes/tool/panel.tsx @@ -11,6 +11,7 @@ import Loading from '@/app/components/base/loading' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' import StructureOutputItem from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/show' import { Type } from '../llm/types' +import { useStore } from '@/app/components/workflow/store' const i18nPrefix = 'workflow.nodes.tool' @@ -37,6 +38,8 @@ const Panel: FC> = ({ } = useConfig(id, data) const [collapsed, setCollapsed] = React.useState(false) + const pipelineId = useStore(s => s.pipelineId) + const setShowInputFieldDialog = useStore(s => s.setShowInputFieldDialog) if (isLoading) { return
@@ -61,6 +64,8 @@ const Panel: FC> = ({ onChange={setInputVar} currentProvider={currCollection} currentTool={currTool} + showManageInputField={!!pipelineId} + onManageInputField={() => setShowInputFieldDialog?.(true)} /> )} diff --git a/web/service/datasets.ts b/web/service/datasets.ts index f145f2b421..acc1fe647e 100644 --- a/web/service/datasets.ts +++ b/web/service/datasets.ts @@ -183,8 +183,12 @@ export const fetchFileIndexingEstimate: Fetcher('/datasets/indexing-estimate', { body }) } -export const fetchNotionPagePreview: Fetcher<{ content: string }, { workspaceID: string; pageID: string; pageType: string }> = ({ workspaceID, pageID, pageType }) => { - return get<{ content: string }>(`notion/workspaces/${workspaceID}/pages/${pageID}/${pageType}/preview`) +export const fetchNotionPagePreview: Fetcher<{ content: string }, { workspaceID: string; pageID: string; credentialID: string; }> = ({ workspaceID, pageID, credentialID }) => { + return get<{ content: string }>(`notion/workspaces/${workspaceID}/pages/${pageID}/preview`, { + params: { + credential_id: credentialID, + }, + }) } export const fetchApiKeysList: Fetcher }> = ({ url, params }) => { diff --git a/web/service/knowledge/use-create-dataset.ts b/web/service/knowledge/use-create-dataset.ts index 987039a758..3f3451af2d 100644 --- a/web/service/knowledge/use-create-dataset.ts +++ b/web/service/knowledge/use-create-dataset.ts @@ -119,6 +119,7 @@ export const useFetchFileIndexingEstimateForFile = ( type GetFileIndexingEstimateParamsOptionNotion = GetFileIndexingEstimateParamsOptionBase & { dataSourceType: DataSourceType.NOTION notionPages: NotionPage[] + credential_id: string } const getFileIndexingEstimateParamsForNotion = ({