feat: Refactor NotionConnector integration and add Header component for improved UI in NotionPageSelector

This commit is contained in:
twwu 2025-04-24 21:26:54 +08:00
parent de30e9278c
commit f317ef2fe2
7 changed files with 120 additions and 39 deletions

View File

@ -2,11 +2,13 @@ import { useTranslation } from 'react-i18next'
import { Notion } from '../icons/src/public/common'
import { Icon3Dots } from '../icons/src/vender/line/others'
import Button from '../button'
import React from 'react'
type NotionConnectorProps = {
onSetting: () => void
}
export const NotionConnector = ({ onSetting }: NotionConnectorProps) => {
const NotionConnector = ({ onSetting }: NotionConnectorProps) => {
const { t } = useTranslation()
return (
@ -25,3 +27,5 @@ export const NotionConnector = ({ onSetting }: NotionConnectorProps) => {
</div>
)
}
export default React.memo(NotionConnector)

View File

@ -1,13 +1,12 @@
import { useCallback, useEffect, useMemo, useState } from 'react'
import useSWR from 'swr'
import { RiEqualizer2Line } from '@remixicon/react'
import WorkspaceSelector from './workspace-selector'
import SearchInput from './search-input'
import PageSelector from './page-selector'
import { preImportNotionPages } from '@/service/datasets'
import type { DataSourceNotionPageMap, DataSourceNotionWorkspace, NotionPage } from '@/models/common'
import { useModalContextSelector } from '@/context/modal-context'
import { NotionConnector } from '../notion-connector'
import NotionConnector from '../notion-connector'
import { usePreImportNotionPages } from '@/service/knowledge/use-import'
import Header from './header'
type NotionPageSelectorProps = {
value?: string[]
@ -16,6 +15,7 @@ type NotionPageSelectorProps = {
previewPageId?: string
onPreview?: (selectedPage: NotionPage) => void
datasetId?: string
isInPipeline?: boolean
}
const NotionPageSelector = ({
@ -25,8 +25,9 @@ const NotionPageSelector = ({
previewPageId,
onPreview,
datasetId = '',
isInPipeline = false,
}: NotionPageSelectorProps) => {
const { data, mutate } = useSWR({ url: '/notion/pre-import/pages', datasetId }, preImportNotionPages)
const { data, refetch } = usePreImportNotionPages({ url: '/notion/pre-import/pages', datasetId })
const [prevData, setPrevData] = useState(data)
const [searchValue, setSearchValue] = useState('')
const [currentWorkspaceId, setCurrentWorkspaceId] = useState('')
@ -86,47 +87,52 @@ const NotionPageSelector = ({
setCurrentWorkspaceId(firstWorkspaceId)
}, [firstWorkspaceId])
const handleConfigureNotion = useCallback(() => {
setShowAccountSettingModal({ payload: 'data-source', onCancelCallback: refetch })
}, [setShowAccountSettingModal, refetch])
return (
<>
{
data?.notion_info?.length
? (
<div className='rounded-xl border border-components-panel-border bg-background-default-subtle'>
<div className='flex h-12 items-center gap-x-2 rounded-t-xl border-b border-b-divider-regular bg-components-panel-bg p-2'>
<div className='flex grow items-center gap-x-1'>
<WorkspaceSelector
value={currentWorkspaceId || firstWorkspaceId}
items={notionWorkspaces}
onSelect={handleSelectWorkspace}
/>
<div className='mx-1 h-3 w-[1px] bg-divider-regular' />
<RiEqualizer2Line
className='h-4 w-4 cursor-pointer text-text-tertiary'
onClick={() => setShowAccountSettingModal({ payload: 'data-source', onCancelCallback: mutate })}
<div className='flex flex-col gap-y-2'>
<Header
isInPipeline={isInPipeline}
handleConfigureNotion={handleConfigureNotion}
/>
<div className='rounded-xl border border-components-panel-border bg-background-default-subtle'>
<div className='flex h-12 items-center gap-x-2 rounded-t-xl border-b border-b-divider-regular bg-components-panel-bg p-2'>
<div className='flex grow items-center gap-x-1'>
<WorkspaceSelector
value={currentWorkspaceId || firstWorkspaceId}
items={notionWorkspaces}
onSelect={handleSelectWorkspace}
/>
</div>
<SearchInput
value={searchValue}
onChange={handleSearchValueChange}
/>
</div>
<div className='overflow-hidden rounded-b-xl'>
<PageSelector
value={selectedPagesId}
disabledValue={getPagesMapAndSelectedPagesId[2]}
searchValue={searchValue}
list={currentWorkspace?.pages || []}
pagesMap={getPagesMapAndSelectedPagesId[0]}
onSelect={handleSelectPages}
canPreview={canPreview}
previewPageId={previewPageId}
onPreview={handlePreviewPage}
/>
</div>
<SearchInput
value={searchValue}
onChange={handleSearchValueChange}
/>
</div>
<div className='overflow-hidden rounded-b-xl'>
<PageSelector
value={selectedPagesId}
disabledValue={getPagesMapAndSelectedPagesId[2]}
searchValue={searchValue}
list={currentWorkspace?.pages || []}
pagesMap={getPagesMapAndSelectedPagesId[0]}
onSelect={handleSelectPages}
canPreview={canPreview}
previewPageId={previewPageId}
onPreview={handlePreviewPage}
/>
</div>
</div>
)
: (
<NotionConnector onSetting={() => setShowAccountSettingModal({ payload: 'data-source', onCancelCallback: mutate })} />
<NotionConnector onSetting={handleConfigureNotion} />
)
}
</>

View File

@ -0,0 +1,55 @@
import React from 'react'
import Divider from '../../divider'
import Button from '../../button'
import cn from '@/utils/classnames'
import { RiBookOpenLine, RiEqualizer2Line } from '@remixicon/react'
type HeaderProps = {
isInPipeline?: boolean
handleConfigureNotion: () => void
}
const Header = ({
isInPipeline = false,
handleConfigureNotion,
}: HeaderProps) => {
return (
<div className='flex items-center gap-x-2'>
<div className='flex grow items-center gap-x-1'>
<div className={cn(
'text-text-secondary',
isInPipeline ? 'system-sm-semibold' : 'system-md-semibold',
)}>
Choose notion pages
</div>
<Divider type='vertical' className='mx-1 h-3.5' />
<Button
variant='secondary'
size='small'
className={cn(isInPipeline ? 'px-1' : 'px-1.5')}
>
<RiEqualizer2Line
className='h-4 w-4'
onClick={handleConfigureNotion}
/>
{!isInPipeline && (
<span className='system-xs-medium'>
Configure Notion
</span>
)}
</Button>
</div>
<a
className='system-xs-medium flex items-center gap-x-1 text-text-accent'
href='https://www.notion.so/docs'
target='_blank'
rel='noopener noreferrer'
>
<RiBookOpenLine className='size-3.5' />
<span>Notion docs</span>
</a>
</div>
)
}
export default React.memo(Header)

View File

@ -31,7 +31,6 @@ export default function WorkspaceSelector({
name={currentWorkspace?.workspace_name}
/>
<div className='mr-1 w-[90px] truncate text-left text-sm font-medium text-text-secondary' title={currentWorkspace?.workspace_name}>{currentWorkspace?.workspace_name}</div>
{/* <div className='mr-1 px-1 h-[18px] bg-primary-50 rounded-lg text-xs font-medium text-text-accent'>{currentWorkspace?.pages.length}</div> */}
<RiArrowDownSLine className='h-4 w-4 text-text-secondary' />
</MenuButton>
<Transition

View File

@ -20,7 +20,7 @@ import { useProviderContext } from '@/context/provider-context'
import VectorSpaceFull from '@/app/components/billing/vector-space-full'
import classNames from '@/utils/classnames'
import { ENABLE_WEBSITE_FIRECRAWL, ENABLE_WEBSITE_JINAREADER, ENABLE_WEBSITE_WATERCRAWL } from '@/config'
import { NotionConnector } from '@/app/components/base/notion-connector'
import NotionConnector from '@/app/components/base/notion-connector'
type IStepOneProps = {
datasetId?: string

View File

@ -2,7 +2,7 @@ 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 NotionConnector from '@/app/components/base/notion-connector'
import { useModalContextSelector } from '@/context/modal-context'
type NotionProps = {
@ -34,6 +34,7 @@ const Notion = ({
value={notionPages.map(page => page.page_id)}
onSelect={updateNotionPages}
canPreview={false}
isInPipeline
/>
)}
</>

View File

@ -0,0 +1,16 @@
import { useQuery } from '@tanstack/react-query'
import { preImportNotionPages } from '../datasets'
type PreImportNotionPagesParams = {
url: string
datasetId?: string
}
export const usePreImportNotionPages = ({ datasetId }: PreImportNotionPagesParams) => {
return useQuery({
queryKey: ['notion-pre-import-pages'],
queryFn: async () => {
return preImportNotionPages({ url: '/notion/pre-import/pages', datasetId })
},
})
}