Compare commits

..

No commits in common. "b4ba58a8d859ced4019056e58be8e94e3791172d" and "78a7628b238ea4c9182a204f8edaf2a13d1adc4f" have entirely different histories.

9 changed files with 5297 additions and 5517 deletions

62
web/package-lock.json generated
View File

@ -84,6 +84,19 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
"integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.29.7",
"@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
@ -140,6 +153,24 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
"integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.29.7",
"@babel/generator": "^7.29.7",
"@babel/helper-globals": "^7.29.7",
"@babel/parser": "^7.29.7",
"@babel/template": "^7.29.7",
"@babel/types": "^7.29.7",
"debug": "^4.3.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
@ -392,37 +423,6 @@
"stylis": "4.2.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/@babel/helper-module-imports": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.27.1",
"@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emotion/babel-plugin/node_modules/@babel/traverse": {
"version": "7.28.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
"@babel/helper-globals": "^7.28.0",
"@babel/parser": "^7.28.5",
"@babel/template": "^7.27.2",
"@babel/types": "^7.28.5",
"debug": "^4.3.1"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emotion/cache": {
"version": "11.14.0",
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",

View File

@ -32,9 +32,5 @@
"daisyui": "^4.12.10",
"tailwindcss": "^3.4.13",
"typescript": "^5.7.3"
},
"overrides": {
"@babel/helper-module-imports": "7.27.1",
"@babel/traverse": "7.28.5"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,6 @@ const RealtimeConnectionContext = createContext(null);
const RealtimeVspOptionsContext = createContext(null);
const LockedCellsStoreContext = createContext(null);
const getColumnRequestKey = (column) => {
const columnKey = column?.columnDef?.id ?? column?.id;
if (columnKey === null || columnKey === undefined) return '';
const normalizedColumnKey = String(columnKey);
return normalizedColumnKey.startsWith('data.') ? normalizedColumnKey.slice(5) : normalizedColumnKey;
};
const useRequiredContext = (context, hookName) => {
const value = useContext(context);
if (value === null) {
@ -246,19 +238,21 @@ export const RealtimeProvider = ({ children, formId, sheetName, direction, year,
// Функция для начала редактирования ячейки
const startEditing = useCallback(
(row, column) => {
const columnId = column.id;
if (!isConnectedRef.current) {
onErrorRef.current?.('WebSocket не подключен');
return false;
}
const lineId = row.id || null;
const columnKey = getColumnRequestKey(column);
const colId = columnId.slice(5); // убираем префикс "data."
const message = {
event: 'cell_edit_start',
data: {
line_id: lineId,
column: columnKey,
column: colId,
},
};
@ -275,19 +269,21 @@ export const RealtimeProvider = ({ children, formId, sheetName, direction, year,
// Функция для завершения редактирования ячейки
const endEditing = useCallback(
(row, column) => {
const columnId = column.id;
if (!isConnectedRef.current) {
onErrorRef.current?.('WebSocket не подключен');
return false;
}
const lineId = row.id || null;
const columnKey = getColumnRequestKey(column);
const colId = columnId.slice(5);
const message = {
event: 'cell_edit_end',
data: {
line_id: lineId,
column: columnKey,
column: colId,
},
};
@ -303,19 +299,20 @@ export const RealtimeProvider = ({ children, formId, sheetName, direction, year,
const updateCell = useCallback(
(row, column, value) => {
const columnId = column.id;
if (!isConnectedRef.current) {
onErrorRef.current?.('WebSocket не подключен');
return false;
}
const lineId = getRowId(row);
const columnKey = getColumnRequestKey(column);
const colId = columnId.slice(5);
const message = {
event: 'cell_updated',
data: {
line_id: lineId,
line_id_code: row.id,
column: columnKey,
column: colId,
value: value,
},
};

View File

@ -1,6 +1,6 @@
import { useCallback, useEffect, useState } from 'react';
import { columnPinningDefault, columnVisibilityDefault } from '../constants/columnConfig.js';
import { collectLeafColumns, getColumnKey, getLeafColumns } from '../utils/columnUtils';
import { collectLeafColumns, getLeafColumns } from '../utils/columnUtils';
import { loadFromStorage, saveToStorage } from '../utils/localStorageUtils.js';
export const useColumnSettings = (tableKey) => {
@ -62,8 +62,7 @@ export const useColumnSettings = (tableKey) => {
const handleToggleColumnVisibility = useCallback((column, isSelect) => {
const leafCols = collectLeafColumns(column).reduce((acc, item) => {
const columnKey = getColumnKey(item);
if (columnKey) acc[columnKey] = isSelect;
acc[item.id] = isSelect;
return acc;
}, {});

View File

@ -1,5 +1,5 @@
// Явный id определяет технический ключ колонки; accessorKey используется как fallback.
export const getColumnKey = (node) => node?.id ?? node?.accessorKey;
// Получение accessorKey колонки
export const getColumnKey = (node) => node?.accessorKey;
// Проверка, нужно ли скрыть колонку из дерева
export const shouldExcludeFromTree = (node, excludeSet) => {

View File

@ -3,7 +3,7 @@ import { CheckBox, CheckBoxOutlineBlank, IndeterminateCheckBox } from '@mui/icon
import { Box, Checkbox, InputAdornment, Popover, TextField, Typography } from '@mui/material';
import { SimpleTreeView, TreeItem } from '@mui/x-tree-view';
import { memo, useMemo, useState } from 'react';
import { filterColumnTree, getColumnKey, getColumnTreeLeafKeys } from '../RealtimeTable/utils/columnUtils';
import { filterColumnTree, getColumnTreeLeafKeys } from '../RealtimeTable/utils/columnUtils';
import { formatHeaderYear } from '../RealtimeTable/utils/headerYearUtils';
const EMPTY_IDS = [];
@ -62,7 +62,7 @@ const CollapsibleTree = ({
};
const leafColumns = getLeafColumn(node);
return leafColumns.map(getColumnKey).filter(Boolean);
return leafColumns.map((c) => c.id || c.accessorKey);
};
const isNodeChecked = (node) => {
@ -84,11 +84,11 @@ const CollapsibleTree = ({
let current = column;
while (current) {
ancestors.unshift(getColumnKey(current));
ancestors.unshift(current.id || current.accessorKey);
current = current.parent;
}
return ancestors.filter(Boolean);
return ancestors;
};
return getFullColumnPath(column).join('_');
};
@ -98,10 +98,9 @@ const CollapsibleTree = ({
return nodes.map((node) => {
const checkStatus = isNodeChecked(node);
const nodeKey = getColumnKey(node);
return (
<TreeItem
key={nodeKey}
key={node.id || node.accessorKey}
itemId={String(getId(node))}
label={
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>