правки #47
@ -23,7 +23,7 @@ const FORMULA_INDICATOR_STYLES = {
|
||||
|
||||
const TEXTAREA_STYLES = {
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
height: '3rem',
|
||||
fieldSizing: 'content',
|
||||
fontSize: 'inherit',
|
||||
};
|
||||
@ -32,7 +32,6 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
const { endEditing: contextEndEditing } = useRealtime();
|
||||
const storageKey = `formula_${tableId}_${cellId}`;
|
||||
|
||||
// Объединенное состояние
|
||||
const [state, setState] = useState(() => ({
|
||||
currentValue: value,
|
||||
displayValue: value,
|
||||
@ -40,7 +39,7 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
}));
|
||||
|
||||
// Позиция ячейки
|
||||
const [position, setPosition] = useState({ left: 0, width: 0, translateY: '' });
|
||||
const [position, setPosition] = useState();
|
||||
const textareaRef = useRef(null);
|
||||
|
||||
const refFinished = useRef(false);
|
||||
@ -89,8 +88,8 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
if (!el) return;
|
||||
|
||||
const resize = () => {
|
||||
el.style.height = 'auto';
|
||||
el.style.minHeight = '3rem';
|
||||
el.style.height = '3rem';
|
||||
el.style.height = el.scrollHeight + 'px';
|
||||
el.style.maxHeight = '180px';
|
||||
};
|
||||
@ -102,16 +101,6 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
return () => observer.disconnect();
|
||||
}, [state.currentValue]);
|
||||
|
||||
// Фокус при монтировании
|
||||
useEffect(() => {
|
||||
const el = textareaRef.current;
|
||||
if (el && !disabled) {
|
||||
el.focus();
|
||||
el.setSelectionRange(el.value.length, el.value.length);
|
||||
}
|
||||
}, [disabled]);
|
||||
|
||||
// Сохранение
|
||||
const handleSave = useCallback(() => {
|
||||
const { currentValue } = state;
|
||||
|
||||
@ -146,7 +135,6 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
}
|
||||
}, [state, storageKey, onChange]);
|
||||
|
||||
// Завершение редактирования
|
||||
const finishEditing = useCallback(() => {
|
||||
if (refFinished.current) return;
|
||||
refFinished.current = true;
|
||||
@ -170,7 +158,6 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside);
|
||||
}, [finishEditing]);
|
||||
|
||||
// Обработчики событий
|
||||
const handleChange = useCallback((e) => {
|
||||
const value = e.target.value;
|
||||
setState(prev => ({
|
||||
@ -187,12 +174,11 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
}
|
||||
}, [finishEditing]);
|
||||
|
||||
// Мемоизация стилей
|
||||
const editorStyles = useMemo(() => ({
|
||||
...EDITOR_STYLES,
|
||||
left: position.left,
|
||||
width: position.width,
|
||||
transform: position.translateY,
|
||||
left: position?.left || 0,
|
||||
width: position?.width || 0,
|
||||
transform: position?.translateY || 0,
|
||||
}), [position]);
|
||||
|
||||
const textareaStyles = useMemo(() => ({
|
||||
@ -204,6 +190,7 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
return (
|
||||
<tr>
|
||||
<td>
|
||||
{position &&
|
||||
<div style={editorStyles}>
|
||||
{state.isFormulaMode && (
|
||||
<div style={FORMULA_INDICATOR_STYLES}>fx</div>
|
||||
@ -218,6 +205,8 @@ const EditCell = memo(({ refCell, onChange, disabled, value, tableId, cellId, ta
|
||||
placeholder={state.isFormulaMode ? 'Введите формулу (начинается с =)' : ''}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
// components/RealtimeTable/index.js
|
||||
import React, { useState, useMemo, useRef, useEffect, useCallback, useTransition } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import {
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
// getTableColumns.js
|
||||
import React, { useEffect, useRef, useState, useMemo, useCallback } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useParams } from 'react-router';
|
||||
import { useRealtime } from './contexts/RealtimeContext';
|
||||
|
||||
// Мемоизированный компонент EditCellPortal
|
||||
const EditCellPortal = React.memo(({
|
||||
cell,
|
||||
table,
|
||||
@ -22,7 +20,6 @@ const EditCellPortal = React.memo(({
|
||||
|
||||
const { endEditing: contextEndEditing } = useRealtime();
|
||||
|
||||
// Оптимизация: вычисляем позицию только при монтировании и изменении cell
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const tbodyRef = ref.current.offsetParent?.offsetParent?.offsetParent;
|
||||
@ -30,9 +27,8 @@ const EditCellPortal = React.memo(({
|
||||
setRefTbody(tbodyRef);
|
||||
}
|
||||
}
|
||||
}, [refTbody]); // Добавляем refTbody в зависимости
|
||||
}, []);
|
||||
|
||||
// Мемоизация обработчика изменения
|
||||
const handleChange = useCallback( (val) => {
|
||||
table.setEditingCell(null);
|
||||
try {
|
||||
@ -53,7 +49,6 @@ const EditCellPortal = React.memo(({
|
||||
}
|
||||
}, [table, cell, onError]);
|
||||
|
||||
// Мемоизация пропсов для EditCell
|
||||
const editCellProps = useMemo(() => ({
|
||||
refCell: ref,
|
||||
cell,
|
||||
@ -65,7 +60,6 @@ const EditCellPortal = React.memo(({
|
||||
cellId: `${cell.row.id}_${cell.column.id}`,
|
||||
}), [cell, isEditable, handleChange, tableKey, table]);
|
||||
|
||||
// Мемоизация портала
|
||||
const portalContent = useMemo(() => {
|
||||
if (!refTbody || isSaving) return null;
|
||||
return createPortal(
|
||||
@ -82,9 +76,7 @@ const EditCellPortal = React.memo(({
|
||||
);
|
||||
});
|
||||
|
||||
EditCellPortal.displayName = 'EditCellPortal';
|
||||
|
||||
// Основная функция getTableColumns
|
||||
export const getTableColumns = ({
|
||||
Cell,
|
||||
EditCell,
|
||||
@ -95,11 +87,9 @@ export const getTableColumns = ({
|
||||
const columnColors = { ...columnsConfig.colors };
|
||||
const columns = structuredClone(columnsConfig.columns);
|
||||
|
||||
// Кэши для вычисленных значений
|
||||
const cellPropsCache = new WeakMap();
|
||||
const editPropsCache = new WeakMap();
|
||||
|
||||
// Функция для получения кешированных пропсов Cell
|
||||
const getCachedCellProps = (row, column, table) => {
|
||||
const key = `${row.id}_${column.id}`;
|
||||
|
||||
@ -109,7 +99,6 @@ export const getTableColumns = ({
|
||||
|
||||
const rowCache = cellPropsCache.get(row);
|
||||
if (rowCache[key]) {
|
||||
// Проверяем, не изменились ли фильтры
|
||||
const cached = rowCache[key];
|
||||
const currentGlobalFilter = table.getState().globalFilter;
|
||||
const currentColumnFilter = table.getState().columnFilters?.find(f => f.id === column.id)?.value;
|
||||
@ -136,7 +125,6 @@ export const getTableColumns = ({
|
||||
return props;
|
||||
};
|
||||
|
||||
// Функция для получения кешированных пропсов Edit
|
||||
const getCachedEditProps = (row, column, table) => {
|
||||
const key = `${row.id}_${column.id}`;
|
||||
|
||||
@ -160,11 +148,9 @@ export const getTableColumns = ({
|
||||
// Оптимизированная функция processColumns
|
||||
const processColumns = (columns) => {
|
||||
columns.forEach((col) => {
|
||||
// Оптимизированный Cell
|
||||
col.Cell = ({ cell, table, column, row }) => {
|
||||
const props = getCachedCellProps(row, column, table);
|
||||
|
||||
// Используем useMemo для мемоизации пропсов
|
||||
const cellProps = useMemo(() => ({
|
||||
row,
|
||||
column,
|
||||
@ -175,11 +161,9 @@ export const getTableColumns = ({
|
||||
return <Cell {...cellProps} />;
|
||||
};
|
||||
|
||||
// Оптимизированный Edit
|
||||
col.Edit = ({ cell, table, row, column }) => {
|
||||
const props = getCachedEditProps(row, column, table);
|
||||
|
||||
// Мемоизируем компонент EditCellPortal
|
||||
const editComponent = useMemo(() => (
|
||||
<EditCellPortal
|
||||
cell={cell}
|
||||
@ -193,7 +177,6 @@ export const getTableColumns = ({
|
||||
return editComponent;
|
||||
};
|
||||
|
||||
// Рекурсивно обрабатываем вложенные колонки
|
||||
if (col.columns?.length) {
|
||||
processColumns(col.columns);
|
||||
}
|
||||
@ -202,7 +185,6 @@ export const getTableColumns = ({
|
||||
|
||||
processColumns(columns);
|
||||
|
||||
// Оптимизированная колонка с номерами строк
|
||||
const rowNumber = {
|
||||
accessorKey: 'sort_order',
|
||||
header: '#',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user