Bladeren bron

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>
tags/1.7.1
呆萌闷油瓶 3 maanden geleden
bovenliggende
commit
ee50a2bcd5
No account linked to committer's email address

+ 11
- 0
api/controllers/console/app/annotation.py Bestand weergeven

} }
return response, 200 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): class AnnotationExportApi(Resource):
@setup_required @setup_required

+ 24
- 0
api/services/annotation_service.py Bestand weergeven

"embedding_model_name": collection_binding_detail.model_name, "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"}

+ 32
- 0
web/app/components/app/annotation/clear-all-annotations-confirm-modal/index.tsx Bestand weergeven

'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)

+ 36
- 1
web/app/components/app/annotation/header-opts/index.tsx Bestand weergeven

'use client' 'use client'
import type { FC } from 'react' import type { FC } from 'react'
import React, { Fragment, useEffect, useState } from 'react' import React, { Fragment, useEffect, useState } from 'react'
import ClearAllAnnotationsConfirmModal from '../clear-all-annotations-confirm-modal'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import {
RiAddLine, RiAddLine,
RiDeleteBinLine,
RiMoreFill, RiMoreFill,
} from '@remixicon/react' } from '@remixicon/react'
import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'


import I18n from '@/context/i18n' import I18n from '@/context/i18n'
import { fetchExportAnnotationList } from '@/service/annotation' import { fetchExportAnnotationList } from '@/service/annotation'
import { clearAllAnnotations } from '@/service/annotation'
import { LanguagesSupported } from '@/i18n-config/language' import { LanguagesSupported } from '@/i18n-config/language'


const CSV_HEADER_QA_EN = ['Question', 'Answer'] const CSV_HEADER_QA_EN = ['Question', 'Answer']
}, [controlUpdateList]) }, [controlUpdateList])


const [showBulkImportModal, setShowBulkImportModal] = useState(false) 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 = () => { const Operations = () => {
return ( return (
<div className="w-full py-1"> <div className="w-full py-1">
</MenuItems> </MenuItems>
</Transition> </Transition>
</Menu> </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> </div>
) )
} }
/> />
) )
} }
{
showClearConfirm && (
<ClearAllAnnotationsConfirmModal
isShow={showClearConfirm}
onHide={() => setShowClearConfirm(false)}
onConfirm={handleConfirmed}
/>
)
}
</div> </div>
) )
} }

+ 2
- 1
web/i18n/en-US/app-annotation.ts Bestand weergeven

addAnnotation: 'Add Annotation', addAnnotation: 'Add Annotation',
bulkImport: 'Bulk Import', bulkImport: 'Bulk Import',
bulkExport: 'Bulk Export', bulkExport: 'Bulk Export',
clearAll: 'Clear All Annotation',
clearAll: 'Delete All',
clearAllConfirm: 'Delete all annotations?',
}, },
}, },
editModal: { editModal: {

+ 2
- 1
web/i18n/ja-JP/app-annotation.ts Bestand weergeven

addAnnotation: '注釈を追加', addAnnotation: '注釈を追加',
bulkImport: '一括インポート', bulkImport: '一括インポート',
bulkExport: '一括エクスポート', bulkExport: '一括エクスポート',
clearAll: 'すべての注釈をクリア',
clearAll: 'すべて削除',
clearAllConfirm: 'すべての寸法を削除?',
}, },
}, },
editModal: { editModal: {

+ 2
- 1
web/i18n/zh-Hans/app-annotation.ts Bestand weergeven

addAnnotation: '添加标注', addAnnotation: '添加标注',
bulkImport: '批量导入', bulkImport: '批量导入',
bulkExport: '批量导出', bulkExport: '批量导出',
clearAll: '删除所有标注',
clearAll: '删除所有',
clearAllConfirm: '删除所有标注?',
}, },
}, },
editModal: { editModal: {

+ 4
- 0
web/service/annotation.ts Bestand weergeven

export const fetchHitHistoryList = (appId: string, annotationId: string, params: Record<string, any>) => { export const fetchHitHistoryList = (appId: string, annotationId: string, params: Record<string, any>) => {
return get(`apps/${appId}/annotations/${annotationId}/hit-histories`, { params }) return get(`apps/${appId}/annotations/${annotationId}/hit-histories`, { params })
} }

export const clearAllAnnotations = (appId: string): Promise<any> => {
return del(`apps/${appId}/annotations`)
}

Laden…
Annuleren
Opslaan