1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-02 07:47:32 +00:00

fix: metadata cv and drag bug (#6532)

Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
杨国璇 2024-08-12 14:24:48 +08:00 committed by GitHub
parent 172ab0d2ad
commit 177e97bb73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 61 additions and 56 deletions

View File

@ -5,18 +5,18 @@ import classnames from 'classnames';
import { Icon } from '@seafile/sf-metadata-ui-component';
import { gettext } from '../../../../utils';
import { CellType, COLUMNS_ICON_CONFIG, PRIVATE_COLUMN_KEY, COLUMNS_ICON_NAME } from '../../../../_basic';
import { getColumnName } from '../../../../utils/column-utils';
import { getColumnDisplayName } from '../../../../utils/column-utils';
import ColumnTypes from './column-types';
import './index.css';
const COLUMNS = [
{ icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], type: CellType.COLLABORATOR, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_COLLABORATORS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.DATE], type: CellType.DATE, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME), unique: true, key: PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.TEXT], type: CellType.TEXT, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_KEYWORDS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_KEYWORDS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], type: CellType.LONG_TEXT, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_SUMMARY), unique: true, key: PRIVATE_COLUMN_KEY.FILE_SUMMARY, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.CHECKBOX], type: CellType.CHECKBOX, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_EXPIRED), unique: true, key: PRIVATE_COLUMN_KEY.FILE_EXPIRED, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], type: CellType.SINGLE_SELECT, name: getColumnName(PRIVATE_COLUMN_KEY.FILE_STATUS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_STATUS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], type: CellType.COLLABORATOR, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_COLLABORATORS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_COLLABORATORS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.DATE], type: CellType.DATE, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME), unique: true, key: PRIVATE_COLUMN_KEY.FILE_EXPIRE_TIME, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.TEXT], type: CellType.TEXT, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_KEYWORDS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_KEYWORDS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.LONG_TEXT], type: CellType.LONG_TEXT, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_SUMMARY), unique: true, key: PRIVATE_COLUMN_KEY.FILE_SUMMARY, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.CHECKBOX], type: CellType.CHECKBOX, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_EXPIRED), unique: true, key: PRIVATE_COLUMN_KEY.FILE_EXPIRED, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.SINGLE_SELECT], type: CellType.SINGLE_SELECT, name: getColumnDisplayName(PRIVATE_COLUMN_KEY.FILE_STATUS), unique: true, key: PRIVATE_COLUMN_KEY.FILE_STATUS, canChangeName: false, groupby: 'predefined' },
{ icon: COLUMNS_ICON_CONFIG[CellType.TEXT], type: CellType.TEXT, name: gettext(COLUMNS_ICON_NAME[CellType.TEXT]), canChangeName: true, key: CellType.TEXT, groupby: 'basics' },
{ icon: COLUMNS_ICON_CONFIG[CellType.CHECKBOX], type: CellType.CHECKBOX, name: gettext(COLUMNS_ICON_NAME[CellType.CHECKBOX]), canChangeName: true, key: CellType.CHECKBOX, groupby: 'basics' },
{ icon: COLUMNS_ICON_CONFIG[CellType.COLLABORATOR], type: CellType.COLLABORATOR, name: gettext(COLUMNS_ICON_NAME[CellType.COLLABORATOR]), canChangeName: true, key: CellType.COLLABORATOR, groupby: 'basics' },

View File

