mirror of https://github.com/langgenius/dify.git
feat: Refactor NotionConnector integration and add Header component for improved UI in NotionPageSelector
This commit is contained in:
parent
de30e9278c
commit
f317ef2fe2
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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} />
|
||||
)
|
||||
}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
},
|
||||
})
|
||||
}
|
||||
Loading…
Reference in New Issue