1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-20 02:48:51 +00:00

feat: init sdoc summary when add summary column (#6449)

* feat: init sdoc summary when add summary column

* feat/meta: add summary single sdoc

* optimize some naming

* add summarize files api

* optimize code

* feat: update code

* feat: optimzie code

* feat: rebase code

* fix/mv: fix invalid path param when create summary

* feat/mv: add batch update summary text func

* feat/mv: add some details in parameter judgment

* feat: optimize code

* feat: delete useless import

* execute return api

* feat/summary: execute file not found situation

* fix: summary

---------

Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
cir9no
2024-08-23 17:51:52 +08:00
committed by GitHub
parent 18a96ed607
commit 500b1dbb6b
9 changed files with 220 additions and 13 deletions

View File

@@ -1,9 +1,11 @@
import React, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { PRIVATE_COLUMN_KEY } from '../../_basic';
import { getColumnByKey, PRIVATE_COLUMN_KEY } from '../../_basic';
import { gettext } from '../../utils';
import { siteRoot } from '../../../../utils/constants';
import { Utils } from '../../../../utils/utils';
import { useMetadata } from '../../hooks';
import toaster from '../../../../components/toast';
import './index.css';
@@ -12,6 +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',
};
const ContextMenu = ({
@@ -22,23 +25,55 @@ const ContextMenu = ({
recordGetterByIndex,
onClearSelected,
onCopySelected,
updateRecords,
}) => {
const menuRef = useRef(null);
const [visible, setVisible] = useState(false);
const [position, setPosition] = useState({ top: 0, left: 0 });
const { metadata } = useMetadata();
const options = useMemo(() => {
if (!visible) return [];
const permission = window.sfMetadataContext.getPermission();
const isReadonly = permission === 'r';
const { columns } = metadata;
const summaryColumn = getColumnByKey(columns, PRIVATE_COLUMN_KEY.FILE_SUMMARY);
const canModifyRow = window.sfMetadataContext.canModifyRow;
let list = [];
if (selectedRange) {
!isReadonly && list.push({ value: OPERATION.CLEAR_SELECTED, label: gettext('Clear selected') });
list.push({ value: OPERATION.COPY_SELECTED, label: gettext('Copy selected') });
if (summaryColumn) {
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.isSdocFile(fileName) && canModifyRow(record)) {
list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') });
break;
}
}
}
return list;
}
if (Object.keys(recordMetrics.idSelectedRecordMap).length > 1) {
const selectedRecords = Object.keys(recordMetrics.idSelectedRecordMap);
if (selectedRecords.length > 1) {
if (summaryColumn) {
const isIncludeSdocRecord = selectedRecords.filter(id => {
const record = metadata.id_row_map[id];
if (record) {
const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME];
return Utils.isSdocFile(fileName) && canModifyRow(record);
}
return false;
});
if (isIncludeSdocRecord.length > 0) {
list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') });
}
}
return list;
}
@@ -49,9 +84,15 @@ 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) {
const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME];
if (Utils.isSdocFile(fileName) && canModifyRow(record)) {
list.push({ value: OPERATION.GENERATE_SUMMARY, label: gettext('Generate summary') });
}
}
return list;
}, [isGroupView, selectedPosition, recordMetrics, selectedRange, recordGetterByIndex]);
}, [visible, isGroupView, selectedPosition, recordMetrics, selectedRange, metadata, recordGetterByIndex]);
const handleHide = useCallback((event) => {
if (menuRef.current && !menuRef.current.contains(event.target)) {
@@ -89,6 +130,66 @@ const ContextMenu = ({
window.open(url, '_blank');
}, [isGroupView, recordGetterByIndex, selectedPosition]);
const generateSummary = useCallback(() => {
const canModifyRow = window.sfMetadataContext.canModifyRow;
const selectedRecords = Object.keys(recordMetrics.idSelectedRecordMap);
const summaryColumnKey = PRIVATE_COLUMN_KEY.FILE_SUMMARY;
let paths = [];
let idOldRecordData = {};
let idOriginalOldRecordData = {};
if (selectedRange) {
const { topLeft, bottomRight } = selectedRange;
for (let i = topLeft.rowIdx; i <= bottomRight.rowIdx; i++) {
const record = recordGetterByIndex({ isGroupView, groupRecordIndex: topLeft.groupRecordIndex, recordIndex: i });
if (!canModifyRow(record)) continue;
const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME];
if (!Utils.isSdocFile(fileName)) continue;
const parentDir = record[PRIVATE_COLUMN_KEY.PARENT_DIR];
paths.push(Utils.joinPath(parentDir, fileName));
idOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
idOriginalOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
}
} else if (selectedRecords.length > 0) {
selectedRecords.forEach(recordId => {
const record = metadata.id_row_map[recordId];
const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME];
if (Utils.isSdocFile(fileName) && canModifyRow(record)) {
const parentDir = record[PRIVATE_COLUMN_KEY.PARENT_DIR];
paths.push(Utils.joinPath(parentDir, fileName));
idOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
idOriginalOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
}
});
} else if (selectedPosition) {
const { groupRecordIndex, rowIdx } = selectedPosition;
const record = recordGetterByIndex({ isGroupView, groupRecordIndex, recordIndex: rowIdx });
const fileName = record[PRIVATE_COLUMN_KEY.FILE_NAME];
if (Utils.isSdocFile(fileName) && canModifyRow(record)) {
const parentDir = record[PRIVATE_COLUMN_KEY.PARENT_DIR];
paths.push(Utils.joinPath(parentDir, fileName));
idOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
idOriginalOldRecordData[record[PRIVATE_COLUMN_KEY.ID]] = { [summaryColumnKey]: record[summaryColumnKey] };
}
}
if (paths.length === 0) return;
window.sfMetadataContext.generateSummary(paths).then(res => {
const updatedRecords = res.data.rows;
let recordIds = [];
let idRecordUpdates = {};
let idOriginalRecordUpdates = {};
updatedRecords.forEach(updatedRecord => {
const { _id: updateRecordId, _summary } = updatedRecord;
recordIds.push(updateRecordId);
idRecordUpdates[updateRecordId] = { [summaryColumnKey]: _summary };
idOriginalRecordUpdates[updateRecordId] = { [summaryColumnKey]: _summary };
});
updateRecords({ recordIds, idRecordUpdates, idOriginalRecordUpdates, idOldRecordData, idOriginalOldRecordData });
}).catch(error => {
const errorMessage = gettext('Failed to generate summary');
toaster.danger(errorMessage);
});
}, [isGroupView, selectedRange, selectedPosition, recordMetrics, metadata, recordGetterByIndex, updateRecords]);
const handleOptionClick = useCallback((event, option) => {
event.stopPropagation();
switch (option.value) {
@@ -108,12 +209,16 @@ const ContextMenu = ({
onClearSelected && onClearSelected();
break;
}
case OPERATION.GENERATE_SUMMARY: {
generateSummary && generateSummary();
break;
}
default: {
break;
}
}
setVisible(false);
}, [onOpenFileInNewTab, onOpenParentFolder, onCopySelected, onClearSelected]);
}, [onOpenFileInNewTab, onOpenParentFolder, onCopySelected, onClearSelected, generateSummary]);
const getMenuPosition = (x = 0, y = 0) => {
let menuStyles = {