фикс плывущей таблицы
This commit is contained in:
parent
5cc07c7704
commit
d1d1f90268
@ -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}
|
||||||
|
|||||||
@ -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}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -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',
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
export const columnPinningDefault = {
|
||||||
|
left: ["mrt-row-expand", "sort_order"],
|
||||||
|
right: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const columnVisibilityDefault = { "mrt-row-select": false };
|
||||||
@ -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),
|
||||||
|
|||||||
@ -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(() => {
|
||||||
|
|||||||
@ -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>
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user