From ca7472213abc1f626df04fc81ac83b922829f62c Mon Sep 17 00:00:00 2001 From: Veronika Tsygankova Date: Tue, 28 Jul 2026 18:24:28 +0300 Subject: [PATCH] =?UTF-8?q?[AURORA-1076]=20-=20=D1=81=D0=BA=D1=80=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BB=D0=BE=D0=BD=D0=BE=D0=BA?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B8=20=D0=B8=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=8D=D1=82?= =?UTF-8?q?=D0=B0=D0=BF=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RealtimeTable/utils/columnUtils.js | 48 +++++++++++++++++++ web/src/components/Stages/AddStagesModal.jsx | 2 + web/src/components/Stages/constants.js | 8 ++++ web/src/components/common/CollapsibleTree.jsx | 27 ++++++++--- 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 web/src/components/Stages/constants.js diff --git a/web/src/components/RealtimeTable/utils/columnUtils.js b/web/src/components/RealtimeTable/utils/columnUtils.js index 91e61cb..cd23607 100644 --- a/web/src/components/RealtimeTable/utils/columnUtils.js +++ b/web/src/components/RealtimeTable/utils/columnUtils.js @@ -1,3 +1,51 @@ +// Получение accessorKey колонки +export const getColumnKey = (node) => node?.accessorKey; + +// Проверка, нужно ли скрыть колонку из дерева +export const shouldExcludeFromTree = (node, excludeSet) => { + if (node?.hideInTree) return true; + const key = getColumnKey(node); + return Boolean(key && excludeSet.has(key)); +}; + +// Фильтрация дерева колонок по списку исключений +export const filterColumnTree = (nodes, excludeColumnKeys = []) => { + if (!nodes?.length) return []; + + const excludeSet = new Set(excludeColumnKeys); + + return nodes.flatMap((node) => { + if (shouldExcludeFromTree(node, excludeSet)) return []; + + const hasChildren = Array.isArray(node.columns) && node.columns.length > 0; + if (!hasChildren) return [node]; + + const filteredChildren = filterColumnTree(node.columns, excludeColumnKeys); + if (filteredChildren.length === 0) return []; + + return [{ ...node, columns: filteredChildren }]; + }); +}; + +// Получение accessorKey всех листовых колонок из дерева +export const getColumnTreeLeafKeys = (nodes) => { + const keys = []; + + const collect = (cols) => { + for (const col of cols) { + if (col.columns?.length) { + collect(col.columns); + } else { + const key = getColumnKey(col); + if (key) keys.push(key); + } + } + }; + + collect(nodes); + return keys; +}; + // Сбор листовых колонок export const getLeafColumns = (targetColumn) => { if (!targetColumn) return []; diff --git a/web/src/components/Stages/AddStagesModal.jsx b/web/src/components/Stages/AddStagesModal.jsx index cdcec58..9bde595 100644 --- a/web/src/components/Stages/AddStagesModal.jsx +++ b/web/src/components/Stages/AddStagesModal.jsx @@ -23,6 +23,7 @@ import { Cancel } from '../common/icons/icons'; import { getStageStatus, getStatusColors } from './StagesTable/utils'; import { StageStatusChip } from './StageStatusChip'; import { formatDateForApi } from './utils'; +import { stageColumnsHiddenFromPicker } from './constants'; import CollapsibleTree from '../common/CollapsibleTree'; import { collectLeafColumns } from '../RealtimeTable/utils/columnUtils'; import { STAGE_ROLE_RUSSIAN_NAME } from '../../constants/constants'; @@ -223,6 +224,7 @@ export const AddStagesModal = ({ filterColumnTree(columnTree, excludeColumnKeys), + [columnTree, excludeColumnKeys], + ); + + const visibleLeafKeys = useMemo( + () => getColumnTreeLeafKeys(visibleColumnTree), + [visibleColumnTree], + ); + const handleExpandedItemsChange = (event, itemIds) => { setExpandedItems(itemIds); }; const handleSelectAll = (isSelected) => { - for (const col of columnTree) { + for (const col of visibleColumnTree) { onSelectNode?.(col, !isSelected); } }; @@ -134,8 +146,8 @@ const CollapsibleTree = ({ }; const treeElements = useMemo(() => { - return columnTree ? renderTree(columnTree) : null; - }, [columnTree, selectedNodes]); + return visibleColumnTree.length > 0 ? renderTree(visibleColumnTree) : null; + }, [visibleColumnTree, selectedNodes]); const handleOpen = (event) => { setAnchorEl(event.currentTarget); @@ -145,12 +157,15 @@ const CollapsibleTree = ({ setAnchorEl(null); }; - const selectedCount = forStage ? selectedNodes.length : selectedNodes.length - 1; //1 колонка всегда скрыта + const visibleSelectedCount = selectedNodes.filter((id) => + visibleLeafKeys.includes(id), + ).length; + const selectedCount = forStage ? visibleSelectedCount : visibleSelectedCount - 1; //1 колонка всегда скрыта const isAllSelected = () => { - if (!columnTree) return false; + if (!visibleColumnTree.length) return false; let isSelect = true; - for (const col of columnTree) { + for (const col of visibleColumnTree) { const isChecked = isNodeChecked(col); isSelect = isChecked === 'indeterminate' ? false : isChecked && isSelect; }