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
82b727cf
Commit
82b727cf
authored
Jul 26, 2023
by
StyleZhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add new segment
parent
49c2309b
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
223 additions
and
2 deletions
+223
-2
hash-02.svg
...ponents/base/icons/assets/vender/line/general/hash-02.svg
+5
-0
Hash02.json
...components/base/icons/src/vender/line/general/Hash02.json
+38
-0
Hash02.tsx
.../components/base/icons/src/vender/line/general/Hash02.tsx
+14
-0
index.ts
...pp/components/base/icons/src/vender/line/general/index.ts
+1
-0
index.tsx
web/app/components/datasets/documents/detail/index.tsx
+1
-0
new-segment-modal.tsx
...omponents/datasets/documents/detail/new-segment-modal.tsx
+134
-0
list.tsx
web/app/components/datasets/documents/list.tsx
+20
-2
dataset-documents.en.ts
web/i18n/lang/dataset-documents.en.ts
+3
-0
dataset-documents.zh.ts
web/i18n/lang/dataset-documents.zh.ts
+3
-0
datasets.ts
web/service/datasets.ts
+4
-0
No files found.
web/app/components/base/icons/assets/vender/line/general/hash-02.svg
0 → 100644
View file @
82b727cf
<svg
width=
"12"
height=
"12"
viewBox=
"0 0 12 12"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
>
<g
id=
"hash-02"
>
<path
id=
"Icon"
d=
"M4.74999 1.5L3.24999 10.5M8.74998 1.5L7.24998 10.5M10.25 4H1.75M9.75 8H1.25"
stroke=
"#98A2B3"
stroke-linecap=
"round"
stroke-linejoin=
"round"
/>
</g>
</svg>
web/app/components/base/icons/src/vender/line/general/Hash02.json
0 → 100644
View file @
82b727cf
{
"icon"
:
{
"type"
:
"element"
,
"isRootNode"
:
true
,
"name"
:
"svg"
,
"attributes"
:
{
"width"
:
"12"
,
"height"
:
"12"
,
"viewBox"
:
"0 0 12 12"
,
"fill"
:
"none"
,
"xmlns"
:
"http://www.w3.org/2000/svg"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"g"
,
"attributes"
:
{
"id"
:
"hash-02"
},
"children"
:
[
{
"type"
:
"element"
,
"name"
:
"path"
,
"attributes"
:
{
"id"
:
"Icon"
,
"d"
:
"M4.74999 1.5L3.24999 10.5M8.74998 1.5L7.24998 10.5M10.25 4H1.75M9.75 8H1.25"
,
"stroke"
:
"currentColor"
,
"stroke-linecap"
:
"round"
,
"stroke-linejoin"
:
"round"
},
"children"
:
[]
}
]
}
]
},
"name"
:
"Hash02"
}
\ No newline at end of file
web/app/components/base/icons/src/vender/line/general/Hash02.tsx
0 → 100644
View file @
82b727cf
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import
*
as
React
from
'react'
import
data
from
'./Hash02.json'
import
IconBase
from
'@/app/components/base/icons/IconBase'
import
type
{
IconBaseProps
,
IconData
}
from
'@/app/components/base/icons/IconBase'
const
Icon
=
React
.
forwardRef
<
React
.
MutableRefObject
<
SVGElement
>
,
Omit
<
IconBaseProps
,
'data'
>>
((
props
,
ref
,
)
=>
<
IconBase
{
...
props
}
ref=
{
ref
}
data=
{
data
as
IconData
}
/>)
export
default
Icon
web/app/components/base/icons/src/vender/line/general/index.ts
View file @
82b727cf
export
{
default
as
Check
}
from
'./Check'
export
{
default
as
Edit03
}
from
'./Edit03'
export
{
default
as
Hash02
}
from
'./Hash02'
export
{
default
as
Loading02
}
from
'./Loading02'
export
{
default
as
LogOut01
}
from
'./LogOut01'
export
{
default
as
Trash03
}
from
'./Trash03'
...
...
web/app/components/datasets/documents/detail/index.tsx
View file @
82b727cf
...
...
@@ -100,6 +100,7 @@ const DocumentDetail: FC<Props> = ({ datasetId, documentId }) => {
enabled
:
documentDetail
?.
enabled
||
false
,
archived
:
documentDetail
?.
archived
||
false
,
id
:
documentId
,
doc_form
:
documentDetail
?.
doc_form
||
''
,
}
}
datasetId=
{
datasetId
}
onUpdate=
{
handleOperate
}
...
...
web/app/components/datasets/documents/detail/new-segment-modal.tsx
0 → 100644
View file @
82b727cf
import
{
memo
,
useState
}
from
'react'
import
type
{
FC
}
from
'react'
import
{
useTranslation
}
from
'react-i18next'
import
{
useContext
}
from
'use-context-selector'
import
{
useParams
}
from
'next/navigation'
import
Modal
from
'@/app/components/base/modal'
import
Button
from
'@/app/components/base/button'
import
AutoHeightTextarea
from
'@/app/components/base/auto-height-textarea/common'
import
{
Hash02
,
XClose
}
from
'@/app/components/base/icons/src/vender/line/general'
import
{
ToastContext
}
from
'@/app/components/base/toast'
import
type
{
SegmentUpdator
}
from
'@/models/datasets'
import
{
addSegment
}
from
'@/service/datasets'
type
NewSegmentModalProps
=
{
isShow
:
boolean
onCancel
:
()
=>
void
docForm
:
string
onSave
:
()
=>
void
}
const
NewSegmentModal
:
FC
<
NewSegmentModalProps
>
=
memo
(({
isShow
,
onCancel
,
docForm
,
onSave
,
})
=>
{
const
{
t
}
=
useTranslation
()
const
{
notify
}
=
useContext
(
ToastContext
)
const
[
question
,
setQuestion
]
=
useState
(
''
)
const
[
answer
,
setAnswer
]
=
useState
(
''
)
const
{
datasetId
,
documentId
}
=
useParams
()
const
handleSave
=
async
()
=>
{
const
params
:
SegmentUpdator
=
{
content
:
''
}
if
(
docForm
===
'qa_model'
)
{
if
(
!
question
.
trim
())
return
notify
({
type
:
'error'
,
message
:
t
(
'datasetDocuments.segment.questionEmpty'
)
})
if
(
!
answer
.
trim
())
return
notify
({
type
:
'error'
,
message
:
t
(
'datasetDocuments.segment.answerEmpty'
)
})
params
.
content
=
question
params
.
answer
=
answer
}
else
{
if
(
!
question
.
trim
())
return
notify
({
type
:
'error'
,
message
:
t
(
'datasetDocuments.segment.contentEmpty'
)
})
params
.
content
=
question
}
await
addSegment
({
datasetId
,
documentId
,
body
:
params
})
notify
({
type
:
'success'
,
message
:
t
(
'common.actionMsg.modifiedSuccessfully'
)
})
onCancel
()
onSave
()
}
const
renderContent
=
()
=>
{
if
(
docForm
===
'qa_model'
)
{
return
(
<>
<
div
className=
'mb-1 text-xs font-medium text-gray-500'
>
QUESTION
</
div
>
<
AutoHeightTextarea
outerClassName=
'mb-4'
className=
'leading-6 text-md text-gray-800'
value=
{
question
}
placeholder=
{
t
(
'datasetDocuments.segment.questionPlaceholder'
)
||
''
}
onChange=
{
e
=>
setQuestion
(
e
.
target
.
value
)
}
autoFocus
/>
<
div
className=
'mb-1 text-xs font-medium text-gray-500'
>
ANSWER
</
div
>
<
AutoHeightTextarea
outerClassName=
'mb-4'
className=
'leading-6 text-md text-gray-800'
value=
{
answer
}
placeholder=
{
t
(
'datasetDocuments.segment.answerPlaceholder'
)
||
''
}
onChange=
{
e
=>
setAnswer
(
e
.
target
.
value
)
}
/>
</>
)
}
return
(
<
AutoHeightTextarea
className=
'leading-6 text-md text-gray-800'
value=
{
question
}
placeholder=
{
t
(
'datasetDocuments.segment.contentPlaceholder'
)
||
''
}
onChange=
{
e
=>
setQuestion
(
e
.
target
.
value
)
}
autoFocus
/>
)
}
return
(
<
Modal
isShow=
{
isShow
}
onClose=
{
()
=>
{}
}
className=
'pt-8 px-8 pb-6 !max-w-[640px] !rounded-xl'
>
<
div
className=
{
'flex flex-col relative'
}
>
<
div
className=
'absolute right-0 -top-0.5 flex items-center h-6'
>
<
div
className=
'flex justify-center items-center w-6 h-6 cursor-pointer'
onClick=
{
onCancel
}
>
<
XClose
className=
'w-4 h-4 text-gray-500'
/>
</
div
>
</
div
>
<
div
className=
'mb-[14px]'
>
<
span
className=
'inline-flex items-center px-1.5 h-5 border border-gray-200 rounded-md'
>
<
Hash02
className=
'mr-0.5 w-3 h-3 text-gray-400'
/>
<
span
className=
'text-[11px] font-medium text-gray-500 italic'
>
{
docForm
===
'qa_model'
?
t
(
'datasetDocuments.segment.newQaSegment'
)
:
t
(
'datasetDocuments.segment.newTextSegment'
)
}
</
span
>
</
span
>
</
div
>
<
div
className=
'mb-4 py-1.5 h-[420px] overflow-auto'
>
{
renderContent
()
}
</
div
>
<
div
className=
'mb-2 text-xs font-medium text-gray-500'
>
{
t
(
'datasetDocuments.segment.keywords'
)
}
</
div
>
<
div
className=
'mb-8'
></
div
>
<
div
className=
'flex justify-end'
>
<
Button
className=
'mr-2 !h-9 !px-4 !py-2 text-sm font-medium text-gray-700 !rounded-lg'
onClick=
{
onCancel
}
>
{
t
(
'common.operation.cancel'
)
}
</
Button
>
<
Button
type=
'primary'
className=
'!h-9 !px-4 !py-2 text-sm font-medium !rounded-lg'
onClick=
{
handleSave
}
>
{
t
(
'common.operation.save'
)
}
</
Button
>
</
div
>
</
div
>
</
Modal
>
)
})
export
default
NewSegmentModal
web/app/components/datasets/documents/list.tsx
View file @
82b727cf
...
...
@@ -27,6 +27,8 @@ import NotionIcon from '@/app/components/base/notion-icon'
import
ProgressBar
from
'@/app/components/base/progress-bar'
import
{
DataSourceType
,
type
DocumentDisplayStatus
,
type
SimpleDocumentDetail
}
from
'@/models/datasets'
import
type
{
CommonResponse
}
from
'@/models/common'
import
{
FilePlus02
}
from
'@/app/components/base/icons/src/vender/line/files'
import
NewSegmentModal
from
'@/app/components/datasets/documents/detail/new-segment-modal'
export
const
SettingsIcon
:
FC
<
{
className
?:
string
}
>
=
({
className
})
=>
{
return
<
svg
width=
"16"
height=
"16"
viewBox=
"0 0 16 16"
fill=
"none"
xmlns=
"http://www.w3.org/2000/svg"
className=
{
className
??
''
}
>
...
...
@@ -94,14 +96,16 @@ export const OperationAction: FC<{
archived
:
boolean
id
:
string
data_source_type
:
string
doc_form
:
string
}
datasetId
:
string
onUpdate
:
(
operationName
?:
string
)
=>
void
scene
?:
'list'
|
'detail'
className
?:
string
}
>
=
({
datasetId
,
detail
,
onUpdate
,
scene
=
'list'
,
className
=
''
})
=>
{
const
{
id
,
enabled
=
false
,
archived
=
false
,
data_source_type
}
=
detail
||
{}
const
{
id
,
enabled
=
false
,
archived
=
false
,
data_source_type
,
doc_form
}
=
detail
||
{}
const
[
showModal
,
setShowModal
]
=
useState
(
false
)
const
[
showNewSegmentModal
,
setShowNewSegmentModal
]
=
useState
(
false
)
const
{
notify
}
=
useContext
(
ToastContext
)
const
{
t
}
=
useTranslation
()
const
router
=
useRouter
()
...
...
@@ -185,6 +189,14 @@ export const OperationAction: FC<{
<
SettingsIcon
/>
<
span
className=
{
s
.
actionName
}
>
{
t
(
'datasetDocuments.list.action.settings'
)
}
</
span
>
</
div
>
{
!
isListScene
&&
(
<
div
className=
{
s
.
actionItem
}
onClick=
{
()
=>
setShowNewSegmentModal
(
true
)
}
>
<
FilePlus02
className=
'w-4 h-4 text-gray-500'
/>
<
span
className=
{
s
.
actionName
}
>
{
t
(
'datasetDocuments.list.action.add'
)
}
</
span
>
</
div
>
)
}
{
data_source_type
===
'notion_import'
&&
(
<
div
className=
{
s
.
actionItem
}
onClick=
{
()
=>
onOperate
(
'sync'
)
}
>
...
...
@@ -231,6 +243,12 @@ export const OperationAction: FC<{
</
div
>
</
div
>
</
Modal
>
}
<
NewSegmentModal
isShow=
{
showNewSegmentModal
}
onCancel=
{
()
=>
setShowNewSegmentModal
(
false
)
}
docForm=
{
doc_form
}
onSave=
{
()
=>
{}
}
/>
</
div
>
}
...
...
@@ -339,7 +357,7 @@ const DocumentList: FC<IDocumentListProps> = ({ documents = [], datasetId, onUpd
<
td
>
<
OperationAction
datasetId=
{
datasetId
}
detail=
{
pick
(
doc
,
[
'enabled'
,
'archived'
,
'id'
,
'data_source_type'
])
}
detail=
{
pick
(
doc
,
[
'enabled'
,
'archived'
,
'id'
,
'data_source_type'
,
'doc_form'
])
}
onUpdate=
{
onUpdate
}
/>
</
td
>
...
...
web/i18n/lang/dataset-documents.en.ts
View file @
82b727cf
...
...
@@ -17,6 +17,7 @@ const translation = {
action
:
{
uploadFile
:
'Upload new file'
,
settings
:
'Segment settings'
,
add
:
'Add new segment'
,
archive
:
'Archive'
,
delete
:
'Delete'
,
enableWarning
:
'Archived file cannot be enabled'
,
...
...
@@ -316,6 +317,8 @@ const translation = {
answerEmpty
:
'Answer can not be empty'
,
contentPlaceholder
:
'add content here'
,
contentEmpty
:
'Content can not be empty'
,
newTextSegment
:
'New Text Segment'
,
newQaSegment
:
'New Q&A Segment'
,
},
}
...
...
web/i18n/lang/dataset-documents.zh.ts
View file @
82b727cf
...
...
@@ -17,6 +17,7 @@ const translation = {
action
:
{
uploadFile
:
'上传新文件'
,
settings
:
'分段设置'
,
add
:
'添加新分段'
,
archive
:
'归档'
,
delete
:
'删除'
,
enableWarning
:
'归档的文件无法启用'
,
...
...
@@ -315,6 +316,8 @@ const translation = {
answerEmpty
:
'答案不能为空'
,
contentPlaceholder
:
'在这里添加内容'
,
contentEmpty
:
'内容不能为空'
,
newTextSegment
:
'新文本分段'
,
newQaSegment
:
'新问答分段'
,
},
}
...
...
web/service/datasets.ts
View file @
82b727cf
...
...
@@ -160,6 +160,10 @@ export const updateSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string
return
patch
(
`/datasets/
${
datasetId
}
/documents/
${
documentId
}
/segments/
${
segmentId
}
`
,
{
body
})
as
Promise
<
{
data
:
SegmentDetailModel
;
doc_form
:
string
}
>
}
export
const
addSegment
:
Fetcher
<
{
data
:
SegmentDetailModel
;
doc_form
:
string
},
{
datasetId
:
string
;
documentId
:
string
;
body
:
SegmentUpdator
}
>
=
({
datasetId
,
documentId
,
body
})
=>
{
return
post
(
`/datasets/
${
datasetId
}
/documents/
${
documentId
}
/segment`
,
{
body
})
as
Promise
<
{
data
:
SegmentDetailModel
;
doc_form
:
string
}
>
}
// hit testing
export
const
hitTesting
:
Fetcher
<
HitTestingResponse
,
{
datasetId
:
string
;
queryText
:
string
}
>
=
({
datasetId
,
queryText
})
=>
{
return
post
(
`/datasets/
${
datasetId
}
/hit-testing`
,
{
body
:
{
query
:
queryText
}
})
as
Promise
<
HitTestingResponse
>
...
...
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