Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
cd042254
Commit
cd042254
authored
Jun 09, 2023
by
JzoNg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: support notion page preview
parent
1ee00cba
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
185 additions
and
10 deletions
+185
-10
index.module.css
.../components/datasets/create/file-preview/index.module.css
+3
-0
index.tsx
web/app/components/datasets/create/file-preview/index.tsx
+5
-3
index.module.css
...ents/datasets/create/notion-page-preview/index.module.css
+54
-0
index.tsx
.../components/datasets/create/notion-page-preview/index.tsx
+84
-0
index.tsx
web/app/components/datasets/create/step-one/index.tsx
+27
-7
dataset-creation.en.ts
web/i18n/lang/dataset-creation.en.ts
+4
-0
dataset-creation.zh.ts
web/i18n/lang/dataset-creation.zh.ts
+4
-0
datasets.ts
web/service/datasets.ts
+4
-0
No files found.
web/app/components/datasets/create/file-preview/index.module.css
View file @
cd042254
...
...
@@ -11,6 +11,9 @@
}
.previewHeader
.title
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
color
:
#101828
;
font-weight
:
600
;
font-size
:
18px
;
...
...
web/app/components/datasets/create/file-preview/index.tsx
View file @
cd042254
...
...
@@ -2,12 +2,14 @@
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
cn
from
'classnames'
import
{
XMarkIcon
}
from
'@heroicons/react/20/solid'
import
s
from
'./index.module.css'
import
type
{
File
}
from
'@/models/datasets'
import
{
fetchFilePreview
}
from
'@/service/common'
type
IProps
=
{
file
?:
File
notionPage
?:
any
hidePreview
:
()
=>
void
}
...
...
@@ -46,9 +48,9 @@ const FilePreview = ({
<
div
className=
{
cn
(
s
.
previewHeader
)
}
>
<
div
className=
{
cn
(
s
.
title
)
}
>
<
span
>
{
t
(
'datasetCreation.stepOne.filePreview'
)
}
</
span
>
{
false
&&
(
<
div
className=
'flex items-center justify-center w-6 h-6 cursor-pointer'
onClick=
{
hidePreview
}
></
div
>
)
}
<
div
className=
'flex items-center justify-center w-6 h-6 cursor-pointer'
onClick=
{
hidePreview
}
>
<
XMarkIcon
className=
'h-4 w-4'
></
XMarkIcon
>
</
div
>
</
div
>
<
div
className=
{
cn
(
s
.
fileName
)
}
>
<
span
>
{
getFileName
(
file
)
}
</
span
><
span
className=
{
cn
(
s
.
filetype
)
}
>
.
{
file
?.
extension
}
</
span
>
...
...
web/app/components/datasets/create/notion-page-preview/index.module.css
0 → 100644
View file @
cd042254
.filePreview
{
@apply
flex
flex-col
border-l
border-gray-200
shrink-0;
width
:
528px
;
background-color
:
#fcfcfd
;
}
.previewHeader
{
@apply
border-b
border-gray-200
shrink-0;
margin
:
42px
32px
0
;
padding-bottom
:
16px
;
}
.previewHeader
.title
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
color
:
#101828
;
font-weight
:
600
;
font-size
:
18px
;
line-height
:
28px
;
}
.previewHeader
.fileName
{
display
:
flex
;
align-items
:
center
;
font-weight
:
400
;
font-size
:
12px
;
line-height
:
18px
;
color
:
#1D2939
;
}
.previewHeader
.filetype
{
color
:
#667085
;
}
.previewContent
{
@apply
overflow-y-auto
grow;
padding
:
20px
32px
;
font-weight
:
400
;
font-size
:
16px
;
line-height
:
24px
;
color
:
#344054
;
}
.previewContent
.loading
{
width
:
100%
;
height
:
180px
;
background
:
#f9fafb
center
no-repeat
url(../assets/Loading.svg)
;
background-size
:
contain
;
}
.fileContent
{
white-space
:
pre-line
;
}
\ No newline at end of file
web/app/components/datasets/create/notion-page-preview/index.tsx
0 → 100644
View file @
cd042254
'use client'
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
cn
from
'classnames'
import
{
XMarkIcon
}
from
'@heroicons/react/20/solid'
import
s
from
'./index.module.css'
import
type
{
DataSourceNotionPage
}
from
'@/models/common'
import
NotionIcon
from
'@/app/components/base/notion-icon'
import
{
fetchNotionPagePreview
}
from
'@/service/datasets'
type
Page
=
DataSourceNotionPage
&
{
workspace_id
:
string
}
type
IProps
=
{
currentPage
?:
Page
hidePreview
:
()
=>
void
}
const
NotionPagePreview
=
({
currentPage
,
hidePreview
,
}:
IProps
)
=>
{
const
{
t
}
=
useTranslation
()
const
[
previewContent
,
setPreviewContent
]
=
useState
(
''
)
const
[
loading
,
setLoading
]
=
useState
(
true
)
const
getPreviewContent
=
async
()
=>
{
if
(
!
currentPage
)
return
try
{
const
res
=
await
fetchNotionPagePreview
({
workspaceID
:
currentPage
.
workspace_id
,
pageID
:
currentPage
.
page_id
,
})
setPreviewContent
(
res
.
content
)
setLoading
(
false
)
}
catch
{}
}
const
getIcon
=
()
=>
{
let
iconSrc
if
(
currentPage
)
{
if
(
currentPage
.
page_icon
&&
currentPage
.
page_icon
.
type
===
'url'
)
iconSrc
=
currentPage
.
page_icon
.
url
if
(
currentPage
.
page_icon
&&
currentPage
.
page_icon
.
type
===
'emoji'
)
iconSrc
=
currentPage
.
page_icon
.
emoji
}
return
iconSrc
}
useEffect
(()
=>
{
if
(
currentPage
)
{
setLoading
(
true
)
getPreviewContent
()
}
},
[
currentPage
])
return
(
<
div
className=
{
cn
(
s
.
filePreview
)
}
>
<
div
className=
{
cn
(
s
.
previewHeader
)
}
>
<
div
className=
{
cn
(
s
.
title
)
}
>
<
span
>
{
t
(
'datasetCreation.stepOne.pagePreview'
)
}
</
span
>
<
div
className=
'flex items-center justify-center w-6 h-6 cursor-pointer'
onClick=
{
hidePreview
}
>
<
XMarkIcon
className=
'h-4 w-4'
></
XMarkIcon
>
</
div
>
</
div
>
<
div
className=
{
cn
(
s
.
fileName
)
}
>
<
NotionIcon
className=
'shrink-0 mr-1'
type=
'page'
src=
{
getIcon
()
}
/>
{
currentPage
?.
page_name
}
</
div
>
</
div
>
<
div
className=
{
cn
(
s
.
previewContent
)
}
>
{
loading
&&
<
div
className=
{
cn
(
s
.
loading
)
}
/>
}
{
!
loading
&&
(
<
div
className=
{
cn
(
s
.
fileContent
)
}
>
{
previewContent
}
</
div
>
)
}
</
div
>
</
div
>
)
}
export
default
NotionPagePreview
web/app/components/datasets/create/step-one/index.tsx
View file @
cd042254
...
...
@@ -4,9 +4,11 @@ import { useTranslation } from 'react-i18next'
import
cn
from
'classnames'
import
FilePreview
from
'../file-preview'
import
FileUploader
from
'../file-uploader'
import
NotionPagePreview
from
'../notion-page-preview'
import
EmptyDatasetCreationModal
from
'../empty-dataset-creation-modal'
import
s
from
'./index.module.css'
import
type
{
File
}
from
'@/models/datasets'
import
type
{
DataSourceNotionPage
}
from
'@/models/common'
import
{
DataSourceType
}
from
'@/models/datasets'
import
Button
from
'@/app/components/base/button'
import
{
NotionPageSelector
}
from
'@/app/components/base/notion-page-selector'
...
...
@@ -24,6 +26,8 @@ type IStepOneProps = {
changeType
:
(
type
:
DataSourceType
)
=>
void
}
type
Page
=
DataSourceNotionPage
&
{
workspace_id
:
string
}
const
StepOne
=
({
datasetId
,
dataSourceType
,
...
...
@@ -34,9 +38,11 @@ const StepOne = ({
file
,
updateFile
,
notionPages
=
[],
updateNotionPages
,
}:
IStepOneProps
)
=>
{
const
[
showModal
,
setShowModal
]
=
useState
(
false
)
const
[
showFilePreview
,
setShowFilePreview
]
=
useState
(
true
)
const
[
currentNotionPage
,
setCurrentNotionPage
]
=
useState
<
Page
|
undefined
>
()
const
{
t
}
=
useTranslation
()
const
hidePreview
=
()
=>
setShowFilePreview
(
false
)
...
...
@@ -45,6 +51,14 @@ const StepOne = ({
const
modalCloseHandle
=
()
=>
setShowModal
(
false
)
const
updateCurrentPage
=
(
page
:
Page
)
=>
{
setCurrentNotionPage
(
page
)
}
const
hideNotionPagePreview
=
()
=>
{
setCurrentNotionPage
(
undefined
)
}
return
(
<
div
className=
'flex w-full h-full'
>
<
div
className=
'grow overflow-y-auto relative'
>
...
...
@@ -53,14 +67,20 @@ const StepOne = ({
<
div
className=
{
s
.
dataSourceTypeList
}
>
<
div
className=
{
cn
(
s
.
dataSourceItem
,
dataSourceType
===
DataSourceType
.
FILE
&&
s
.
active
)
}
onClick=
{
()
=>
changeType
(
DataSourceType
.
FILE
)
}
onClick=
{
()
=>
{
changeType
(
DataSourceType
.
FILE
)
hidePreview
()
}
}
>
<
span
className=
{
cn
(
s
.
datasetIcon
)
}
/>
{
t
(
'datasetCreation.stepOne.dataSourceType.file'
)
}
</
div
>
<
div
className=
{
cn
(
s
.
dataSourceItem
,
dataSourceType
===
DataSourceType
.
NOTION
&&
s
.
active
)
}
onClick=
{
()
=>
changeType
(
DataSourceType
.
NOTION
)
}
onClick=
{
()
=>
{
changeType
(
DataSourceType
.
NOTION
)
hidePreview
()
}
}
>
<
span
className=
{
cn
(
s
.
datasetIcon
,
s
.
notion
)
}
/>
{
t
(
'datasetCreation.stepOne.dataSourceType.notion'
)
}
...
...
@@ -85,16 +105,16 @@ const StepOne = ({
{
!
hasConnection
&&
(
<
div
className=
{
s
.
notionConnectionTip
}
>
<
span
className=
{
s
.
notionIcon
}
/>
<
div
className=
{
s
.
title
}
>
Notion is not connected
</
div
>
<
div
className=
{
s
.
tip
}
>
To sync with Notion, connection to Notion must be established first.
</
div
>
<
Button
className=
'h-8'
type=
'primary'
onClick=
{
onSetting
}
>
Go to connect
</
Button
>
<
div
className=
{
s
.
title
}
>
{
t
(
'datasetCreation.stepOne.notionSyncTitle'
)
}
</
div
>
<
div
className=
{
s
.
tip
}
>
{
t
(
'datasetCreation.stepOne.notionSyncTip'
)
}
</
div
>
<
Button
className=
'h-8'
type=
'primary'
onClick=
{
onSetting
}
>
{
t
(
'datasetCreation.stepOne.connect'
)
}
</
Button
>
</
div
>
)
}
{
hasConnection
&&
(
<>
{
/* TODO */
}
<
div
className=
'mb-8 w-[640px]'
>
<
NotionPageSelector
/>
<
NotionPageSelector
onSelect=
{
updateNotionPages
}
onPreview=
{
updateCurrentPage
}
/>
</
div
>
<
Button
disabled=
{
!
notionPages
.
length
}
className=
{
s
.
submitButton
}
type=
'primary'
onClick=
{
onStepChange
}
>
{
t
(
'datasetCreation.stepOne.button'
)
}
</
Button
>
</>
...
...
@@ -111,7 +131,7 @@ const StepOne = ({
<
EmptyDatasetCreationModal
show=
{
showModal
}
onHide=
{
modalCloseHandle
}
/>
</
div
>
{
file
&&
showFilePreview
&&
<
FilePreview
file=
{
file
}
hidePreview=
{
hidePreview
}
/>
}
{
/* TODO notion page preview */
}
{
currentNotionPage
&&
<
NotionPagePreview
currentPage=
{
currentNotionPage
}
hidePreview=
{
hideNotionPagePreview
}
/>
}
</
div
>
)
}
...
...
web/i18n/lang/dataset-creation.en.ts
View file @
cd042254
...
...
@@ -13,6 +13,7 @@ const translation = {
},
stepOne
:
{
filePreview
:
'File Preview'
,
pagePreview
:
'Page Preview'
,
dataSourceType
:
{
file
:
'Import from text file'
,
notion
:
'Sync from Notion'
,
...
...
@@ -32,6 +33,9 @@ const translation = {
change
:
'Change'
,
failed
:
'Upload failed'
,
},
notionSyncTitle
:
'Notion is not connected'
,
notionSyncTip
:
'To sync with Notion, connection to Notion must be established first.'
,
connect
:
'Go to connect'
,
button
:
'next'
,
emptyDatasetCreation
:
'I want to create an empty dataset'
,
modal
:
{
...
...
web/i18n/lang/dataset-creation.zh.ts
View file @
cd042254
...
...
@@ -13,6 +13,7 @@ const translation = {
},
stepOne
:
{
filePreview
:
'文件预览'
,
pagePreview
:
'页面预览'
,
dataSourceType
:
{
file
:
'导入已有文本'
,
notion
:
'同步自 Notion 内容'
,
...
...
@@ -32,6 +33,9 @@ const translation = {
change
:
'更改文件'
,
failed
:
'上传失败'
,
},
notionSyncTitle
:
'Notion 未绑定'
,
notionSyncTip
:
'同步 Notion 内容前,须先绑定 Notion 空间'
,
connect
:
'去绑定'
,
button
:
'下一步'
,
emptyDatasetCreation
:
'创建一个空数据集'
,
modal
:
{
...
...
web/service/datasets.ts
View file @
cd042254
...
...
@@ -125,3 +125,7 @@ export const fetchTestingRecords: Fetcher<HitTestingRecordsResponse, { datasetId
export
const
fetchFileIndexingEstimate
:
Fetcher
<
FileIndexingEstimateResponse
,
any
>
=
(
body
:
any
)
=>
{
return
post
(
'/datasets/indexing-estimate'
,
{
body
})
as
Promise
<
FileIndexingEstimateResponse
>
}
export
const
fetchNotionPagePreview
:
Fetcher
<
{
content
:
string
},
{
workspaceID
:
string
;
pageID
:
string
}
>
=
({
workspaceID
,
pageID
})
=>
{
return
get
(
`notion/workspaces/
${
workspaceID
}
/pages/
${
pageID
}
/preview`
)
as
Promise
<
{
content
:
string
}
>
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment