1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-24 04:48:03 +00:00
Files
seahub/frontend/src/components/sf-table/utils/selected-cell-utils.js
2025-01-07 12:17:57 +08:00

197 lines
7.7 KiB
JavaScript

// import { Utils } from '../../../utils/utils';
import { CELL_MASK as Z_INDEX_CELL_MASK, FROZEN_CELL_MASK as Z_INDEX_FROZEN_CELL_MASK } from '../constants/z-index';
import { getCellValueByColumn } from './cell';
import { checkIsColumnEditable, checkIsColumnSupportPreview, getColumnByIndex } from './column';
import { getGroupByPath } from './group';
import { getGroupRecordByIndex } from './group-metrics';
const SELECT_DIRECTION = {
UP: 'upwards',
DOWN: 'downwards',
};
export const getRowTop = (rowIdx, rowHeight) => rowIdx * rowHeight;
export const getSelectedRow = ({ selectedPosition, isGroupView, recordGetterByIndex }) => {
const { groupRecordIndex, rowIdx } = selectedPosition;
return recordGetterByIndex({ isGroupView, groupRecordIndex, recordIndex: rowIdx });
};
export const getSelectedColumn = ({ selectedPosition, columns }) => {
const { idx } = selectedPosition;
return getColumnByIndex(idx, columns);
};
export const getSelectedCellValue = ({ selectedPosition, columns, isGroupView, recordGetterByIndex }) => {
const column = getSelectedColumn({ selectedPosition, columns });
const record = getSelectedRow({ selectedPosition, isGroupView, recordGetterByIndex });
return getCellValueByColumn(record, column);
};
export const checkIsCellSupportOpenEditor = (cell, column, isGroupView, recordGetterByIndex, checkCanModifyRecord) => {
const { groupRecordIndex, rowIdx } = cell;
if (!column) return false;
// open the editor to preview cell value
if (checkIsColumnSupportPreview(column)) {
return true;
}
if (!checkIsColumnEditable(column)) {
return false;
}
const record = recordGetterByIndex({ isGroupView, groupRecordIndex, recordIndex: rowIdx });
if (!record || !checkCanModifyRecord) return false;
return !!checkCanModifyRecord(record);
};
export const checkIsSelectedCellEditable = ({ enableCellSelect, selectedPosition, columns, isGroupView, recordGetterByIndex, checkCanModifyRecord }) => {
const column = getSelectedColumn({ selectedPosition, columns });
if (!checkIsColumnEditable(column)) {
return false;
}
const row = getSelectedRow({ selectedPosition, isGroupView, recordGetterByIndex });
if (!row || !checkCanModifyRecord) {
return false;
}
return checkCanModifyRecord(row);
};
export function selectedRangeIsSingleCell(selectedRange) {
const { topLeft, bottomRight } = selectedRange;
if (
topLeft.idx !== bottomRight.idx ||
topLeft.rowIdx !== bottomRight.rowIdx
) {
return false;
}
return true;
}
export const getSelectedDimensions = ({
selectedPosition, columns, rowHeight, scrollLeft, isGroupView, groupOffsetLeft,
getRecordTopFromRecordsBody,
}) => {
const { idx, rowIdx, groupRecordIndex } = selectedPosition;
const defaultDimensions = { width: 0, left: 0, top: 0, height: rowHeight, zIndex: 1 };
if (idx >= 0) {
const column = columns && columns[idx];
if (!column) {
return defaultDimensions;
}
const { frozen, width } = column;
let left = frozen ? scrollLeft + column.left : column.left;
let top;
if (isGroupView) {
left += groupOffsetLeft;
// group view uses border-top, No group view uses border-bottom (for group animation) so selected top should be increased 1
top = getRecordTopFromRecordsBody(groupRecordIndex) + 1;
} else {
top = getRecordTopFromRecordsBody(rowIdx);
}
const zIndex = frozen ? Z_INDEX_FROZEN_CELL_MASK : Z_INDEX_CELL_MASK;
return { width, left, top, height: rowHeight, zIndex };
}
return defaultDimensions;
};
export function getNewSelectedRange(startCell, nextCellPosition) {
const { idx: currentIdx, rowIdx: currentRowIdx, groupRecordIndex: currentGroupRecordIndex } = startCell;
const { idx: newIdx, rowIdx: newRowIdx, groupRecordIndex: newGroupRecordIndex } = nextCellPosition;
const colIndexes = [currentIdx, newIdx].sort((a, b) => a - b);
const rowIndexes = [currentRowIdx, newRowIdx].sort((a, b) => a - b);
const groupRecordIndexes = [currentGroupRecordIndex, newGroupRecordIndex].sort((a, b) => a - b);
const topLeft = { idx: colIndexes[0], rowIdx: rowIndexes[0], groupRecordIndex: groupRecordIndexes[0] };
const bottomRight = { idx: colIndexes[1], rowIdx: rowIndexes[1], groupRecordIndex: groupRecordIndexes[1] };
return { topLeft, bottomRight };
}
const getColumnRangeProperties = (from, to, columns) => {
let totalWidth = 0;
let anyColFrozen = false;
for (let i = from; i <= to; i++) {
const column = columns[i];
if (column) {
totalWidth += column.width;
anyColFrozen = anyColFrozen || column.frozen;
}
}
return { totalWidth, anyColFrozen, left: columns[from].left };
};
export const getSelectedRangeDimensions = ({
selectedRange, columns, rowHeight, isGroupView, groups, groupMetrics,
groupOffsetLeft, getRecordTopFromRecordsBody,
}) => {
const { topLeft, bottomRight, startCell, cursorCell } = selectedRange;
if (topLeft.idx < 0) {
return { width: 0, left: 0, top: 0, height: rowHeight, zIndex: Z_INDEX_CELL_MASK };
}
let { totalWidth, anyColFrozen, left } = getColumnRangeProperties(topLeft.idx, bottomRight.idx, columns);
let height;
let top;
if (isGroupView) {
let { groupRecordIndex: startGroupRecordIndex } = startCell;
let { groupRecordIndex: endGroupRecordIndex } = cursorCell;
const startGroupRow = getGroupRecordByIndex(startGroupRecordIndex, groupMetrics);
const endGroupRow = getGroupRecordByIndex(endGroupRecordIndex, groupMetrics);
const startGroupPathString = startGroupRow.groupPathString;
const endGroupPathString = endGroupRow.groupPathString;
let topGroupRowIndex;
let selectDirection;
if (startGroupRecordIndex < endGroupRecordIndex) {
topGroupRowIndex = startGroupRecordIndex;
selectDirection = SELECT_DIRECTION.DOWN;
} else {
topGroupRowIndex = endGroupRecordIndex;
selectDirection = SELECT_DIRECTION.UP;
}
if (startGroupPathString === endGroupPathString) {
// within the same group.
height = (Math.abs(endGroupRecordIndex - startGroupRecordIndex) + 1) * rowHeight;
} else if (selectDirection === SELECT_DIRECTION.DOWN) {
// within different group: select cells from top to bottom.
const groupPath = startGroupRow.groupPath;
const group = getGroupByPath(groupPath, groups);
const groupRowIds = group.row_ids || [];
height = (groupRowIds.length - startGroupRow.rowIdx || 0) * rowHeight;
} else if (selectDirection === SELECT_DIRECTION.UP) {
// within different group: select cells from bottom to top.
const startGroupRowIdx = startGroupRow.rowIdx || 0;
topGroupRowIndex = startGroupRecordIndex - startGroupRowIdx;
height = (startGroupRowIdx + 1) * rowHeight;
}
height += 1; // record height: 32
left += groupOffsetLeft;
top = getRecordTopFromRecordsBody(topGroupRowIndex);
} else {
height = (bottomRight.rowIdx - topLeft.rowIdx + 1) * rowHeight;
top = getRecordTopFromRecordsBody(topLeft.rowIdx);
}
const zIndex = anyColFrozen ? Z_INDEX_FROZEN_CELL_MASK : Z_INDEX_CELL_MASK;
return { width: totalWidth, left, top, height, zIndex };
};
export const getRecordsFromSelectedRange = ({ selectedRange, isGroupView, recordGetterByIndex }) => {
const { topLeft, bottomRight } = selectedRange;
const { rowIdx: startRecordIdx, groupRecordIndex } = topLeft;
const { rowIdx: endRecordIdx } = bottomRight;
let currentGroupRowIndex = groupRecordIndex;
let records = [];
for (let recordIndex = startRecordIdx, endIdx = endRecordIdx + 1; recordIndex < endIdx; recordIndex++) {
const record = recordGetterByIndex({ isGroupView, groupRecordIndex: currentGroupRowIndex, recordIndex });
if (isGroupView) {
currentGroupRowIndex++;
}
if (record) {
records.push(record);
}
}
return records;
};