From 99e728c9b4d244d23be4a07efc76d1ea9734c3ad 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: Tue, 10 Sep 2024 15:18:07 +0800 Subject: [PATCH] feat: metadata description property (#6744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: metadata description property * feat: optimize view --------- Co-authored-by: 杨国璇 --- frontend/src/metadata/api.js | 2 +- .../constants/column/predefined-columns.js | 2 +- .../_basic/constants/column/private.js | 8 +-- .../popup-editor-container.js | 10 +--- .../cell-editor/long-text-editor/index.js | 10 ++++ .../components/context-menu/index.js | 50 +++++++++---------- .../popover/column-popover/type/index.js | 4 +- .../components/popover/sort-popover/index.js | 2 +- .../components/view/gallery/index.js | 2 +- .../src/metadata/metadata-view/context.js | 4 +- .../metadata-view/model/metadata/view.js | 4 +- .../metadata-view/store/operations/apply.js | 4 +- .../metadata-view/utils/column-utils.js | 6 +-- frontend/src/utils/utils.js | 2 +- 14 files changed, 55 insertions(+), 55 deletions(-) diff --git a/frontend/src/metadata/api.js b/frontend/src/metadata/api.js index 484ed0fc64..02fac8ddb6 100644 --- a/frontend/src/metadata/api.js +++ b/frontend/src/metadata/api.js @@ -202,7 +202,7 @@ class MetadataManagerAPI { }; // ai - generateSummary = (repoID, filePath) => { + generateDescription = (repoID, filePath) => { const url = this.server + '/api/v2.1/ai/generate-summary/'; const params = { path: filePath, diff --git a/frontend/src/metadata/metadata-view/_basic/constants/column/predefined-columns.js b/frontend/src/metadata/metadata-view/_basic/constants/column/predefined-columns.js index 8309b82360..f971ec242d 100644 --- a/frontend/src/metadata/metadata-view/_basic/constants/column/predefined-columns.js +++ b/frontend/src/metadata/metadata-view/_basic/constants/column/predefined-columns.js @@ -4,7 +4,7 @@ const PREDEFINED_COLUMN_KEYS = [ PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, PRIVATE_COLUMN_KEY.FILE_KEYWORDS, - PRIVATE_COLUMN_KEY.FILE_SUMMARY, + PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, PRIVATE_COLUMN_KEY.FILE_EXPIRED, PRIVATE_COLUMN_KEY.FILE_STATUS, ]; diff --git a/frontend/src/metadata/metadata-view/_basic/constants/column/private.js b/frontend/src/metadata/metadata-view/_basic/constants/column/private.js index 218ce2479e..63089a340e 100644 --- a/frontend/src/metadata/metadata-view/_basic/constants/column/private.js +++ b/frontend/src/metadata/metadata-view/_basic/constants/column/private.js @@ -18,7 +18,7 @@ export const PRIVATE_COLUMN_KEY = { FILE_COLLABORATORS: '_collaborators', FILE_EXPIRE_TIME: '_expire_time', FILE_KEYWORDS: '_keywords', - FILE_SUMMARY: '_summary', + FILE_DESCRIPTION: '_description', FILE_EXPIRED: '_expired', FILE_STATUS: '_status', LOCATION: '_location', @@ -45,7 +45,7 @@ export const PRIVATE_COLUMN_KEYS = [ PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, PRIVATE_COLUMN_KEY.FILE_KEYWORDS, - PRIVATE_COLUMN_KEY.FILE_SUMMARY, + PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, PRIVATE_COLUMN_KEY.FILE_EXPIRED, PRIVATE_COLUMN_KEY.FILE_STATUS, PRIVATE_COLUMN_KEY.LOCATION, @@ -59,7 +59,7 @@ export const EDITABLE_PRIVATE_COLUMN_KEYS = [ PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, PRIVATE_COLUMN_KEY.FILE_KEYWORDS, - // PRIVATE_COLUMN_KEY.FILE_SUMMARY, + PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, PRIVATE_COLUMN_KEY.FILE_EXPIRED, PRIVATE_COLUMN_KEY.FILE_STATUS, ]; @@ -72,7 +72,7 @@ export const DELETABLE_PRIVATE_COLUMN_KEY = [ PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, PRIVATE_COLUMN_KEY.FILE_KEYWORDS, - PRIVATE_COLUMN_KEY.FILE_SUMMARY, + PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, PRIVATE_COLUMN_KEY.FILE_EXPIRED, PRIVATE_COLUMN_KEY.FILE_STATUS, ]; diff --git a/frontend/src/metadata/metadata-view/components/cell-editor/editor-container/popup-editor-container.js b/frontend/src/metadata/metadata-view/components/cell-editor/editor-container/popup-editor-container.js index acedb59999..647434f909 100644 --- a/frontend/src/metadata/metadata-view/components/cell-editor/editor-container/popup-editor-container.js +++ b/frontend/src/metadata/metadata-view/components/cell-editor/editor-container/popup-editor-container.js @@ -125,15 +125,12 @@ class PopupEditorContainer extends React.Component { getOldRowData = (originalOldCellValue) => { const { column } = this.props; const columnName = getColumnOriginName(column); - const { key: columnKey, type: columnType } = column; + const { key: columnKey } = column; let oldValue = originalOldCellValue; if (this.getEditor().getOldValue) { const original = this.getEditor().getOldValue(); oldValue = original[Object.keys(original)[0]]; } - if (columnType === CellType.LONG_TEXT) { - oldValue = this.getEditor().getValue(); // long-text cell value need format to {text: '', links: [], ...} - } const oldRowData = { [columnName]: oldValue }; const originalOldRowData = { [columnKey]: originalOldCellValue }; // { [column.key]: cellValue } return { oldRowData, originalOldRowData }; @@ -171,11 +168,6 @@ class PopupEditorContainer extends React.Component { const key = Object.keys(updated)[0]; const value = updated[key]; const updates = PRIVATE_COLUMN_KEYS.includes(columnKey) ? { [columnKey]: value } : { [columnName]: value }; - - // special treatment of long-text column types to keep the stored data consistent - if (columnType === CellType.LONG_TEXT) { - originalUpdates[key] = value.text; - } const { oldRowData, originalOldRowData } = this.getOldRowData(originalOldCellValue); // updates used for update remote record data diff --git a/frontend/src/metadata/metadata-view/components/cell-editor/long-text-editor/index.js b/frontend/src/metadata/metadata-view/components/cell-editor/long-text-editor/index.js index 7a520684fa..bafa6f2654 100644 --- a/frontend/src/metadata/metadata-view/components/cell-editor/long-text-editor/index.js +++ b/frontend/src/metadata/metadata-view/components/cell-editor/long-text-editor/index.js @@ -44,6 +44,16 @@ class LongTextEditor extends React.PureComponent { return { text: '', preview: '', links: [], images: [], checklist: { completed: 0, count: 0 } }; }; + getOldValue = () => { + const value = this.props.value; + if (value) { + if (typeof value === 'object') return value.text; + if (typeof value === 'string') return value; + return ''; + } + return ''; + }; + getValue = () => { const updated = {}; updated[this.props.column.key] = this.value.text; diff --git a/frontend/src/metadata/metadata-view/components/context-menu/index.js b/frontend/src/metadata/metadata-view/components/context-menu/index.js index 79ec70c46e..a44cb08f12 100644 --- a/frontend/src/metadata/metadata-view/components/context-menu/index.js +++ b/frontend/src/metadata/metadata-view/components/context-menu/index.js @@ -14,7 +14,7 @@ const OPERATION = { COPY_SELECTED: 'copy-selected', OPEN_PARENT_FOLDER: 'open-parent-folder', OPEN_IN_NEW_TAB: 'open-new-tab', - GENERATE_SUMMARY: 'generate-summary', + GENERATE_DESCRIPTION: 'generate-description', IMAGE_CAPTION: 'image-caption', }; @@ -40,7 +40,7 @@ const ContextMenu = ({ const permission = window.sfMetadataContext.getPermission(); const isReadonly = permission === 'r'; const { columns } = metadata; - const summaryColumn = getColumnByKey(columns, PRIVATE_COLUMN_KEY.FILE_SUMMARY); + const descriptionColumn = getColumnByKey(columns, PRIVATE_COLUMN_KEY.FILE_DESCRIPTION); const canModifyRow = window.sfMetadataContext.canModifyRow; let list = []; @@ -48,13 +48,13 @@ const ContextMenu = ({ !isReadonly && list.push({ value: OPERATION.CLEAR_SELECTED, label: gettext('Clear selected') }); list.push({ value: OPERATION.COPY_SELECTED, label: gettext('Copy selected') }); - if (summaryColumn) { + if (descriptionColumn) { const { topLeft, bottomRight } = selectedRange; for (let i = topLeft.rowIdx; i <= bottomRight.rowIdx; i++) { const record = recordGetterByIndex({ isGroupView, groupRecordIndex: topLeft.groupRecordIndex, recordIndex: i }); const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME]; - if (Utils.isSummarySupportedFile(fileName) && canModifyRow(record)) { - list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') }); + if (Utils.isDescriptionSupportedFile(fileName) && canModifyRow(record)) { + list.push({ value: OPERATION.GENERATE_DESCRIPTION, label: gettext('Generate description') }); break; } } @@ -64,17 +64,17 @@ const ContextMenu = ({ const selectedRecords = Object.keys(recordMetrics.idSelectedRecordMap); if (selectedRecords.length > 1) { - if (summaryColumn) { + if (descriptionColumn) { const isIncludeSdocRecord = selectedRecords.filter(id => { const record = metadata.id_row_map[id]; if (record) { const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME]; - return Utils.isSummarySupportedFile(fileName) && canModifyRow(record); + return Utils.isDescriptionSupportedFile(fileName) && canModifyRow(record); } return false; }); if (isIncludeSdocRecord.length > 0) { - list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') }); + list.push({ value: OPERATION.GENERATE_DESCRIPTION, label: gettext('Generate description') }); } } return list; @@ -87,10 +87,10 @@ const ContextMenu = ({ const isFolder = record[PRIVATE_COLUMN_KEY.IS_DIR]; list.push({ value: OPERATION.OPEN_IN_NEW_TAB, label: isFolder ? gettext('Open folder in new tab') : gettext('Open file in new tab') }); list.push({ value: OPERATION.OPEN_PARENT_FOLDER, label: gettext('Open parent folder') }); - if (summaryColumn) { + if (descriptionColumn) { const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME]; - if (Utils.isSummarySupportedFile(fileName) && canModifyRow(record)) { - list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') }); + if (Utils.isDescriptionSupportedFile(fileName) && canModifyRow(record)) { + list.push({ value: OPERATION.GENERATE_DESCRIPTION, label: gettext('Generate description') }); } else if (Utils.imageCheck(fileName) && canModifyRow(record)) { list.push({ value: OPERATION.IMAGE_CAPTION, label: gettext('Generate image description') }); } @@ -140,40 +140,40 @@ const ContextMenu = ({ window.open(url, '_blank'); }, [isGroupView, recordGetterByIndex, selectedPosition]); - const generateSummary = useCallback(() => { + const generateDescription = useCallback(() => { const canModifyRow = window.sfMetadataContext.canModifyRow; - const summaryColumnKey = PRIVATE_COLUMN_KEY.FILE_SUMMARY; + const descriptionColumnKey = PRIVATE_COLUMN_KEY.FILE_DESCRIPTION; let path = ''; let idOldRecordData = {}; let idOriginalOldRecordData = {}; const { groupRecordIndex, rowIdx } = selectedPosition; const record = recordGetterByIndex({ isGroupView, groupRecordIndex, recordIndex: rowIdx }); const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME]; - if (Utils.isSummarySupportedFile(fileName) && canModifyRow(record)) { + if (Utils.isDescriptionSupportedFile(fileName) && canModifyRow(record)) { const parentDir = record[PRIVATE_COLUMN_KEY.PARENT_DIR]; path = Utils.joinPath(parentDir, fileName); - idOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] }; - idOriginalOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] }; + idOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [descriptionColumnKey]: record[descriptionColumnKey] }; + idOriginalOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [descriptionColumnKey]: record[descriptionColumnKey] }; } if (path === '') return; - window.sfMetadataContext.generateSummary(path).then(res => { - const summary = res.data.summary; + window.sfMetadataContext.generateDescription(path).then(res => { + const description = res.data.summary; const updateRecordId = record[PRIVATE_COLUMN_KEY.ID]; const recordIds = [updateRecordId]; let idRecordUpdates = {}; let idOriginalRecordUpdates = {}; - idRecordUpdates[updateRecordId] = { [summaryColumnKey]: summary }; - idOriginalRecordUpdates[updateRecordId] = { [summaryColumnKey]: summary }; + idRecordUpdates[updateRecordId] = { [descriptionColumnKey]: description }; + idOriginalRecordUpdates[updateRecordId] = { [descriptionColumnKey]: description }; updateRecords({ recordIds, idRecordUpdates, idOriginalRecordUpdates, idOldRecordData, idOriginalOldRecordData }); }).catch(error => { - const errorMessage = gettext('Failed to generate summary'); + const errorMessage = gettext('Failed to generate description'); toaster.danger(errorMessage); }); }, [isGroupView, selectedPosition, recordGetterByIndex, updateRecords]); const imageCaption = useCallback(() => { const canModifyRow = window.sfMetadataContext.canModifyRow; - const summaryColumnKey = PRIVATE_COLUMN_KEY.FILE_SUMMARY; + const summaryColumnKey = PRIVATE_COLUMN_KEY.FILE_DESCRIPTION; let path = ''; let idOldRecordData = {}; let idOriginalOldRecordData = {}; @@ -221,8 +221,8 @@ const ContextMenu = ({ onClearSelected && onClearSelected(); break; } - case OPERATION.GENERATE_SUMMARY: { - generateSummary && generateSummary(); + case OPERATION.GENERATE_DESCRIPTION: { + generateDescription && generateDescription(); break; } case OPERATION.IMAGE_CAPTION: { @@ -234,7 +234,7 @@ const ContextMenu = ({ } } setVisible(false); - }, [onOpenFileInNewTab, onOpenParentFolder, onCopySelected, onClearSelected, generateSummary, imageCaption]); + }, [onOpenFileInNewTab, onOpenParentFolder, onCopySelected, onClearSelected, generateDescription, imageCaption]); const getMenuPosition = useCallback((x = 0, y = 0) => { let menuStyles = { diff --git a/frontend/src/metadata/metadata-view/components/popover/column-popover/type/index.js b/frontend/src/metadata/metadata-view/components/popover/column-popover/type/index.js index 09421dbeb5..96edd458ea 100644 --- a/frontend/src/metadata/metadata-view/components/popover/column-popover/type/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/column-popover/type/index.js @@ -38,9 +38,9 @@ const COLUMNS = [ }, { icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], type: CellType.LONG_TEXT, - name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_SUMMARY), + name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_DESCRIPTION), unique: true, - key: PRIVATE_COLUMN_KEY.FILE_SUMMARY, + key: PRIVATE_COLUMN_KEY.FILE_DESCRIPTION, canChangeName: false, groupby: 'predefined' }, { diff --git a/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.js b/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.js index 435ea730ec..15a2968d1a 100644 --- a/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.js +++ b/frontend/src/metadata/metadata-view/components/popover/sort-popover/index.js @@ -218,7 +218,7 @@ class SortPopover extends Component { return (
{!readOnly && -
{} : (event) => this.deleteSort(event, index)}> +
{} : (event) => this.deleteSort(event, index)}> {!(viewType === VIEW_TYPE.GALLERY && index === 0) && }
} diff --git a/frontend/src/metadata/metadata-view/components/view/gallery/index.js b/frontend/src/metadata/metadata-view/components/view/gallery/index.js index beaa25fc80..e3910f9096 100644 --- a/frontend/src/metadata/metadata-view/components/view/gallery/index.js +++ b/frontend/src/metadata/metadata-view/components/view/gallery/index.js @@ -42,7 +42,7 @@ const Gallery = () => { const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME]; const parentDir = record[PRIVATE_COLUMN_KEY.PARENT_DIR]; const path = Utils.encodePath(Utils.joinPath(parentDir, fileName)); - const date = firstSort ? getDateDisplayString(record[firstSort.column_key], 'YYYY-MM-DD') : record[PRIVATE_COLUMN_KEY.FILE_CTIME].split('T')[0]; + const date = getDateDisplayString(record[firstSort.column_key], 'YYYY-MM-DD'); const img = { name: fileName, url: `${siteRoot}lib/${repoID}/file${path}`, diff --git a/frontend/src/metadata/metadata-view/context.js b/frontend/src/metadata/metadata-view/context.js index b366e88600..05956862da 100644 --- a/frontend/src/metadata/metadata-view/context.js +++ b/frontend/src/metadata/metadata-view/context.js @@ -192,9 +192,9 @@ class Context { }; // ai - generateSummary = (filePath) => { + generateDescription = (filePath) => { const repoID = this.settings['repoID']; - return this.metadataAPI.generateSummary(repoID, filePath); + return this.metadataAPI.generateDescription(repoID, filePath); }; imageCaption = (filePath) => { diff --git a/frontend/src/metadata/metadata-view/model/metadata/view.js b/frontend/src/metadata/metadata-view/model/metadata/view.js index 7a8ee14234..f196da9798 100644 --- a/frontend/src/metadata/metadata-view/model/metadata/view.js +++ b/frontend/src/metadata/metadata-view/model/metadata/view.js @@ -1,4 +1,4 @@ -import { getColumnByKey, VIEW_NOT_DISPLAY_COLUMN_KEYS, VIEW_TYPE_DEFAULT_BASIC_FILTER, VIEW_TYPE } from '../../_basic'; +import { getColumnByKey, VIEW_NOT_DISPLAY_COLUMN_KEYS, VIEW_TYPE_DEFAULT_BASIC_FILTER, VIEW_TYPE, VIEW_TYPE_DEFAULT_SORTS } from '../../_basic'; class View { constructor(object, columns) { @@ -17,7 +17,7 @@ class View { this.basic_filters = object.basic_filters && object.basic_filters.length > 0 ? object.basic_filters : VIEW_TYPE_DEFAULT_BASIC_FILTER[this.type]; // sort - this.sorts = object.sorts || []; + this.sorts = object.sorts && object.sorts.length > 0 ? object.sorts : VIEW_TYPE_DEFAULT_SORTS[this.type]; // group this.groupbys = object.groupbys || []; diff --git a/frontend/src/metadata/metadata-view/store/operations/apply.js b/frontend/src/metadata/metadata-view/store/operations/apply.js index 09f19bc97c..446841ec37 100644 --- a/frontend/src/metadata/metadata-view/store/operations/apply.js +++ b/frontend/src/metadata/metadata-view/store/operations/apply.js @@ -40,9 +40,7 @@ export default function apply(data, operation) { const rowId = row._id; const originalRowUpdates = id_original_row_updates[rowId]; const rowUpdates = id_row_updates[rowId]; - if (!rowUpdates && !originalRowUpdates) { - return; - } + if (!rowUpdates && !originalRowUpdates) return; const updatedRow = Object.assign({}, row, rowUpdates, originalRowUpdates, { '_mtime': modifyTime, '_last_modifier': modifier, diff --git a/frontend/src/metadata/metadata-view/utils/column-utils.js b/frontend/src/metadata/metadata-view/utils/column-utils.js index dd4a6bd148..b293fc5b05 100644 --- a/frontend/src/metadata/metadata-view/utils/column-utils.js +++ b/frontend/src/metadata/metadata-view/utils/column-utils.js @@ -196,8 +196,8 @@ export const getColumnDisplayName = (key, name) => { return gettext('File expire time'); case PRIVATE_COLUMN_KEY.FILE_KEYWORDS: return gettext('Document keywords'); - case PRIVATE_COLUMN_KEY.FILE_SUMMARY: - return gettext('Document summary'); + case PRIVATE_COLUMN_KEY.FILE_DESCRIPTION: + return gettext('Description'); case PRIVATE_COLUMN_KEY.FILE_EXPIRED: return gettext('Is expired'); case PRIVATE_COLUMN_KEY.FILE_STATUS: @@ -243,7 +243,7 @@ export const getColumnType = (key, type) => { return CellType.DATE; case PRIVATE_COLUMN_KEY.FILE_KEYWORDS: return CellType.TEXT; - case PRIVATE_COLUMN_KEY.FILE_SUMMARY: + case PRIVATE_COLUMN_KEY.FILE_DESCRIPTION: return CellType.LONG_TEXT; case PRIVATE_COLUMN_KEY.FILE_EXPIRED: return CellType.CHECKBOX; diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js index 2fa609421a..9175e1a118 100644 --- a/frontend/src/utils/utils.js +++ b/frontend/src/utils/utils.js @@ -905,7 +905,7 @@ export const Utils = { } }, - isSummarySupportedFile: function (filePath) { + isDescriptionSupportedFile: function (filePath) { return Utils.isSdocFile(filePath) || Utils.isMarkdownFile(filePath) || Utils.pdfCheck(filePath) || Utils.isDocxFile(filePath); },