Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>tags/1.7.1
| } | } | ||||
| 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 |
| "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"} |
| '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) |
| '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> | ||||
| ) | ) | ||||
| } | } |
| 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: { |
| addAnnotation: '注釈を追加', | addAnnotation: '注釈を追加', | ||||
| bulkImport: '一括インポート', | bulkImport: '一括インポート', | ||||
| bulkExport: '一括エクスポート', | bulkExport: '一括エクスポート', | ||||
| clearAll: 'すべての注釈をクリア', | |||||
| clearAll: 'すべて削除', | |||||
| clearAllConfirm: 'すべての寸法を削除?', | |||||
| }, | }, | ||||
| }, | }, | ||||
| editModal: { | editModal: { |
| addAnnotation: '添加标注', | addAnnotation: '添加标注', | ||||
| bulkImport: '批量导入', | bulkImport: '批量导入', | ||||
| bulkExport: '批量导出', | bulkExport: '批量导出', | ||||
| clearAll: '删除所有标注', | |||||
| clearAll: '删除所有', | |||||
| clearAllConfirm: '删除所有标注?', | |||||
| }, | }, | ||||
| }, | }, | ||||
| editModal: { | editModal: { |
| 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`) | |||||
| } |