feat: clear all annotation (#22878)
Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -123,6 +123,17 @@ class AnnotationListApi(Resource):
|
||||
}
|
||||
return response, 200
|
||||
|
||||
@setup_required
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
def delete(self, app_id):
|
||||
if not current_user.is_editor:
|
||||
raise Forbidden()
|
||||
|
||||
app_id = str(app_id)
|
||||
AppAnnotationService.clear_all_annotations(app_id)
|
||||
return {"result": "success"}, 204
|
||||
|
||||
|
||||
class AnnotationExportApi(Resource):
|
||||
@setup_required
|
||||
|
@@ -440,3 +440,27 @@ class AppAnnotationService:
|
||||
"embedding_model_name": collection_binding_detail.model_name,
|
||||
},
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def clear_all_annotations(cls, app_id: str) -> dict:
|
||||
app = (
|
||||
db.session.query(App)
|
||||
.filter(App.id == app_id, App.tenant_id == current_user.current_tenant_id, App.status == "normal")
|
||||
.first()
|
||||
)
|
||||
|
||||
if not app:
|
||||
raise NotFound("App not found")
|
||||
|
||||
annotations_query = db.session.query(MessageAnnotation).filter(MessageAnnotation.app_id == app_id)
|
||||
for annotation in annotations_query.yield_per(100):
|
||||
annotation_hit_histories_query = db.session.query(AppAnnotationHitHistory).filter(
|
||||
AppAnnotationHitHistory.annotation_id == annotation.id
|
||||
)
|
||||
for annotation_hit_history in annotation_hit_histories_query.yield_per(100):
|
||||
db.session.delete(annotation_hit_history)
|
||||
|
||||
db.session.delete(annotation)
|
||||
|
||||
db.session.commit()
|
||||
return {"result": "success"}
|
||||
|
@@ -0,0 +1,32 @@
|
||||
'use client'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Confirm from '@/app/components/base/confirm'
|
||||
|
||||
type Props = {
|
||||
isShow: boolean
|
||||
onHide: () => void
|
||||
onConfirm: () => void
|
||||
}
|
||||
|
||||
const ClearAllAnnotationsConfirmModal: FC<Props> = ({
|
||||
isShow,
|
||||
onHide,
|
||||
onConfirm,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Confirm
|
||||
isShow={isShow}
|
||||
onCancel={onHide}
|
||||
onConfirm={onConfirm}
|
||||
type='danger'
|
||||
title={t('appAnnotation.table.header.clearAllConfirm')}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(ClearAllAnnotationsConfirmModal)
|
@@ -1,9 +1,11 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import React, { Fragment, useEffect, useState } from 'react'
|
||||
import ClearAllAnnotationsConfirmModal from '../clear-all-annotations-confirm-modal'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
RiAddLine,
|
||||
RiDeleteBinLine,
|
||||
RiMoreFill,
|
||||
} from '@remixicon/react'
|
||||
import { useContext } from 'use-context-selector'
|
||||
@@ -22,6 +24,7 @@ import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows
|
||||
|
||||
import I18n from '@/context/i18n'
|
||||
import { fetchExportAnnotationList } from '@/service/annotation'
|
||||
import { clearAllAnnotations } from '@/service/annotation'
|
||||
import { LanguagesSupported } from '@/i18n-config/language'
|
||||
|
||||
const CSV_HEADER_QA_EN = ['Question', 'Answer']
|
||||
@@ -76,7 +79,21 @@ const HeaderOptions: FC<Props> = ({
|
||||
}, [controlUpdateList])
|
||||
|
||||
const [showBulkImportModal, setShowBulkImportModal] = useState(false)
|
||||
|
||||
const [showClearConfirm, setShowClearConfirm] = useState(false)
|
||||
const handleClearAll = () => {
|
||||
setShowClearConfirm(true)
|
||||
}
|
||||
const handleConfirmed = async () => {
|
||||
try {
|
||||
await clearAllAnnotations(appId)
|
||||
onAdded()
|
||||
}
|
||||
catch (_) {
|
||||
}
|
||||
finally {
|
||||
setShowClearConfirm(false)
|
||||
}
|
||||
}
|
||||
const Operations = () => {
|
||||
return (
|
||||
<div className="w-full py-1">
|
||||
@@ -125,6 +142,15 @@ const HeaderOptions: FC<Props> = ({
|
||||
</MenuItems>
|
||||
</Transition>
|
||||
</Menu>
|
||||
<button
|
||||
onClick={handleClearAll}
|
||||
className='mx-1 flex h-9 w-[calc(100%_-_8px)] cursor-pointer items-center space-x-2 rounded-lg px-3 py-2 text-red-600 hover:bg-red-50 disabled:opacity-50'
|
||||
>
|
||||
<RiDeleteBinLine className='h-4 w-4'/>
|
||||
<span className='system-sm-regular grow text-left'>
|
||||
{t('appAnnotation.table.header.clearAll')}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -169,6 +195,15 @@ const HeaderOptions: FC<Props> = ({
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
showClearConfirm && (
|
||||
<ClearAllAnnotationsConfirmModal
|
||||
isShow={showClearConfirm}
|
||||
onHide={() => setShowClearConfirm(false)}
|
||||
onConfirm={handleConfirmed}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@@ -16,7 +16,8 @@ const translation = {
|
||||
addAnnotation: 'Add Annotation',
|
||||
bulkImport: 'Bulk Import',
|
||||
bulkExport: 'Bulk Export',
|
||||
clearAll: 'Clear All Annotation',
|
||||
clearAll: 'Delete All',
|
||||
clearAllConfirm: 'Delete all annotations?',
|
||||
},
|
||||
},
|
||||
editModal: {
|
||||
|
@@ -18,7 +18,8 @@ const translation = {
|
||||
addAnnotation: '注釈を追加',
|
||||
bulkImport: '一括インポート',
|
||||
bulkExport: '一括エクスポート',
|
||||
clearAll: 'すべての注釈をクリア',
|
||||
clearAll: 'すべて削除',
|
||||
clearAllConfirm: 'すべての寸法を削除?',
|
||||
},
|
||||
},
|
||||
editModal: {
|
||||
|
@@ -18,7 +18,8 @@ const translation = {
|
||||
addAnnotation: '添加标注',
|
||||
bulkImport: '批量导入',
|
||||
bulkExport: '批量导出',
|
||||
clearAll: '删除所有标注',
|
||||
clearAll: '删除所有',
|
||||
clearAllConfirm: '删除所有标注?',
|
||||
},
|
||||
},
|
||||
editModal: {
|
||||
|
@@ -63,3 +63,7 @@ export const delAnnotation = (appId: string, annotationId: string) => {
|
||||
export const fetchHitHistoryList = (appId: string, annotationId: string, params: Record<string, any>) => {
|
||||
return get(`apps/${appId}/annotations/${annotationId}/hit-histories`, { params })
|
||||
}
|
||||
|
||||
export const clearAllAnnotations = (appId: string): Promise<any> => {
|
||||
return del(`apps/${appId}/annotations`)
|
||||
}
|
||||
|
Reference in New Issue
Block a user