From 9d63b3cbfcb6b7a0aa427a3595f55534ade53586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=9B=BD=E7=92=87?= <37972689+YangGuoXuan-0503@users.noreply.github.com> Date: Fri, 27 Dec 2024 17:45:28 +0800 Subject: [PATCH] Feat ai op tip (#7270) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ai op tip * feat: optimize code --------- Co-authored-by: 杨国璇 --- frontend/src/hooks/metadata-ai-operation.js | 19 +++++++++++++++---- .../components/metadata-details/constants.js | 1 - .../components/metadata-details/utils.js | 7 ++----- .../src/metadata/hooks/metadata-details.js | 10 ++++++---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/frontend/src/hooks/metadata-ai-operation.js b/frontend/src/hooks/metadata-ai-operation.js index 3b540f99a37..b6d1a58dc42 100644 --- a/frontend/src/hooks/metadata-ai-operation.js +++ b/frontend/src/hooks/metadata-ai-operation.js @@ -21,7 +21,6 @@ export const MetadataAIOperationsProvider = ({ const canModify = useMemo(() => permission === 'rw', [permission]); const OCRSuccessCallBack = useCallback(({ parentDir, fileName, ocrResult } = {}) => { - toaster.success(gettext('Successfully OCR')); if (!ocrResult) return; const update = { [PRIVATE_COLUMN_KEY.OCR]: ocrResult }; metadataAPI.modifyRecord(repoID, { parentDir, fileName }, update).then(res => { @@ -32,12 +31,16 @@ export const MetadataAIOperationsProvider = ({ const onOCR = useCallback(({ parentDir, fileName }, { success_callback, fail_callback } = {}) => { const filePath = Utils.joinPath(parentDir, fileName); + const inProgressToaster = toaster.notifyInProgress(gettext('Using AI to extract text, please wait...'), { duration: null }); metadataAPI.ocr(repoID, filePath).then(res => { const ocrResult = res.data.ocr_result; const validResult = Array.isArray(ocrResult) && ocrResult.length > 0 ? JSON.stringify(ocrResult) : null; + inProgressToaster.close(); + toaster.success(gettext('AI to extract text, completed.')); success_callback && success_callback({ parentDir, fileName, ocrResult: validResult }); }).catch(error => { - const errorMessage = gettext('OCR failed'); + inProgressToaster.close(); + const errorMessage = gettext('Failed to extract text'); toaster.danger(errorMessage); fail_callback && fail_callback(); }); @@ -51,22 +54,30 @@ export const MetadataAIOperationsProvider = ({ APIName = isImage ? 'imageCaption' : 'generateDescription'; } if (!APIName) return; - + const descriptionTip = isImage ? gettext('image description') : gettext('description'); + const inProgressToaster = toaster.notifyInProgress(gettext('Using AI to generate {description}, please wait...').replace('{description}', descriptionTip), { duration: null }); metadataAPI[APIName](repoID, filePath, lang).then(res => { const description = res?.data?.summary || res.data.desc || ''; + inProgressToaster.close(); + toaster.success(gettext('AI to generate description, completed.').replace('{description}', descriptionTip)); success_callback && success_callback({ parentDir, fileName, description }); }).catch(error => { - const errorMessage = isImage ? gettext('Failed to generate image description') : gettext('Failed to generate description'); + inProgressToaster.close(); + const errorMessage = gettext('Failed to generate description').replace('{description}', descriptionTip); toaster.danger(errorMessage); fail_callback && fail_callback(); }); }, [repoID]); const extractFilesDetails = useCallback((objIds, { success_callback, fail_callback } = {}) => { + const inProgressToaster = toaster.notifyInProgress(gettext('Using AI to extract file details, please wait...'), { duration: null }); metadataAPI.extractFileDetails(repoID, objIds).then(res => { const details = res?.data?.details || []; + inProgressToaster.close(); + toaster.success(gettext('AI to extract file details, completed.')); success_callback && success_callback({ details }); }).catch(error => { + inProgressToaster.close(); const errorMessage = gettext('Failed to extract file details'); toaster.danger(errorMessage); fail_callback && fail_callback(); diff --git a/frontend/src/metadata/components/metadata-details/constants.js b/frontend/src/metadata/components/metadata-details/constants.js index 8e665f9c406..9657203796c 100644 --- a/frontend/src/metadata/components/metadata-details/constants.js +++ b/frontend/src/metadata/components/metadata-details/constants.js @@ -18,7 +18,6 @@ export const NOT_DISPLAY_COLUMN_KEYS = [ PRIVATE_COLUMN_KEY.SIZE, PRIVATE_COLUMN_KEY.SUFFIX, PRIVATE_COLUMN_KEY.FILE_DETAILS, - PRIVATE_COLUMN_KEY.LOCATION, PRIVATE_COLUMN_KEY.FACE_LINKS, PRIVATE_COLUMN_KEY.EXCLUDED_FACE_LINKS, PRIVATE_COLUMN_KEY.FACE_VECTORS, diff --git a/frontend/src/metadata/components/metadata-details/utils.js b/frontend/src/metadata/components/metadata-details/utils.js index 0721f694f09..0f04f7e95f7 100644 --- a/frontend/src/metadata/components/metadata-details/utils.js +++ b/frontend/src/metadata/components/metadata-details/utils.js @@ -1,10 +1,9 @@ import { getNormalizedColumnType } from '../../utils/column'; import { getCellValueByColumn } from '../../utils/cell'; -import { NOT_DISPLAY_COLUMN_KEYS, CellType, PRIVATE_COLUMN_KEY } from './constants'; export const normalizeFields = (fields) => { if (!Array.isArray(fields) || fields.length === 0) return []; - let validFields = fields.map((field) => { + return fields.map((field) => { const { type, key, ...params } = field; return { ...params, @@ -12,9 +11,7 @@ export const normalizeFields = (fields) => { type: getNormalizedColumnType(key, type), width: 200, }; - }).filter(field => !NOT_DISPLAY_COLUMN_KEYS.includes(field.key)); - validFields.push({ key: PRIVATE_COLUMN_KEY.LOCATION, type: CellType.GEOLOCATION, width: 200 }); - return validFields; + }); }; export { diff --git a/frontend/src/metadata/hooks/metadata-details.js b/frontend/src/metadata/hooks/metadata-details.js index 9671d904f6d..e86c256f28e 100644 --- a/frontend/src/metadata/hooks/metadata-details.js +++ b/frontend/src/metadata/hooks/metadata-details.js @@ -11,6 +11,7 @@ import { getCellValueByColumn, getColumnOptionNamesByIds, getColumnOptionNameByI import tagsAPI from '../../tag/api'; import { getColumnByKey, getColumnOptions, getColumnOriginName } from '../utils/column'; import ObjectUtils from '../utils/object-utils'; +import { NOT_DISPLAY_COLUMN_KEYS } from '../components/metadata-details/constants'; const MetadataDetailsContext = React.createContext(null); @@ -56,7 +57,7 @@ export const MetadataDetailsProvider = ({ repoID, repoInfo, path, dirent, dirent }, [record]); const onChange = useCallback((fieldKey, newValue) => { - const field = getColumnByKey(originColumns, fieldKey); + const field = getColumnByKey(allColumnsRef.current, fieldKey); const columnName = getColumnOriginName(field); const recordId = getRecordIdFromRecord(record); let update = { [columnName]: newValue }; @@ -74,7 +75,7 @@ export const MetadataDetailsProvider = ({ repoID, repoInfo, path, dirent, dirent const errorMsg = Utils.getErrorMsg(error); toaster.danger(errorMsg); }); - }, [repoID, record, originColumns]); + }, [repoID, record, allColumnsRef]); const modifyColumnData = useCallback((fieldKey, newData) => { let newColumns = originColumns.slice(0); @@ -174,8 +175,9 @@ export const MetadataDetailsProvider = ({ repoID, repoInfo, path, dirent, dirent metadataAPI.getRecord(repoID, { parentDir, fileName }).then(res => { const { results, metadata } = res.data; const record = Array.isArray(results) && results.length > 0 ? results[0] : {}; - const columns = normalizeFields(metadata).map(field => new Column(field)); - allColumnsRef.current = columns; + const allColumns = normalizeFields(metadata).map(field => new Column(field)); + allColumnsRef.current = allColumns; + const columns = allColumns.filter(c => !NOT_DISPLAY_COLUMN_KEYS.includes(c.key)); setRecord(record); setOriginColumns(columns); setLoading(false);