import type { DataSourceCredential } from '../../header/account-setting/data-source-page-new/types' import type { NotionCredential } from './credential-selector' import type { DataSourceNotionPageMap, DataSourceNotionWorkspace, NotionPage, } from '@/models/common' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { ACCOUNT_SETTING_TAB } from '@/app/components/header/account-setting/constants' import { useIntegrationsSetting } from '@/app/components/header/account-setting/use-integrations-setting' import { useInvalidPreImportNotionPages, usePreImportNotionPages, } from '@/service/knowledge/use-import' import Header from '../../datasets/create/website/base/header' import Loading from '../loading' import NotionConnector from '../notion-connector' import WorkspaceSelector from './credential-selector' import PageSelector from './page-selector' import SearchInput from './search-input' type NotionPageSelectorProps = { value?: string[] onSelect: (selectedPages: NotionPage[]) => void canPreview?: boolean previewPageId?: string onPreview?: (selectedPage: NotionPage) => void datasetId?: string credentialList: DataSourceCredential[] onSelectCredential?: (credentialId: string) => void } const NotionPageSelector = ({ value, onSelect, canPreview, previewPageId, onPreview, datasetId = '', credentialList, onSelectCredential, }: NotionPageSelectorProps) => { const { t } = useTranslation() const [searchValue, setSearchValue] = useState('') const openIntegrationsSetting = useIntegrationsSetting() const invalidPreImportNotionPages = useInvalidPreImportNotionPages() const notionCredentials = useMemo((): NotionCredential[] => { return credentialList.map((item) => { return { credentialId: item.id, credentialName: item.name, workspaceIcon: item.credential.workspace_icon, workspaceName: item.credential.workspace_name, } }) }, [credentialList]) const [selectedCredentialId, setSelectedCredentialId] = useState( () => notionCredentials[0]?.credentialId ?? '', ) const currentCredential = useMemo(() => { return ( notionCredentials.find((item) => item.credentialId === selectedCredentialId) ?? notionCredentials[0] ?? null ) }, [notionCredentials, selectedCredentialId]) const currentCredentialId = currentCredential?.credentialId ?? '' useEffect(() => { onSelectCredential?.(currentCredentialId) }, [currentCredentialId, onSelectCredential]) useEffect(() => { if (!notionCredentials.length) { onSelect([]) return } if (!selectedCredentialId || selectedCredentialId === currentCredentialId) return invalidPreImportNotionPages({ datasetId, credentialId: currentCredentialId }) onSelect([]) }, [ currentCredentialId, datasetId, invalidPreImportNotionPages, notionCredentials.length, onSelect, selectedCredentialId, ]) const { data: notionsPages, isFetching: isFetchingNotionPages, isError: isFetchingNotionPagesError, } = usePreImportNotionPages({ datasetId, credentialId: currentCredentialId }) const pagesMapAndSelectedPagesId: [DataSourceNotionPageMap, Set, Set] = useMemo(() => { const selectedPagesId = new Set() const boundPagesId = new Set() const notionWorkspaces = notionsPages?.notion_info || [] const pagesMap = notionWorkspaces.reduce( (prev: DataSourceNotionPageMap, cur: DataSourceNotionWorkspace) => { cur.pages.forEach((page) => { if (page.is_bound) { selectedPagesId.add(page.page_id) boundPagesId.add(page.page_id) } prev[page.page_id] = { ...page, workspace_id: cur.workspace_id, } }) return prev }, {}, ) return [pagesMap, selectedPagesId, boundPagesId] }, [notionsPages?.notion_info]) const defaultSelectedPagesId = useMemo(() => { return [...Array.from(pagesMapAndSelectedPagesId[1]), ...(value || [])] }, [pagesMapAndSelectedPagesId, value]) const selectedPagesId = useMemo(() => new Set(defaultSelectedPagesId), [defaultSelectedPagesId]) const handleSearchValueChange = useCallback((value: string) => { setSearchValue(value) }, []) const handleSelectCredential = useCallback( (credentialId: string) => { if (credentialId === currentCredentialId) return invalidPreImportNotionPages({ datasetId, credentialId }) setSelectedCredentialId(credentialId) onSelect([]) // Clear selected pages when changing credential }, [currentCredentialId, datasetId, invalidPreImportNotionPages, onSelect], ) const handleSelectPages = useCallback( (newSelectedPagesId: Set) => { const selectedPages = Array.from(newSelectedPagesId).map( (pageId) => pagesMapAndSelectedPagesId[0][pageId]!, ) onSelect(selectedPages) }, [pagesMapAndSelectedPagesId, onSelect], ) const handlePreviewPage = useCallback( (previewPageId: string) => { if (onPreview) onPreview(pagesMapAndSelectedPagesId[0][previewPageId]!) }, [pagesMapAndSelectedPagesId, onPreview], ) const handleConfigureNotion = useCallback(() => { openIntegrationsSetting({ payload: ACCOUNT_SETTING_TAB.DATA_SOURCE }) }, [openIntegrationsSetting]) if (isFetchingNotionPagesError) { return } return (
$['dataSource.notion.selector.headerTitle'], { ns: 'common' })} buttonText={t(($) => $['dataSource.notion.selector.configure'], { ns: 'common' })} docTitle={t(($) => $['dataSource.notion.selector.docs'], { ns: 'common' })} docLink="https://www.notion.so/docs" />
{isFetchingNotionPages ? (
) : ( )}
) } export default NotionPageSelector