| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 | import { useCallback, useEffect, useMemo, useState } from 'react'import useSWR from 'swr'import cn from 'classnames'import s from './base.module.css'import WorkspaceSelector from './workspace-selector'import SearchInput from './search-input'import PageSelector from './page-selector'import { preImportNotionPages } from '@/service/datasets'import { NotionConnector } from '@/app/components/datasets/create/step-one'import type { DataSourceNotionPageMap, DataSourceNotionWorkspace, NotionPage } from '@/models/common'import { useModalContext } from '@/context/modal-context'type NotionPageSelectorProps = {  value?: string[]  onSelect: (selectedPages: NotionPage[]) => void  canPreview?: boolean  previewPageId?: string  onPreview?: (selectedPage: NotionPage) => void  datasetId?: string}const NotionPageSelector = ({  value,  onSelect,  canPreview,  previewPageId,  onPreview,  datasetId = '',}: NotionPageSelectorProps) => {  const { data, mutate } = useSWR({ url: '/notion/pre-import/pages', datasetId }, preImportNotionPages)  const [prevData, setPrevData] = useState(data)  const [searchValue, setSearchValue] = useState('')  const [currentWorkspaceId, setCurrentWorkspaceId] = useState('')  const { setShowAccountSettingModal } = useModalContext()  const notionWorkspaces = useMemo(() => {    return data?.notion_info || []  }, [data?.notion_info])  const firstWorkspaceId = notionWorkspaces[0]?.workspace_id  const currentWorkspace = notionWorkspaces.find(workspace => workspace.workspace_id === currentWorkspaceId)  const getPagesMapAndSelectedPagesId: [DataSourceNotionPageMap, Set<string>] = useMemo(() => {    const selectedPagesId = new Set<string>()    const pagesMap = notionWorkspaces.reduce((prev: DataSourceNotionPageMap, next: DataSourceNotionWorkspace) => {      next.pages.forEach((page) => {        if (page.is_bound)          selectedPagesId.add(page.page_id)        prev[page.page_id] = {          ...page,          workspace_id: next.workspace_id,        }      })      return prev    }, {})    return [pagesMap, selectedPagesId]  }, [notionWorkspaces])  const defaultSelectedPagesId = [...Array.from(getPagesMapAndSelectedPagesId[1]), ...(value || [])]  const [selectedPagesId, setSelectedPagesId] = useState<Set<string>>(new Set(defaultSelectedPagesId))  if (prevData !== data) {    setPrevData(data)    setSelectedPagesId(new Set(defaultSelectedPagesId))  }  const handleSearchValueChange = useCallback((value: string) => {    setSearchValue(value)  }, [])  const handleSelectWorkspace = useCallback((workspaceId: string) => {    setCurrentWorkspaceId(workspaceId)  }, [])  const handleSelecPages = (newSelectedPagesId: Set<string>) => {    const selectedPages = Array.from(newSelectedPagesId).map(pageId => getPagesMapAndSelectedPagesId[0][pageId])    setSelectedPagesId(new Set(Array.from(newSelectedPagesId)))    onSelect(selectedPages)  }  const handlePreviewPage = (previewPageId: string) => {    if (onPreview)      onPreview(getPagesMapAndSelectedPagesId[0][previewPageId])  }  useEffect(() => {    setCurrentWorkspaceId(firstWorkspaceId)  }, [firstWorkspaceId])  return (    <div className='bg-gray-25 border border-gray-200 rounded-xl'>      {        data?.notion_info?.length          ? (            <>              <div className='flex items-center pl-[10px] pr-2 h-11 bg-white border-b border-b-gray-200 rounded-t-xl'>                <WorkspaceSelector                  value={currentWorkspaceId || firstWorkspaceId}                  items={notionWorkspaces}                  onSelect={handleSelectWorkspace}                />                <div className='mx-1 w-[1px] h-3 bg-gray-200' />                <div                  className={cn(s['setting-icon'], 'w-6 h-6 cursor-pointer')}                  onClick={() => setShowAccountSettingModal({ payload: 'data-source', onCancelCallback: mutate })}                />                <div className='grow' />                <SearchInput                  value={searchValue}                  onChange={handleSearchValueChange}                />              </div>              <div className='rounded-b-xl overflow-hidden'>                <PageSelector                  value={selectedPagesId}                  searchValue={searchValue}                  list={currentWorkspace?.pages || []}                  pagesMap={getPagesMapAndSelectedPagesId[0]}                  onSelect={handleSelecPages}                  canPreview={canPreview}                  previewPageId={previewPageId}                  onPreview={handlePreviewPage}                />              </div>            </>          )          : (            <NotionConnector onSetting={() => setShowAccountSettingModal({ payload: 'data-source', onCancelCallback: mutate })} />          )      }    </div>  )}export default NotionPageSelector
 |