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
2b5bc9e0
Commit
2b5bc9e0
authored
Aug 04, 2023
by
JzoNg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: delete segment supported
parent
340d7495
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
79 additions
and
4 deletions
+79
-4
InfiniteVirtualList.tsx
...tasets/documents/detail/completed/InfiniteVirtualList.tsx
+3
-0
SegmentCard.tsx
...nents/datasets/documents/detail/completed/SegmentCard.tsx
+36
-3
index.tsx
.../components/datasets/documents/detail/completed/index.tsx
+13
-1
style.module.css
...ents/datasets/documents/detail/completed/style.module.css
+21
-0
dataset-documents.en.ts
web/i18n/lang/dataset-documents.en.ts
+1
-0
dataset-documents.zh.ts
web/i18n/lang/dataset-documents.zh.ts
+1
-0
datasets.ts
web/service/datasets.ts
+4
-0
No files found.
web/app/components/datasets/documents/detail/completed/InfiniteVirtualList.tsx
View file @
2b5bc9e0
...
@@ -13,6 +13,7 @@ type IInfiniteVirtualListProps = {
...
@@ -13,6 +13,7 @@ type IInfiniteVirtualListProps = {
loadNextPage
:
()
=>
Promise
<
any
>
// Callback function responsible for loading the next page of items.
loadNextPage
:
()
=>
Promise
<
any
>
// Callback function responsible for loading the next page of items.
onClick
:
(
detail
:
SegmentDetailModel
)
=>
void
onClick
:
(
detail
:
SegmentDetailModel
)
=>
void
onChangeSwitch
:
(
segId
:
string
,
enabled
:
boolean
)
=>
Promise
<
void
>
onChangeSwitch
:
(
segId
:
string
,
enabled
:
boolean
)
=>
Promise
<
void
>
onDelete
:
(
segId
:
string
)
=>
Promise
<
void
>
}
}
const
InfiniteVirtualList
:
FC
<
IInfiniteVirtualListProps
>
=
({
const
InfiniteVirtualList
:
FC
<
IInfiniteVirtualListProps
>
=
({
...
@@ -22,6 +23,7 @@ const InfiniteVirtualList: FC<IInfiniteVirtualListProps> = ({
...
@@ -22,6 +23,7 @@ const InfiniteVirtualList: FC<IInfiniteVirtualListProps> = ({
loadNextPage
,
loadNextPage
,
onClick
:
onClickCard
,
onClick
:
onClickCard
,
onChangeSwitch
,
onChangeSwitch
,
onDelete
,
})
=>
{
})
=>
{
// If there are more items to be loaded then add an extra row to hold a loading indicator.
// If there are more items to be loaded then add an extra row to hold a loading indicator.
const
itemCount
=
hasNextPage
?
items
.
length
+
1
:
items
.
length
const
itemCount
=
hasNextPage
?
items
.
length
+
1
:
items
.
length
...
@@ -52,6 +54,7 @@ const InfiniteVirtualList: FC<IInfiniteVirtualListProps> = ({
...
@@ -52,6 +54,7 @@ const InfiniteVirtualList: FC<IInfiniteVirtualListProps> = ({
detail=
{
segItem
}
detail=
{
segItem
}
onClick=
{
()
=>
onClickCard
(
segItem
)
}
onClick=
{
()
=>
onClickCard
(
segItem
)
}
onChangeSwitch=
{
onChangeSwitch
}
onChangeSwitch=
{
onChangeSwitch
}
onDelete=
{
onDelete
}
loading=
{
false
}
loading=
{
false
}
/>
/>
))
))
...
...
web/app/components/datasets/documents/detail/completed/SegmentCard.tsx
View file @
2b5bc9e0
import
type
{
FC
}
from
'react'
import
type
{
FC
}
from
'react'
import
React
from
'react'
import
React
,
{
useState
}
from
'react'
import
cn
from
'classnames'
import
cn
from
'classnames'
import
{
ArrowUpRightIcon
}
from
'@heroicons/react/24/outline'
import
{
ArrowUpRightIcon
}
from
'@heroicons/react/24/outline'
import
{
useTranslation
}
from
'react-i18next'
import
{
useTranslation
}
from
'react-i18next'
...
@@ -7,11 +7,15 @@ import { StatusItem } from '../../list'
...
@@ -7,11 +7,15 @@ import { StatusItem } from '../../list'
import
{
DocumentTitle
}
from
'../index'
import
{
DocumentTitle
}
from
'../index'
import
s
from
'./style.module.css'
import
s
from
'./style.module.css'
import
{
SegmentIndexTag
}
from
'./index'
import
{
SegmentIndexTag
}
from
'./index'
import
Modal
from
'@/app/components/base/modal'
import
Button
from
'@/app/components/base/button'
import
Switch
from
'@/app/components/base/switch'
import
Switch
from
'@/app/components/base/switch'
import
Divider
from
'@/app/components/base/divider'
import
Divider
from
'@/app/components/base/divider'
import
Indicator
from
'@/app/components/header/indicator'
import
Indicator
from
'@/app/components/header/indicator'
import
{
formatNumber
}
from
'@/utils/format'
import
{
formatNumber
}
from
'@/utils/format'
import
type
{
SegmentDetailModel
}
from
'@/models/datasets'
import
type
{
SegmentDetailModel
}
from
'@/models/datasets'
import
{
AlertCircle
}
from
'@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import
{
Trash03
}
from
'@/app/components/base/icons/src/vender/line/general'
const
ProgressBar
:
FC
<
{
percent
:
number
;
loading
:
boolean
}
>
=
({
percent
,
loading
})
=>
{
const
ProgressBar
:
FC
<
{
percent
:
number
;
loading
:
boolean
}
>
=
({
percent
,
loading
})
=>
{
return
(
return
(
...
@@ -35,6 +39,7 @@ type ISegmentCardProps = {
...
@@ -35,6 +39,7 @@ type ISegmentCardProps = {
score
?:
number
score
?:
number
onClick
?:
()
=>
void
onClick
?:
()
=>
void
onChangeSwitch
?:
(
segId
:
string
,
enabled
:
boolean
)
=>
Promise
<
void
>
onChangeSwitch
?:
(
segId
:
string
,
enabled
:
boolean
)
=>
Promise
<
void
>
onDelete
?:
(
segId
:
string
)
=>
Promise
<
void
>
scene
?:
UsageScene
scene
?:
UsageScene
className
?:
string
className
?:
string
}
}
...
@@ -44,6 +49,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
...
@@ -44,6 +49,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
score
,
score
,
onClick
,
onClick
,
onChangeSwitch
,
onChangeSwitch
,
onDelete
,
loading
=
true
,
loading
=
true
,
scene
=
'doc'
,
scene
=
'doc'
,
className
=
''
,
className
=
''
,
...
@@ -60,6 +66,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
...
@@ -60,6 +66,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
answer
,
answer
,
}
=
detail
as
any
}
=
detail
as
any
const
isDocScene
=
scene
===
'doc'
const
isDocScene
=
scene
===
'doc'
const
[
showModal
,
setShowModal
]
=
useState
(
false
)
const
renderContent
=
()
=>
{
const
renderContent
=
()
=>
{
if
(
answer
)
{
if
(
answer
)
{
...
@@ -86,7 +93,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
...
@@ -86,7 +93,7 @@ const SegmentCard: FC<ISegmentCardProps> = ({
s
.
segWrapper
,
s
.
segWrapper
,
(
isDocScene
&&
!
enabled
)
?
'bg-gray-25'
:
''
,
(
isDocScene
&&
!
enabled
)
?
'bg-gray-25'
:
''
,
'group'
,
'group'
,
!
loading
?
'pb-4'
:
''
,
!
loading
?
'pb-4
hover:pb-[10px]
'
:
''
,
className
,
className
,
)
}
)
}
onClick=
{
()
=>
onClick
?.()
}
onClick=
{
()
=>
onClick
?.()
}
...
@@ -159,10 +166,16 @@ const SegmentCard: FC<ISegmentCardProps> = ({
...
@@ -159,10 +166,16 @@ const SegmentCard: FC<ISegmentCardProps> = ({
<
div
className=
{
cn
(
s
.
commonIcon
,
s
.
targetIcon
)
}
/>
<
div
className=
{
cn
(
s
.
commonIcon
,
s
.
targetIcon
)
}
/>
<
div
className=
{
s
.
segDataText
}
>
{
formatNumber
(
hit_count
)
}
</
div
>
<
div
className=
{
s
.
segDataText
}
>
{
formatNumber
(
hit_count
)
}
</
div
>
</
div
>
</
div
>
<
div
className=
"flex items-center"
>
<
div
className=
"
grow
flex items-center"
>
<
div
className=
{
cn
(
s
.
commonIcon
,
s
.
bezierCurveIcon
)
}
/>
<
div
className=
{
cn
(
s
.
commonIcon
,
s
.
bezierCurveIcon
)
}
/>
<
div
className=
{
s
.
segDataText
}
>
{
index_node_hash
}
</
div
>
<
div
className=
{
s
.
segDataText
}
>
{
index_node_hash
}
</
div
>
</
div
>
</
div
>
<
div
className=
'shrink-0 w-6 h-6 flex items-center justify-center rounded-md hover:bg-red-100 hover:text-red-600 cursor-pointer group/delete'
onClick=
{
(
e
)
=>
{
e
.
stopPropagation
()
setShowModal
(
true
)
}
}
>
<
Trash03
className=
'w-[14px] h-[14px] text-gray-500 group-hover/delete:text-red-600'
/>
</
div
>
</
div
>
</
div
>
</>
</>
:
<>
:
<>
...
@@ -187,6 +200,26 @@ const SegmentCard: FC<ISegmentCardProps> = ({
...
@@ -187,6 +200,26 @@ const SegmentCard: FC<ISegmentCardProps> = ({
</
div
>
</
div
>
</>
</>
)
}
)
}
{
showModal
&&
<
Modal
isShow=
{
showModal
}
onClose=
{
()
=>
setShowModal
(
false
)
}
className=
{
s
.
delModal
}
closable
>
<
div
>
<
div
className=
{
s
.
warningWrapper
}
>
<
AlertCircle
className=
'w-6 h-6 text-red-600'
/>
</
div
>
<
div
className=
'text-xl font-semibold text-gray-900 mb-1'
>
{
t
(
'datasetDocuments.segment.delete'
)
}
</
div
>
<
div
className=
'flex gap-2 justify-end'
>
<
Button
onClick=
{
()
=>
setShowModal
(
false
)
}
>
{
t
(
'common.operation.cancel'
)
}
</
Button
>
<
Button
type=
'warning'
onClick=
{
async
()
=>
{
await
onDelete
?.(
id
)
}
}
className=
'border-red-700 border-[0.5px]'
>
{
t
(
'common.operation.sure'
)
}
</
Button
>
</
div
>
</
div
>
</
Modal
>
}
</
div
>
</
div
>
)
)
}
}
...
...
web/app/components/datasets/documents/detail/completed/index.tsx
View file @
2b5bc9e0
...
@@ -18,7 +18,7 @@ import Input from '@/app/components/base/input'
...
@@ -18,7 +18,7 @@ import Input from '@/app/components/base/input'
import
{
ToastContext
}
from
'@/app/components/base/toast'
import
{
ToastContext
}
from
'@/app/components/base/toast'
import
type
{
Item
}
from
'@/app/components/base/select'
import
type
{
Item
}
from
'@/app/components/base/select'
import
{
SimpleSelect
}
from
'@/app/components/base/select'
import
{
SimpleSelect
}
from
'@/app/components/base/select'
import
{
disableSegment
,
enableSegment
,
fetchSegments
,
updateSegment
}
from
'@/service/datasets'
import
{
d
eleteSegment
,
d
isableSegment
,
enableSegment
,
fetchSegments
,
updateSegment
}
from
'@/service/datasets'
import
type
{
SegmentDetailModel
,
SegmentUpdator
,
SegmentsQuery
,
SegmentsResponse
}
from
'@/models/datasets'
import
type
{
SegmentDetailModel
,
SegmentUpdator
,
SegmentsQuery
,
SegmentsResponse
}
from
'@/models/datasets'
import
{
asyncRunSafe
}
from
'@/utils'
import
{
asyncRunSafe
}
from
'@/utils'
import
type
{
CommonResponse
}
from
'@/models/common'
import
type
{
CommonResponse
}
from
'@/models/common'
...
@@ -272,6 +272,17 @@ const Completed: FC<ICompletedProps> = ({ showNewSegmentModal, onNewSegmentModal
...
@@ -272,6 +272,17 @@ const Completed: FC<ICompletedProps> = ({ showNewSegmentModal, onNewSegmentModal
}
}
}
}
const
onDelete
=
async
(
segId
:
string
)
=>
{
const
[
e
]
=
await
asyncRunSafe
<
CommonResponse
>
(
deleteSegment
({
datasetId
,
documentId
,
segmentId
:
segId
})
as
Promise
<
CommonResponse
>
)
if
(
!
e
)
{
notify
({
type
:
'success'
,
message
:
t
(
'common.actionMsg.modifiedSuccessfully'
)
})
resetList
()
}
else
{
notify
({
type
:
'error'
,
message
:
t
(
'common.actionMsg.modificationFailed'
)
})
}
}
const
handleUpdateSegment
=
async
(
segmentId
:
string
,
question
:
string
,
answer
:
string
)
=>
{
const
handleUpdateSegment
=
async
(
segmentId
:
string
,
question
:
string
,
answer
:
string
)
=>
{
const
params
:
SegmentUpdator
=
{
content
:
''
}
const
params
:
SegmentUpdator
=
{
content
:
''
}
if
(
docForm
===
'qa_model'
)
{
if
(
docForm
===
'qa_model'
)
{
...
@@ -330,6 +341,7 @@ const Completed: FC<ICompletedProps> = ({ showNewSegmentModal, onNewSegmentModal
...
@@ -330,6 +341,7 @@ const Completed: FC<ICompletedProps> = ({ showNewSegmentModal, onNewSegmentModal
items=
{
allSegments
}
items=
{
allSegments
}
loadNextPage=
{
getSegments
}
loadNextPage=
{
getSegments
}
onChangeSwitch=
{
onChangeSwitch
}
onChangeSwitch=
{
onChangeSwitch
}
onDelete=
{
onDelete
}
onClick=
{
onClickCard
}
onClick=
{
onClickCard
}
/>
/>
<
Modal
isShow=
{
currSegment
.
showModal
}
onClose=
{
()
=>
{}
}
className=
'!max-w-[640px] !overflow-visible'
>
<
Modal
isShow=
{
currSegment
.
showModal
}
onClose=
{
()
=>
{}
}
className=
'!max-w-[640px] !overflow-visible'
>
...
...
web/app/components/datasets/documents/detail/completed/style.module.css
View file @
2b5bc9e0
...
@@ -132,3 +132,24 @@
...
@@ -132,3 +132,24 @@
.editTip
{
.editTip
{
box-shadow
:
0px
4px
6px
-2px
rgba
(
16
,
24
,
40
,
0.03
),
0px
12px
16px
-4px
rgba
(
16
,
24
,
40
,
0.08
);
box-shadow
:
0px
4px
6px
-2px
rgba
(
16
,
24
,
40
,
0.03
),
0px
12px
16px
-4px
rgba
(
16
,
24
,
40
,
0.08
);
}
}
.delModal
{
background
:
linear-gradient
(
180deg
,
rgba
(
217
,
45
,
32
,
0.05
)
0%
,
rgba
(
217
,
45
,
32
,
0
)
24.02%
),
#f9fafb
;
box-shadow
:
0px
20px
24px
-4px
rgba
(
16
,
24
,
40
,
0.08
),
0px
8px
8px
-4px
rgba
(
16
,
24
,
40
,
0.03
);
@apply
rounded-2xl
p-8;
}
.warningWrapper
{
box-shadow
:
0px
20px
24px
-4px
rgba
(
16
,
24
,
40
,
0.08
),
0px
8px
8px
-4px
rgba
(
16
,
24
,
40
,
0.03
);
background
:
rgba
(
255
,
255
,
255
,
0.9
);
@apply
h-12
w-12
border-[0.5px]
border-gray-100
rounded-xl
mb-3
flex
items-center
justify-center;
}
.warningIcon
{
@apply
w-[22px]
h-[22px]
fill-current
text-red-600;
}
web/i18n/lang/dataset-documents.en.ts
View file @
2b5bc9e0
...
@@ -320,6 +320,7 @@ const translation = {
...
@@ -320,6 +320,7 @@ const translation = {
contentEmpty
:
'Content can not be empty'
,
contentEmpty
:
'Content can not be empty'
,
newTextSegment
:
'New Text Segment'
,
newTextSegment
:
'New Text Segment'
,
newQaSegment
:
'New Q&A Segment'
,
newQaSegment
:
'New Q&A Segment'
,
delete
:
'Delete this segment ?'
,
},
},
}
}
...
...
web/i18n/lang/dataset-documents.zh.ts
View file @
2b5bc9e0
...
@@ -319,6 +319,7 @@ const translation = {
...
@@ -319,6 +319,7 @@ const translation = {
contentEmpty
:
'内容不能为空'
,
contentEmpty
:
'内容不能为空'
,
newTextSegment
:
'新文本分段'
,
newTextSegment
:
'新文本分段'
,
newQaSegment
:
'新问答分段'
,
newQaSegment
:
'新问答分段'
,
delete
:
'删除这个分段?'
,
},
},
}
}
...
...
web/service/datasets.ts
View file @
2b5bc9e0
...
@@ -168,6 +168,10 @@ export const addSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string },
...
@@ -168,6 +168,10 @@ export const addSegment: Fetcher<{ data: SegmentDetailModel; doc_form: string },
return
post
(
`/datasets/
${
datasetId
}
/documents/
${
documentId
}
/segment`
,
{
body
})
as
Promise
<
{
data
:
SegmentDetailModel
;
doc_form
:
string
}
>
return
post
(
`/datasets/
${
datasetId
}
/documents/
${
documentId
}
/segment`
,
{
body
})
as
Promise
<
{
data
:
SegmentDetailModel
;
doc_form
:
string
}
>
}
}
export
const
deleteSegment
:
Fetcher
<
CommonResponse
,
{
datasetId
:
string
;
documentId
:
string
;
segmentId
:
string
}
>
=
({
datasetId
,
documentId
,
segmentId
})
=>
{
return
del
(
`/datasets/
${
datasetId
}
/documents/
${
documentId
}
/segments/
${
segmentId
}
`
)
as
Promise
<
CommonResponse
>
}
// hit testing
// hit testing
export
const
hitTesting
:
Fetcher
<
HitTestingResponse
,
{
datasetId
:
string
;
queryText
:
string
}
>
=
({
datasetId
,
queryText
})
=>
{
export
const
hitTesting
:
Fetcher
<
HitTestingResponse
,
{
datasetId
:
string
;
queryText
:
string
}
>
=
({
datasetId
,
queryText
})
=>
{
return
post
(
`/datasets/
${
datasetId
}
/hit-testing`
,
{
body
:
{
query
:
queryText
}
})
as
Promise
<
HitTestingResponse
>
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