@ -6,7 +6,7 @@ import CheckboxEditor from '../../../../../cell-editor/checkbox-editor';
const Formatter = ({ isCellSelected, isDir, field, value, onChange }) => {
const { type } = field;
if (type === CellType.CHECKBOX && window.sfMetadataContext.canModifyCell(field)) {
if (type === CellType.CHECKBOX && window.sfMetadataContext.canModifyColumn(field)) {
return (<CheckboxEditor isCellSelected={isCellSelected} value={value} field={field} onChange={onChange} />);
}
return (<CellFormatter readonly={true} value={value} field={field} isDir={isDir} />);

View File

@ -27,7 +27,7 @@ const Cell = React.memo(({
}) => {
const className = useMemo(() => {
const { type } = column;
const canEditable = window.sfMetadataContext.canModifyCell(column);
const canEditable = window.sfMetadataContext.canModifyColumn(column);
return classnames('sf-metadata-result-table-cell', `sf-metadata-result-table-${type}-cell`, highlightClassName, {
'table-cell-uneditable': !canEditable || !TABLE_SUPPORT_EDIT_TYPE_MAP[type],
'last-cell': isLastCell,

View File

@ -485,7 +485,7 @@ class InteractionMasks extends React.Component {
// get editable columns from selected range
for (let j = startColumnIdx; j <= endColumnIdx; j++) {
const column = columns[j];
if (!column || NOT_SUPPORT_EDIT_COLUMN_TYPE_MAP[column.type] || !window.sfMetadataContext.canModifyCell(column)) {
if (!column || NOT_SUPPORT_EDIT_COLUMN_TYPE_MAP[column.type] || !window.sfMetadataContext.canModifyColumn(column)) {
break;
}
const { type, data } = column;
@ -1010,7 +1010,7 @@ class InteractionMasks extends React.Component {
selectedPosition,
} = this.state;
const isDragEnabled = this.isSelectedCellEditable();
const canEdit = false;
const canEdit = window.sfMetadataContext.canModifyRows();
const showDragHandle = (isDragEnabled && canEdit);
const column = getSelectedColumn({ selectedPosition, columns });
const { type: columnType } = column || {};
@ -1039,7 +1039,7 @@ class InteractionMasks extends React.Component {
const { columns, rowHeight } = this.props;
const isDragEnabled = this.isSelectedCellEditable();
const canEdit = false;
const canEdit = window.sfMetadataContext.canModifyRows();
const showDragHandle = (isDragEnabled && canEdit);
return [
<SelectionRangeMask

View File

@ -92,20 +92,20 @@ class Context {
return this.permission;
};
canModifyCell = (column) => {
canModifyRow = (row) => {
if (this.permission === 'r') return false;
const { editable } = column;
if (!editable) return false;
return true;
};
canModifyRow = (row) => {
canModifyRows = () => {
if (this.permission === 'r') return false;
return true;
};
canModifyColumn = (column) => {
if (this.permission === 'r') return false;
const { editable } = column;
if (!editable) return false;
if (PRIVATE_COLUMN_KEYS.includes(column.key) && !EDITABLE_PRIVATE_COLUMN_KEYS.includes(column.key)) return false;
return true;
};

View File

@ -1,10 +1,10 @@
import { normalizeColumnData, getColumnName } from '../../utils/column-utils';
import { normalizeColumnData, getColumnDisplayName } from '../../utils/column-utils';
import { CellType, PRIVATE_COLUMN_KEYS, EDITABLE_PRIVATE_COLUMN_KEYS, PRIVATE_COLUMN_KEY } from '../../_basic';
class Column {
constructor(object) {
this.key = object.key || '';
this.name = getColumnName(this.key, object.name) || '';
this.name = getColumnDisplayName(this.key, object.name) || '';
this.type = object.type || '';
this.data = object.data || null;
this.width = object.width || 200;

View File

@ -159,7 +159,7 @@ export const recalculate = (columns, allColumns) => {
};
};
export const getColumnName = (key, name) => {
export const getColumnDisplayName = (key, name) => {
switch (key) {
case PRIVATE_COLUMN_KEY.CTIME:
case PRIVATE_COLUMN_KEY.FILE_CTIME:
@ -200,6 +200,12 @@ export const getColumnName = (key, name) => {
}
};
export const getColumnOriginName = (column) => {
const { key, name } = column;
if (PRIVATE_COLUMN_KEYS.includes(key)) return key;
return name;
};
export const getColumnType = (key, type) => {
switch (key) {
case PRIVATE_COLUMN_KEY.CTIME:
@ -323,7 +329,7 @@ export const normalizeColumns = (columns) => {
export function canEdit(col, record, enableCellSelect) {
if (!col) return false;
if (window.sfMetadataContext.canModifyCell(col) === false) return false;
if (window.sfMetadataContext.canModifyColumn(col) === false) return false;
if (col.editable != null && typeof (col.editable) === 'function') {
return enableCellSelect === true && col.editable(record);
}

View File

@ -1,4 +1,4 @@
import { CellType, DEFAULT_DATE_FORMAT, generatorCellOption, getCollaboratorsName, getOptionName, getDateDisplayString } from '../_basic';
import { CellType, DEFAULT_DATE_FORMAT, generatorCellOption, getCollaboratorsName, getOptionName, getDateDisplayString, PREDEFINED_COLUMN_KEYS } from '../_basic';
import { formatTextToDate } from './date';
import { getFloatNumber, getNumberDisplayString, formatStringToNumber, isNumber } from '../_basic/utils/cell/column/number';
@ -158,7 +158,7 @@ function convert2SingleSelect(cellValue, oldCellValue, fromColumn, targetColumn)
const currentOptions = getSelectColumnOptions(targetColumn);
const newOption = generatorCellOption(currentOptions, fromOptionName);
return newOption.name;
return PREDEFINED_COLUMN_KEYS.includes(targetColumn.key) ? newOption.id : newOption.name;
}
const LONG_TEXT_LENGTH_LIMIT = 10 * 10000;

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs';
import { CellType, NOT_SUPPORT_EDIT_COLUMN_TYPE_MAP } from '../_basic';
import { getColumnByIndex } from './column-utils';
import { CellType, getCellValueByColumn } from '../_basic';
import { getColumnByIndex, getColumnOriginName } from './column-utils';
import { NOT_SUPPORT_DRAG_COPY_COLUMN_TYPES, TRANSFER_TYPES } from '../constants';
import { getGroupRecordByIndex } from './group-metrics';
import { convertCellValue } from './convert-utils';
@ -92,18 +92,19 @@ class GridUtils {
const copiedRecord = copiedRecords[copiedRecordIndex];
let originalUpdate = {};
let originalOldRecordData = {};
const { canModifyRow, canModifyColumn } = window.sfMetadataContext;
for (let j = 0; j < pasteColumnsLen; j++) {
const pasteColumn = getColumnByIndex(j + startColumnIndex, columns);
if (!pasteColumn || NOT_SUPPORT_EDIT_COLUMN_TYPE_MAP[pasteColumn.type]) {
if (!pasteColumn || !(canModifyRow(pasteRecord) && canModifyColumn(pasteColumn))) {
continue;
}
const copiedColumnIndex = j % copiedColumnsLen;
const copiedColumn = getColumnByIndex(copiedColumnIndex, copiedColumns);
const { name: pasteColumnName } = pasteColumn;
const { name: copiedColumnName } = copiedColumn;
const pasteCellValue = Object.prototype.hasOwnProperty.call(pasteRecord, pasteColumnName) ? pasteRecord[pasteColumnName] : null;
const copiedCellValue = Object.prototype.hasOwnProperty.call(copiedRecord, copiedColumnName) ? copiedRecord[copiedColumnName] : null;
const pasteColumnName = getColumnOriginName(pasteColumn);
const copiedColumnName = getColumnOriginName(copiedColumn);
const pasteCellValue = Object.prototype.hasOwnProperty.call(pasteRecord, pasteColumnName) ? getCellValueByColumn(pasteRecord, pasteColumn) : null;
const copiedCellValue = Object.prototype.hasOwnProperty.call(copiedRecord, copiedColumnName) ? getCellValueByColumn(copiedRecord, copiedColumn) : null;
const update = convertCellValue(copiedCellValue, pasteCellValue, pasteColumn, copiedColumn);
if (update === pasteCellValue) {
continue;
@ -166,45 +167,44 @@ class GridUtils {
const updatedRows = {};
const oldRows = {};
const { overRecordIdx, topLeft, bottomRight } = draggedRange;
let { idx: startColumnIdx } = topLeft;
let { idx: endColumnIdx, rowIdx: endRecordIdx, groupRecordIndex } = bottomRight;
const { idx: startColumnIdx } = topLeft;
const { idx: endColumnIdx, rowIdx: endRecordIdx, groupRecordIndex } = bottomRight;
const { canModifyRow, canModifyColumn } = window.sfMetadataContext;
let draggedRangeMatrix = this.getdraggedRangeMatrix(shownColumns, draggedRange, rows, groupMetrics, idRowMap);
let rules = this.getDraggedRangeRules(draggedRangeMatrix, shownColumns, startColumnIdx);
const draggedRangeMatrix = this.getDraggedRangeMatrix(shownColumns, draggedRange, rows, groupMetrics, idRowMap);
const rules = this.getDraggedRangeRules(draggedRangeMatrix, shownColumns, startColumnIdx);
const selectedRowLength = draggedRangeMatrix[0].length;
let fillingIndex = draggedRangeMatrix[0].length;
// if group view then use index of gropRows which is different from the normal rows(they represent DOMs)
// if group view then use index of groupRows which is different from the normal rows(they represent DOMs)
let currentGroupRowIndex = groupRecordIndex + 1;
for (let i = endRecordIdx + 1; i <= overRecordIdx; i++) {
let dragRow;
// find the row that need to be updated (it's draged)
// find the row that need to be updated (it's dragged)
if (currentGroupRowIndex) {
const groupRow = getGroupRecordByIndex(currentGroupRowIndex, groupMetrics);
dragRow = idRowMap[groupRow.rowId];
} else {
dragRow = rows[i];
}
let { _id: dragRowId, _locked } = dragRow;
const { _id: dragRowId } = dragRow;
fillingIndex++;
if (_locked) continue;
if (!canModifyRow(dragRow)) continue;
rowIds.push(dragRowId);
let idx = (i - endRecordIdx - 1) % selectedRowLength;
const idx = (i - endRecordIdx - 1) % selectedRowLength;
for (let j = startColumnIdx; j <= endColumnIdx; j++) {
let column = shownColumns[j];
let { key: cellKey, type, editable } = column;
if (editable && !NOT_SUPPORT_EDIT_COLUMN_TYPE_MAP[type] && !NOT_SUPPORT_DRAG_COPY_COLUMN_TYPES.includes(type)) {
let value = draggedRangeMatrix[j - startColumnIdx][idx];
let rule = rules[cellKey];
let fillingValue = rule({ n: fillingIndex - 1, value });
updatedOriginalRows[dragRowId] = Object.assign({}, updatedOriginalRows[dragRowId], { [cellKey]: fillingValue });
oldOriginalRows[dragRowId] = Object.assign({}, oldOriginalRows[dragRowId], { [cellKey]: dragRow[cellKey] });
// update: {[name]: value}
// originalUpdate: {[key]: id}
let { key: cellKey, type } = column;
const columnName = getColumnOriginName(column);
if (canModifyColumn(column) && !NOT_SUPPORT_DRAG_COPY_COLUMN_TYPES.includes(type)) {
const value = draggedRangeMatrix[j - startColumnIdx][idx];
const rule = rules[cellKey];
const fillingValue = rule({ n: fillingIndex - 1, value });
updatedOriginalRows[dragRowId] = Object.assign({}, updatedOriginalRows[dragRowId], { [columnName]: fillingValue });
oldOriginalRows[dragRowId] = Object.assign({}, oldOriginalRows[dragRowId], { [columnName]: dragRow[columnName] });
const update = updatedOriginalRows[dragRowId];
const oldUpdate = oldOriginalRows[dragRowId];
@ -218,16 +218,15 @@ class GridUtils {
return { recordIds: rowIds, idOriginalRecordUpdates: updatedOriginalRows, idRecordUpdates: updatedRows, idOriginalOldRecordData: oldOriginalRows, idOldRecordData: oldRows };
}
getdraggedRangeMatrix(columns, draggedRange, rows, groupMetrics, idRowMap) {
getDraggedRangeMatrix(columns, draggedRange, rows, groupMetrics, idRowMap) {
let draggedRangeMatrix = [];
let { topLeft, bottomRight } = draggedRange;
let { idx: startColumnIdx, rowIdx: startRowIdx, groupRecordIndex } = topLeft;
let { idx: endColumnIdx, rowIdx: endRowIdx } = bottomRight;
const { topLeft, bottomRight } = draggedRange;
const { idx: startColumnIdx, rowIdx: startRowIdx, groupRecordIndex } = topLeft;
const { idx: endColumnIdx, rowIdx: endRowIdx } = bottomRight;
for (let i = startColumnIdx; i <= endColumnIdx; i++) {
let currentGroupRecordIndex = groupRecordIndex;
draggedRangeMatrix[i - startColumnIdx] = [];
let column = columns[i];
let { key } = column;
const column = columns[i];
for (let j = startRowIdx; j <= endRowIdx; j++) {
let selectedRecord;
if (currentGroupRecordIndex) {
@ -236,7 +235,7 @@ class GridUtils {
} else {
selectedRecord = rows[j];
}
draggedRangeMatrix[i - startColumnIdx][j - startRowIdx] = selectedRecord[key];
draggedRangeMatrix[i - startColumnIdx][j - startRowIdx] = getCellValueByColumn(selectedRecord, column);
currentGroupRecordIndex++;
}
}