Merge pull request 'фикс плывущей таблицы' (#59) from fix-front into test

Reviewed-on: #59
This commit is contained in:
PotapovaA 2026-06-22 10:20:15 +03:00
commit d2b1b3a4d0
8 changed files with 49 additions and 24 deletions

View File

@ -63,6 +63,18 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
handleToggleColumnVisibility, handleToggleColumnVisibility,
} = useColumnSettings(); } = useColumnSettings();
useEffect(() => {
// Принудительно обновляем состояние закрепленных колонок
// если так не сделать при скролле будут пропадать закрепленные колонки
if (columnPinning && Object.keys(columnPinning).length > 0) {
const timer = setTimeout(() => {
setColumnPinning(prev => ({ ...prev }));
}, 10);
return () => clearTimeout(timer);
}
}, [columnPinning, setColumnPinning]);
const { headerPortalRef, containerRef } = useHeaderPortal(); const { headerPortalRef, containerRef } = useHeaderPortal();
const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } = const { sizeMult, setSizeMult, tableScaleStyle, tableWrapperStyle } =
@ -153,7 +165,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
rowSelection, rowSelection,
}, },
initialState: { initialState: {
expanded: true expanded: true,
}, },
meta: tableMeta, meta: tableMeta,
muiTableHeadCellProps: { muiTableHeadCellProps: {
@ -240,6 +252,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction }) => {
<SettingsPanel <SettingsPanel
selectedColumn={selectedColumn} selectedColumn={selectedColumn}
table={table} table={table}
columns={columns}
onPinColumn={handlePinColumn} onPinColumn={handlePinColumn}
onUnpinColumn={handleUnpinColumn} onUnpinColumn={handleUnpinColumn}
onToggleColumnVisibility={handleToggleColumnVisibility} onToggleColumnVisibility={handleToggleColumnVisibility}

View File

@ -23,6 +23,7 @@ import { exportSheet } from '../../../utils/exportForm';
const SettingPanel = ({ const SettingPanel = ({
selectedColumn, selectedColumn,
table, table,
columns,
onPinColumn, onPinColumn,
onUnpinColumn, onUnpinColumn,
onToggleColumnVisibility, onToggleColumnVisibility,
@ -40,16 +41,9 @@ const SettingPanel = ({
}) => { }) => {
const [isPinned, setIsPinned] = useState(false); const [isPinned, setIsPinned] = useState(false);
const [isExporting, setIsExporting] = useState(false); const [isExporting, setIsExporting] = useState(false);
const [columnTree, setColumnTree] = useState();
const [selectedColumnIds, setSelectedColumnIds] = useState(); const [selectedColumnIds, setSelectedColumnIds] = useState();
const [showColumnFilters, setShowColumnFilters] = useState(false); const [showColumnFilters, setShowColumnFilters] = useState(false);
useEffect(() => {
if (!table) return;
setColumnTree(table.getAllColumns());
setShowColumnFilters(table.getState().showColumnFilters);
}, [table, isLoadingData]);
useEffect(() => { useEffect(() => {
if (!selectedColumn) return; if (!selectedColumn) return;
const pinningColumn = table.getState().columnPinning.left; const pinningColumn = table.getState().columnPinning.left;
@ -141,9 +135,9 @@ const SettingPanel = ({
</GroupByObject> </GroupByObject>
<Divider orientation="vertical" flexItem /> <Divider orientation="vertical" flexItem />
<GroupByObject title="Столбцы"> <GroupByObject title="Столбцы">
{columnTree ? ( {columns ? (
<CollapsibleTree <CollapsibleTree
columnTree={columnTree} columnTree={columns}
onSelectNode={onToggleColumnVisibility} onSelectNode={onToggleColumnVisibility}
selectedIds={selectedColumnIds} selectedIds={selectedColumnIds}
/> />

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import ColumnResizer from './ColumnResizer'; import ColumnResizer from './ColumnResizer';
import { columnPinningDefault } from '../constants/columnConfig';
const getSortedColumns = (table) => { const getSortedColumns = (table) => {
const allLeafColumns = table.getAllLeafColumns(); const allLeafColumns = table.getAllLeafColumns();
@ -18,9 +19,20 @@ const getSortedColumns = (table) => {
}); });
}; };
const getColumnId = (header) => {
//в header.id содержаться колонки по типу depth_idColParent_idChild, а в pinningColumn только idCol, которые закреплены
//header.id.split('_').at(-1) - получение самой нижней колонки
let columnId = header?.id?.match(/data\..*$/)?.[0] || header?.id || header;
columnPinningDefault.left.forEach(colPinned => {
if (columnId.includes(colPinned)) {
columnId = colPinned;
}
})
return columnId;
}
const calculateLeftOffset = (table, columnOrHeader) => { const calculateLeftOffset = (table, columnOrHeader) => {
const columnId = const columnId = getColumnId(columnOrHeader);
columnOrHeader.id.match(/data\..*$/)?.[0] || columnOrHeader.id;
const pinnedColumns = table.getState().columnPinning.left || []; const pinnedColumns = table.getState().columnPinning.left || [];
const currentPinnedIndex = pinnedColumns.indexOf(columnId); const currentPinnedIndex = pinnedColumns.indexOf(columnId);
@ -40,12 +52,11 @@ const calculateLeftOffset = (table, columnOrHeader) => {
const isColumnPin = (table, header) => { const isColumnPin = (table, header) => {
const pinningColumn = table.getState().columnPinning.left; const pinningColumn = table.getState().columnPinning.left;
//в header.id содержаться колонки по типу depth_idColParent_idChild, а в pinningColumn только idCol, которые закреплены const columnId = getColumnId(header);
//header.id.split('_').at(-1) - получение самой нижней колонки
const columnId = header.id.match(/data\..*$/)?.[0] || header.id;
const isPinned = pinningColumn.includes(columnId); const isPinned = pinningColumn.includes(columnId);
return isPinned; return isPinned;
}; };
const ColumnNumbersRow = ({ table }) => { const ColumnNumbersRow = ({ table }) => {
const sortedColumns = getSortedColumns(table); const sortedColumns = getSortedColumns(table);
const tableState = table.getState(); const tableState = table.getState();
@ -91,7 +102,7 @@ const ColumnNumberCell = ({ column, table }) => {
maxWidth: column.getSize(), maxWidth: column.getSize(),
padding: '2px 6px', padding: '2px 6px',
textAlign: 'center', textAlign: 'center',
backgroundColor: isPinned ? '#f5f5f5' : '#F3F4F6', backgroundColor: '#e5e5e5',
boxSizing: 'border-box', boxSizing: 'border-box',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',

View File

@ -0,0 +1,6 @@
export const columnPinningDefault = {
left: ["mrt-row-expand", "sort_order"],
right: [],
};
export const columnVisibilityDefault = { "mrt-row-select": false };

View File

@ -1,16 +1,17 @@
import { useState, useEffect, useCallback } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { loadFromStorage, saveToStorage } from '../utils/localStorageUtils.js'; import { loadFromStorage, saveToStorage } from '../utils/localStorageUtils.js';
import { getLeafColumns, collectLeafColumns } from '../utils/columnUtils'; import { getLeafColumns, collectLeafColumns } from '../utils/columnUtils';
import { columnPinningDefault, columnVisibilityDefault } from '../constants/columnConfig.js';
export const useColumnSettings = () => { export const useColumnSettings = () => {
const [columnSizing, setColumnSizing] = useState(() => const [columnSizing, setColumnSizing] = useState(() =>
loadFromStorage('columnSizing', {}), loadFromStorage('columnSizing', {}),
); );
const [columnPinning, setColumnPinning] = useState(() => const [columnPinning, setColumnPinning] = useState(() =>
loadFromStorage('columnPinning', { left: [], right: [] }), loadFromStorage('columnPinning', columnPinningDefault),
); );
const [columnVisibility, setColumnVisibility] = useState(() => const [columnVisibility, setColumnVisibility] = useState(() =>
loadFromStorage('columnVisibility', { }), loadFromStorage('columnVisibility', columnVisibilityDefault),
); );
// Сохранение в localStorage // Сохранение в localStorage
@ -31,6 +32,7 @@ export const useColumnSettings = () => {
}, []); }, []);
const handleUnpinColumn = useCallback((colId) => { const handleUnpinColumn = useCallback((colId) => {
if (columnPinningDefault.left.includes(colId)) return;
setColumnPinning((prev) => ({ setColumnPinning((prev) => ({
...prev, ...prev,
left: prev.left.filter((c) => c !== colId), left: prev.left.filter((c) => c !== colId),

View File

@ -4,7 +4,7 @@ import { rowBaseOffset } from "../constants/tableConfig";
export const useTableScale = () => { export const useTableScale = () => {
const [sizeMult, setSizeMult] = useState(() => const [sizeMult, setSizeMult] = useState(() =>
loadFromStorage("sizeMult", 1.5), loadFromStorage("sizeMult", 1),
); );
useEffect(() => { useEffect(() => {

View File

@ -136,12 +136,11 @@ export const getTableColumns = ({
const rowNumber = { const rowNumber = {
accessorKey: 'sort_order', accessorKey: 'sort_order',
header: '#', header: '#',
size: 70, size: 50,
enableEditing: false, enableEditing: false,
enablePinning: true,
Cell: ({ cell, row }) => { Cell: ({ cell, row }) => {
return <button onClick={() => { console.log('TEST', row.id); onCellNumberClick(row.id) }}> return <button onClick={() => { onCellNumberClick(row.id) }}>
{cell.getValue()} {cell.getValue()+ ' '}
</button> </button>
}, },
}; };

View File

@ -144,7 +144,7 @@ const CollapsibleTree = ({
setAnchorEl(null); setAnchorEl(null);
}; };
const selectedCount = selectedNodes.length; const selectedCount = selectedNodes.length - 1; //1 колонка всегда скрыта
const isAllSelected = () => { const isAllSelected = () => {
if (!columnTree) return false; if (!columnTree) return false;