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:
parent
172ab0d2ad
commit
177e97bb73
@ -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' },
|
||||
|
@ -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} />);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user