add-columns-spod-4-form #176

Merged
PotapovaA merged 2 commits from add-columns-spod-4-form into test 2026-09-24 15:11:47 +03:00
9 changed files with 5517 additions and 5297 deletions

62
web/package-lock.json generated
View File

@ -84,19 +84,6 @@
"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",
@ -153,24 +140,6 @@
"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",
@ -423,6 +392,37 @@
"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,5 +32,9 @@
"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,6 +8,14 @@ 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) {
@ -238,21 +246,19 @@ 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 colId = columnId.slice(5); // убираем префикс "data."
const columnKey = getColumnRequestKey(column);
const message = {
event: 'cell_edit_start',
data: {
line_id: lineId,
column: colId,
column: columnKey,
},
};
@ -269,21 +275,19 @@ 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 colId = columnId.slice(5);
const columnKey = getColumnRequestKey(column);
const message = {
event: 'cell_edit_end',
data: {
line_id: lineId,
column: colId,
column: columnKey,
},
};
@ -299,20 +303,19 @@ 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 colId = columnId.slice(5);
const columnKey = getColumnRequestKey(column);
const message = {
event: 'cell_updated',
data: {
line_id: lineId,
line_id_code: row.id,
column: colId,
column: columnKey,
value: value,
},
};

View File

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

View File

@ -1,5 +1,5 @@
// Получение accessorKey колонки
export const getColumnKey = (node) => node?.accessorKey;
// Явный id определяет технический ключ колонки; accessorKey используется как fallback.
export const getColumnKey = (node) => node?.id ?? 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, getColumnTreeLeafKeys } from '../RealtimeTable/utils/columnUtils';
import { filterColumnTree, getColumnKey, 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((c) => c.id || c.accessorKey);
return leafColumns.map(getColumnKey).filter(Boolean);
};
const isNodeChecked = (node) => {
@ -84,11 +84,11 @@ const CollapsibleTree = ({
let current = column;
while (current) {
ancestors.unshift(current.id || current.accessorKey);
ancestors.unshift(getColumnKey(current));
current = current.parent;
}
return ancestors;
return ancestors.filter(Boolean);
};
return getFullColumnPath(column).join('_');
};
@ -98,9 +98,10 @@ const CollapsibleTree = ({
return nodes.map((node) => {
const checkStatus = isNodeChecked(node);
const nodeKey = getColumnKey(node);
return (
<TreeItem
key={node.id || node.accessorKey}
key={nodeKey}
itemId={String(getId(node))}
label={
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>