вот код 
import React, { RefObject, useCallback, useEffect, useRef, useState } from 'react';
import { Table } from 'rsuite';
import {
  FileParameter,
  ObjectsClient,
  ObjectWithPropertiesEntity,
  PropertyEntity,
  SolutionEntity,
  ViewSetting,
} from '../../../../shared-objects-client/src/shared/g';
import { CustomTreeNode } from '../../types';
import { instance } from '../../../../shared-objects-client/src/api.config';
import { ContextMenu } from 'primereact/contextmenu';
import { HotKeyParams } from '../../../../objects-tree/src/types';
import { useObjectTreeWithProperties } from './objectTreeWithProperty-hook';
import { DivId } from '../../constants';
import EditProperty from '../../../../editors/src/components/editProperty/EditProperty';
import { HotKeys } from '../../../../objects-tree/src/constants';
import 'rsuite/Table/styles/index.css';
import { DraggableCell } from '../draggableCell/DraggableCell';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { useImmer } from 'use-immer';

const { Column, HeaderCell, Cell, ColumnGroup } = Table;

interface Props {
  sources: Array<ObjectWithPropertiesEntity>;
  selectionMode: 'checkbox' | 'single' | 'multiple';
  solution: SolutionEntity | undefined;
  parentId: string | undefined;
  onDoubleNodeClick?: (object: string | null) => void;
  searchText?: string;
  affiliation?: string;
  contextMenuRef?: RefObject<ContextMenu> | null;
  setNodeKey?: (key: string | undefined) => void;
  types?: Array<string>;
  externalContainerHeight?: number | null;
  hotKeyFromContextMenu?: HotKeyParams | null;
  setClickedKey?: (key: string | undefined) => void;
  viewSettings?: ViewSetting[] | undefined;
  setSelectedNodeKeys?: (keys: string[] | null) => void;
  onParentChange?: (targetKeyNode: string | null | undefined, draggableIds: string[] | undefined) => void;
  externalSelectedObject?: string | null | undefined;
  setExternalSelectedObject?: (id: string | null | undefined) => void;
}

const ObjectsService = new ObjectsClient(undefined, instance);

const minCellHeight = 70;
const headerHeight = 80;
const groupHeaderHeight = 55;
const tableContainerPadding = 28;

/**
 * Компонент виртуализированного детализированного древа
 * @param sources - источник данных
 * @param selectionMode - режим выбора узлов
 * @param solution - решение
 * @param parentId - id родителя
 * @param searchText - текст поиска
 * @param affiliation - принадлежность дерева к вкладке
 * @param contextMenuRef - ссылка на контекстное меню
 * @param setNodeKey - ключ узла, у которого открыли контекстное меню
 * @param externalContainerHeight - высота контейнера под таблицу
 * @param hotKeyFromContextMenu - горячия клавиша, вызванная из контекстного меню
 * @param setClickedKey - устанавливает ключ, нажатого узла
 * @param viewSettings - настройки представления
 * @param setSelectedNodeKeys - устанавливает выбранные узлы
 * @param onParentChange -обработчик измениения родительского узла
 * @param externalSelectedObject - выбранный объект из вне
 * @param setExternalSelectedObject - устанавливает выбранный объект из вне
 * @constructor
 */
const VirtualizedDetailedTree = ({
  sources,
  selectionMode,
  solution,
  parentId,
  searchText,
  affiliation,
  contextMenuRef,
  setNodeKey,
  externalContainerHeight,
  hotKeyFromContextMenu,
  setClickedKey,
  viewSettings,
  setSelectedNodeKeys,
  onParentChange,
  externalSelectedObject,
  setExternalSelectedObject,
}: Props) => {
  const [objects, updateObjects] = useImmer<Array<CustomTreeNode>>([]);
  const [filteredTree, updateFilteredTree] = useImmer<Array<CustomTreeNode>>([]);

  // const [objects, setObjects] = useState<Array<CustomTreeNode>>();
  // const [filteredTree, setFilteredTree] = useState<Array<CustomTreeNode>>();
  const [selectedKeys, setSelectedKeys] = useState<string[] | null>(null);
  const [expandedKeys, setExpandedKeys] = useState<Array<string>>([]);
  const [groupedProperties, setGroupedProperties] = useState<Map<string, PropertyEntity[]>>();
  const [tableHeight, setTableHeight] = useState<number | null>(null);

  const selectedObjectId = useRef<string | null>(null);
  const selectedKeysRef = useRef<string[] | null>(null);
  const tableContainerRef = useRef(null);

  const tree = useObjectTreeWithProperties();

  const expandedKeysBeforeFiltration = useRef<Record<string, boolean> | null>(null);

  useEffect(() => {
    selectedKeysRef.current = selectedKeys;
  }, [selectedKeys]);

  /**
   * Устанавливает выбранный узел
   */
  useEffect(() => {
    if (externalSelectedObject === undefined) {
      return;
    }
    if (externalSelectedObject === null) {
      setSelectedKeys(null);
      setExternalSelectedObject?.(undefined);
      return;
    }
    setClickedKey?.(externalSelectedObject);
    setSelectedKeys([externalSelectedObject]);
    setSelectedNodeKeys?.([externalSelectedObject]);
    setExternalSelectedObject?.(undefined);
  }, [externalSelectedObject]);

  /**
   * Обрабатывает drop узла или выбранную коллекцию узлов
   */
  const handleDragRow = useCallback((sourceId: string | undefined, targetId: string | undefined) => {
    // Перетаскиваемые узлы
    const targetNodes =
      selectedKeysRef.current &&
      selectedKeysRef.current.length > 0 &&
      sourceId &&
      selectedKeysRef.current.includes(sourceId)
        ? selectedKeysRef.current
        : [sourceId];

    if (onParentChange && targetId && targetNodes) {
      onParentChange(
        targetId,
        targetNodes.filter((item) => item !== undefined),
      );
    }
  }, []);

  useEffect(() => {
    if (!groupedProperties) {
      return;
    }

    // eslint-disable-next-line
  }, [groupedProperties]);

  useEffect(() => {
    if (!hotKeyFromContextMenu) {
      return;
    }
    handleKeyDown(hotKeyFromContextMenu);

    // eslint-disable-next-line
  }, [hotKeyFromContextMenu]);

  /**
   * Запрос на сервер при изменении данных свойства
   * @param propertyId - id свойства
   * @param newValue - новое значение
   * @param selectedId - id выбранного объекта
   */
  const fetchUpdatePropertyValue = async ({
    propertyId,
    newValue,
    selectedNodeId,
  }: {
    propertyId: string;
    newValue: string | undefined | null;
    selectedNodeId?: string | undefined;
  }) => {
    if (!selectedObjectId.current && !selectedNodeId) {
      return;
    }
    const objectId = selectedNodeId ? selectedNodeId : selectedObjectId.current;
    return (
      objectId && (await ObjectsService.updatePropertyValue(solution?.id, objectId, propertyId, newValue ?? undefined))
    );
  };

  /**
   * Обновляет значение свойства
   */
  const updatePropertyValue = async (variables: {
    propertyId: string;
    newValue: string | undefined | null;
    selectedObjectId?: string | undefined;
  }) => {
    try {
      await fetchUpdatePropertyValue(variables);
      if (!(solution && parentId && viewSettings)) {
        return;
      }
      const updatedObjects = await ObjectsService.getObjectWithChildrenByIdPOST(solution.id, parentId, viewSettings);
      const newTree = await tree.buildTree(updatedObjects);

      updateObjects((draft) => {
        draft.splice(0, draft.length, ...newTree);
      });
    } catch (err) {
      console.error(err);
    }
  };

  /**
   * Обрабатывает изменения свойства (всех, кроме файла) при редактировании
   * @param propertyId - id свойства
   * @param newValue - новое значение
   * @param selectedNodeId - id выбранного узла
   */
  const onPropertyValueChange = async (
    propertyId: string,
    newValue: string | undefined | null,
    selectedNodeId?: string | undefined,
  ) => {
    if (selectedNodeId) {
      await updatePropertyValue({ propertyId, newValue, selectedObjectId: selectedNodeId });
      selectedObjectId.current = selectedNodeId;
    } else {
      await updatePropertyValue({ propertyId, newValue });
    }
  };

  /**
   * Запрос на сервер при изменении данных свойства Файл
   * @param propertyId - id свойства
   * @param file - данные файла
   * @param selectedNodeId - id выбранного узла
   */
  const fetchUpdateFileValue = async ({
    propertyId,
    file,
    selectedNodeId,
  }: {
    propertyId: string;
    file: FileParameter | undefined | null;
    selectedNodeId?: string | undefined;
  }) => {
    if (!selectedObjectId.current) {
      return;
    }
    const objectId = selectedNodeId ? selectedNodeId : selectedObjectId.current;
    return await ObjectsService.updatePropertyFileValue(solution?.id, objectId, propertyId, file);
  };

  /**
   * Обновляет значение файла
   * @param variables
   */
  const updateFileValue = async (variables: {
    propertyId: string;
    file: FileParameter | undefined | null;
    selectedNodeId?: string | undefined;
  }) => {
    try {
      await fetchUpdateFileValue(variables);
      if (!(solution && parentId && viewSettings)) {
        return;
      }
      const updatedObjects = await ObjectsService.getObjectWithChildrenByIdPOST(solution.id, parentId, viewSettings);
      const newTree = await tree.buildTree(updatedObjects);

      updateObjects((draft) => {
        draft.splice(0, draft.length, ...newTree);
      });
    } catch (err) {
      console.error(err);
    }
  };

  /**
   * Обрабатывает изменения свойства Файл при редактировании
   * @param propertyId - id свойства
   * @param file - новое значение
   * @param selectedNodeId - id объекта, у которого редактируют свойство
   */
  const onFilePropertyChange = async (
    propertyId: string,
    file: FileParameter | undefined | null,
    selectedNodeId?: string | undefined,
  ) => {
    if (selectedNodeId) {
      await updateFileValue({ propertyId, file, selectedNodeId });
    } else {
      await updateFileValue({ propertyId, file });
    }
  };

  /**
   * Высчитывает высоту Table
   */
  const getTableHeight = () => {
    const navTabPanel = document.getElementsByClassName('p-tabview-nav-container');
    const filterHeight = document.getElementById(DivId.FILTER_TEMPLATE);

    if (!externalContainerHeight || !navTabPanel || !filterHeight) {
      return;
    }
    if (!(navTabPanel[0] instanceof HTMLElement)) {
      return;
    }

    const newTableHeight =
      externalContainerHeight - navTabPanel[0]?.offsetHeight - filterHeight.offsetHeight - tableContainerPadding;

    setTableHeight(newTableHeight);
  };

  useEffect(() => {
    getTableHeight();

    // eslint-disable-next-line
  }, [externalContainerHeight]);

  /**
   * Компонент по умолчанию, если у объекта отсутствует свойство
   */
  const defaultPropertyValue = () => {
    return <div className='min-h-full flex bg-gray-100 w-full' style={{ height: 'inherit', maxHeight: '100%' }}></div>;
  };

  /**
   * Инициализация дерева
   */
  const initializeTree = useCallback(async () => {
    try {
      const newTree = await tree.buildTree(sources);
      const columnOrder = viewSettings
        ? viewSettings[0]?.browsablePropertiesSettings
            ?.map((setting) => setting.id)
            .filter((item) => item !== undefined)
        : null;

      const columnNamesList = columnOrder && tree.getGroupedProperty(sources, columnOrder);

      columnNamesList && setGroupedProperties(columnNamesList);
      updateObjects((draft) => {
        draft.splice(0, draft.length, ...newTree);
      });
      searchText && searchText?.length > 0
        ? updateFilteredTree((draft) => {
            draft.splice(0, draft.length, ...tree.filterNodes(newTree, searchText));
          })
        : updateFilteredTree((draft) => {
            draft.splice(0, draft.length, ...newTree);
          });
    } catch (err) {
      console.error(err);
    }
  }, [sources]);

  useEffect(() => {
    const restoredKeys = tree.restoreExpandedKeys(affiliation, parentId);
    if (restoredKeys) {
      setExpandedKeys(restoredKeys);
    }
    initializeTree().catch((err) => console.error(err));

    // eslint-disable-next-line
  }, [initializeTree]);

  /**
   * Сворачивает узлы
   * @param nodes - узлы дерева
   */
  const collapseNodes = useCallback((nodes: Array<CustomTreeNode> | undefined): CustomTreeNode[] | undefined => {
    return nodes?.map((node) => {
      node.expanded = false;
      if (node.children?.length) {
        collapseNodes(node.children);
      }
      return node;
    });
  }, []);

  /**
   * Обрабатывает введенные данные в поиск
   * @param searchText - поисковый текст
   */
  const handleFilter = useCallback(
    (searchText: string) => {
      // if (!objectsImmer) {
      //   return;
      // }
      //
      // if (searchText?.length > 0) {
      //   if (objectsImmer) {
      //     updateObjectsImmer((draft) => {
      //       const filteredTree = tree.filterNodes(draft, searchText);
      //       updateFilteredTreeImmer((d) => {
      //         d.splice(0, d.length, ...(collapseNodes(filteredTree) || []));
      //       });
      //     });
      //   }
      // } else {
      //   updateObjectsImmer((draft) => {
      //     updateFilteredTreeImmer((d) => {
      //       d.splice(0, d.length, ...(collapseNodes(draft) || []));
      //     });
      //   });
      // }
    },

    // eslint-disable-next-line
    [objects, searchText],
  );

  useEffect(() => {
    if (!affiliation || !expandedKeysBeforeFiltration || !expandedKeys) {
      return;
    }

    if (filteredTree && searchText && searchText?.length > 0) {
      // Получаем все ключи отфильтрованного дерева
      const newExpandedKeys = getAllExpandedKeys(filteredTree, {}) ?? {};

      //  Ключи до фильтрации без учета текущих раскрытых
      const previousKeysWithoutCurrentOnes = newExpandedKeys
        ? Object.keys(expandedKeys).filter((key) => !Object.keys(newExpandedKeys).includes(key))
        : null;

      // Получаем раскрытые узлы до фильтрации
      expandedKeysBeforeFiltration.current =
        previousKeysWithoutCurrentOnes?.reduce(
          (acc, key) => {
            acc[key] = true;
            return acc;
          },
          {} as Record<string, boolean>,
        ) ?? {};

      setExpandedKeys(Object.keys(newExpandedKeys) ?? []);
      tree.putExpandedKeysInLocalStorage(
        [...Object.keys(newExpandedKeys), ...Object.keys(expandedKeysBeforeFiltration.current)],
        parentId,
        affiliation,
      );
    } else {
      if ([...expandedKeys, ...Object.keys(expandedKeysBeforeFiltration.current ?? {})].length !== 0) {
        setExpandedKeys([...expandedKeys, ...Object.keys(expandedKeysBeforeFiltration.current ?? {})]);
        tree.putExpandedKeysInLocalStorage(
          [...expandedKeys, ...Object.keys(expandedKeysBeforeFiltration.current ?? {})],
          parentId,
          affiliation,
        );
      }
    }

    // eslint-disable-next-line
  }, [filteredTree]);

  /**
   * Возвращает коллекцию раскрытых ключей массива узлов
   * @param nodes - массив узлов
   * @param keys - коллекция раскрытых узлов
   */
  const getAllExpandedKeys = (nodes: CustomTreeNode[], keys: Record<string, boolean>) => {
    for (const node of nodes) {
      if (node.children && node.children.length > 0) {
        keys[node.key as string] = true;

        getAllExpandedKeys(node.children, keys);
      }
    }
    return keys;
  };

  useEffect(() => {
    if (!objects) {
      return;
    }

    searchText !== undefined ? handleFilter(searchText) : null;
  }, [handleFilter, objects, searchText]);

  /**
   * Рендерит компонент для редактирования значения свойства в ячейку таблицы
   * @param objectProperty - свойство
   * @param selectedObjectKey - ключ выбранного элемента
   */
  const renderEditableCell = (objectProperty: PropertyEntity, selectedObjectKey: string) => {
    return (
      <div className='table-cell-content' onClick={() => handleCellClick(selectedObjectKey)}>
        <EditProperty
          solution={solution}
          selectedObjectId={selectedObjectKey}
          objectProperty={objectProperty}
          onPropertyChange={onPropertyValueChange}
          onFilePropertyChange={onFilePropertyChange}
        />
      </div>
    );
  };

  /**
   * Обработчик нажатия по ячейки
   * @param selectedObjectKey - ключ выбранного элемента
   */
  const handleCellClick = (selectedObjectKey: string | undefined) => {
    if (!selectedObjectKey || !setClickedKey || !setNodeKey) {
      return;
    }

    setClickedKey(selectedObjectKey);
    selectedObjectId.current = selectedObjectKey;

    setNodeKey(selectedObjectKey);
  };

  /**
   * Устанавливает id выбранного объекта для редактирования
   * @param nodeKey - id(ключ) узла
   */
  const setEditableObject = (nodeKey: string | undefined) => {
    if (!nodeKey || !selectedObjectId) {
      return;
    }
    selectedObjectId.current = nodeKey as string;

    if (typeof setNodeKey === 'function') {
      setNodeKey(nodeKey as string);
    }
  };

  /**
   * Управляет нажатием по горячим клавишам
   * @param hotKey - парраметры нажатой клавиши
   */
  const handleKeyDown = (hotKey: HotKeyParams) => {
    // Выбранные узлы, к которым будут применяться горячие клавиши
    const targetNodes: Array<string> = [];
    if (selectedKeys)
      selectedKeys?.forEach((key) => {
        targetNodes.push(key);
      });

    if (!targetNodes) {
      return;
    }

    // Обрабатывает команду РАСКРЫТИЯ коллекции дочерних элементов, выбранного узла
    if (hotKey.pressedCtrl && hotKey.key === HotKeys.ARROW_RIGHT) {
      setExpandedKeys((prevKeys) => [...prevKeys, ...targetNodes]);
      tree.putExpandedKeysInLocalStorage([...expandedKeys, ...targetNodes], parentId, affiliation);
    }

    // Обрабатывает команду СКРЫТИЯ коллекции дочерних элементов, выбранного узла
    if (hotKey.pressedCtrl && hotKey.key === HotKeys.ARROW_LEFT) {
      if (objects) {
        const newExpandedKeys: Array<string> = [...expandedKeys];

        for (const targetNode of targetNodes) {
          const selectedNode = tree.findNodeByKey(objects, targetNode);

          if (selectedNode && selectedNode.children) {
            selectedNode.children.forEach((node) => {
              tree.removeAllKeys(node, newExpandedKeys);
            });
          }
        }

        setExpandedKeys(newExpandedKeys);
        tree.putExpandedKeysInLocalStorage(newExpandedKeys, parentId, affiliation);
      }
    }

    // Обрабатывает команду РАСКРЫТИЯ дочерних элементов, выбранного узла
    if (!hotKey.pressedCtrl && hotKey.key === HotKeys.ARROW_RIGHT) {
      if (objects) {
        targetNodes.forEach((targetNode) => {
          const selectedNode = tree.findNodeByKey(objects, targetNode);

          if (selectedNode) {
            const allDescendantKeys = tree.getAllKeys(selectedNode);
            setExpandedKeys((prevExpandedKeys) => [
              ...prevExpandedKeys,
              ...(allDescendantKeys ?? []), // Добавляем ключи всех потомков
            ]);
            tree.putExpandedKeysInLocalStorage([...expandedKeys, ...(allDescendantKeys ?? [])], parentId, affiliation);
          }
        });
      }
    }

    // Обрабатывает команду СКРЫТИЯ дочерних элементов, выбранного узла
    if (!hotKey.pressedCtrl && hotKey.key === HotKeys.ARROW_LEFT) {
      setExpandedKeys((prevKeys) => {
        const updatedKeys: Array<string> = [...prevKeys];
        targetNodes.forEach((targetNode) => {
          const indexToDelete = updatedKeys.findIndex((key) => key === targetNode);
          updatedKeys.splice(indexToDelete, 1);
        });
        tree.putExpandedKeysInLocalStorage(updatedKeys, parentId, affiliation);
        return updatedKeys;
      });
    }
  };

  /**
   * Обработчик контекстного меню
   * @param rowData - данные строки
   * @param e - событие
   */
  const handleContextMenu = (rowData: CustomTreeNode, e: React.MouseEvent) => {
    const nodeKey = rowData?.key?.toString();
    if (!nodeKey) {
      return;
    }
    contextMenuRef?.current?.show(e);

    setClickedKey?.(rowData.key as string);
    setEditableObject(rowData?.key?.toString());

    // @ts-ignore
    const newSelectedNodes = getNewSelectedNodes(e.ctrlKey, nodeKey);
    setSelectedKeys(newSelectedNodes);
    setSelectedNodeKeys?.(newSelectedNodes);

    if (typeof setNodeKey === 'function') {
      setNodeKey(rowData.id);
    }
  };

  /**
   * Получает новые раскрытые узлы
   * @param isCtrlPressed - ctrl зажат
   * @param nodeKey - ключ узла
   */
  const getNewSelectedNodes = (isCtrlPressed: boolean, nodeKey: string) => {
    switch (selectionMode) {
      case 'multiple':
        // Если клик был по еще не выбранному элементу
        if (!selectedKeys || !selectedKeys.includes(nodeKey)) {
          // Если зажат ctrl, то добавляем вершину к выбранным
          if (isCtrlPressed && typeof selectedKeys === 'object') {
            return [...(selectedKeys ?? []), nodeKey];
          } else {
            // Если ctrl не зажат, то выделяем только этот узел
            return [nodeKey];
          }
        } else {
          // Если клик по одному из выбранных ранее узлов, то ничего не меняем
          return selectedKeys;
        }
      default:
        return [];
    }
  };

  /**
   * Рендер иконки toggle
   * @param icon
   * @param rowData - данные строки
   * @param expanded - раскрытый\не раскрытый узел
   */
  const renderToggleIcon = (
    icon: React.ReactNode,
    rowData: CustomTreeNode | undefined,
    expanded: boolean | undefined,
  ) => {
    // Не показываем иконку, если нет детей
    if (icon && (!rowData?.children || rowData.children.length === 0)) {
      return <div style={{ width: '16px', height: '16px' }}></div>;
    }
    return expanded ? (
      <span className='pi pi-chevron-down ' style={{ color: '#6c757d', marginTop: '4px' }}></span>
    ) : (
      <span className='pi pi-chevron-right ' style={{ color: '#6c757d', marginTop: '4px' }}></span>
    );
  };

  /**
   * Управляет раскрытыми\закрытыми узлами
   * @param isOpen - раскрытый\не раскрытый узел
   * @param rowData - данные строки
   */
  const handleOnExpandNode = (isOpen: boolean, rowData: CustomTreeNode) => {
    if (!rowData.key) {
      return;
    }

    const newExpandedKeys = !isOpen
      ? expandedKeys.filter((key) => key !== rowData.key)
      : [...expandedKeys, rowData.key.toString()];

    if (affiliation) {
      tree.putExpandedKeysInLocalStorage(newExpandedKeys, parentId, affiliation);
    }
    setExpandedKeys(newExpandedKeys);
  };

  /**
   * Обработчик смены узла
   * @param rowData - данные строки
   * @param e - событие
   */
  const handleOnSelectionChange = (rowData: CustomTreeNode, e: React.MouseEvent) => {
    if (!rowData.id) {
      return;
    }
    const targetElement = e.target as HTMLDivElement;

    // Если нажаты иконки раскрытия\скрытия
    if (
      targetElement.className?.includes('pi pi-chevron-down') ||
      targetElement.className?.includes('pi pi-chevron-right')
    ) {
      return;
    }

    if (e.ctrlKey) {
      const newSelectedKeys = selectedKeys?.includes(rowData.id)
        ? selectedKeys?.filter((key) => key !== rowData.id)
        : [...(selectedKeys ?? []), rowData.id];

      setSelectedKeys(newSelectedKeys);
      if (setSelectedNodeKeys) {
        setSelectedNodeKeys(newSelectedKeys);
      }
    } else {
      setSelectedKeys([rowData.id]);
      if (setSelectedNodeKeys) {
        setSelectedNodeKeys([rowData.id]);
      }
    }

    if (setClickedKey) {
      setClickedKey(rowData.id);
    }
    setEditableObject(rowData.id);
  };

  /**
   * Обработчик перехвата нажатия клавиш
   * @param event -событие
   */
  const handleOnKeyCapture = (event: React.KeyboardEvent) => {
    if (
      event.key === 'ArrowDown' ||
      event.key === 'ArrowUp' ||
      event.key === 'ArrowLeft' ||
      event.key === 'ArrowRight'
    ) {
      event.stopPropagation();
      event.preventDefault();

      handleKeyDown({ pressedCtrl: event.ctrlKey, key: event.key });
    }
  };

  return (
    <DndProvider backend={HTML5Backend}>
      <div className='detailed-tree min-h-full max-h-full min-w-full' ref={tableContainerRef}>
        {filteredTree && filteredTree.length > 0 && (
          <Table
            isTree
            virtualized
            bordered
            cellBordered
            tabIndex={0}
            rowKey='id'
            height={tableHeight ?? 900}
            data={filteredTree}
            shouldUpdateScroll={false}
            rowHeight={minCellHeight}
            headerHeight={headerHeight + groupHeaderHeight}
            renderTreeToggle={renderToggleIcon}
            renderEmpty={() => <div className={'p-5'}>Результаты не найдены</div>}
            onRowContextMenu={(rowData, event) => handleContextMenu(rowData, event)}
            expandedRowKeys={expandedKeys}
            onExpandChange={handleOnExpandNode}
            onRowClick={(rowData, event) => handleOnSelectionChange(rowData, event)}
            rowClassName={(rowData) => {
              return rowData?.id && selectedKeys?.includes(rowData.id) ? 'selected-row' : '';
            }}
            onKeyDownCapture={handleOnKeyCapture}
          >
            <Column width={300} fixed>
              <HeaderCell>{''}</HeaderCell>
              <Cell>
                {(rowData: CustomTreeNode) => (
                  <DraggableCell key={rowData.id} rowData={rowData} onDrag={handleDragRow} />
                )}
              </Cell>
            </Column>
            {groupedProperties &&
              Array.from(groupedProperties?.entries()).map(([category, properties]) => {
                const categoryWidth = properties?.reduce(
                  (groupWidth, property) => groupWidth + (property?.columnWidth ?? 0),
                  0,
                );
                return (
                  <ColumnGroup
                    key={category}
                    header={category}
                    width={categoryWidth}
                    headerHeight={headerHeight}
                    groupHeaderHeight={groupHeaderHeight}
                  >
                    {properties?.map((property) => {
                      return (
                        <Column
                          key={property.id}
                          width={property.columnWidth}
                          minWidth={property.columnWidth}
                          resizable
                          fullText
                        >
                          <HeaderCell>{property.name}</HeaderCell>
                          <Cell>
                            {(rowData) => {
                              const propertyVal = rowData.properties?.find(
                                (prop: PropertyEntity) =>
                                  prop.id === property.id && prop.category === property.category,
                              );
                              return propertyVal
                                ? renderEditableCell(propertyVal, rowData.key)
                                : defaultPropertyValue();
                            }}
                          </Cell>
                        </Column>
                      );
                    })}
                  </ColumnGroup>
                );
              })}
          </Table>
        )}
      </div>
    </DndProvider>
  );
};

export default VirtualizedDetailedTree;

у меня естьп роблема в функции handleFilter
когда я ее раскомментирую то получаю ошибку Uncaught TypeError: Cannot perform 'get' on a proxy that has been revoked
index.tsx:86The above error occurred in the <VirtualizedDetailedTree> component: at VirtualizedDetailedTree (https://localhost:5173/src/packages/tecon-smart-studio-components/src/components/detailed-tree/src/components/objectTreeWithProperies/VirtualizedDetailedTree.tsx?t=1747912928429:40:3) at div at div at DetailedObjectTree (https://localhost:5173/src/packages/tecon-smart-studio-components/src/components/detailed-tree/src/components/detailedObjectTree/DetailedObjectTree.tsx?t=1747912928429:33:3) at div at div at div at https://localhost:5173/node_modules/.vite/deps/primereact_tabview.js?v=92bf95c6:279:20 at div at TabsPanel (https://localhost:5173/src/widgets/TabsPanel/TabsPanel.tsx?t=1747912928429:53:30) at div at div at https://localhost:5173/node_modules/.vite/deps/primereact_splitter.js?v=92bf95c6:206:20 at Layout (https://localhost:5173/src/pages/mainPage/ui/Layout.tsx?t=1747912928429:29:29) at main at div at MainPage (https://localhost:5173/src/pages/mainPage/MainPage.tsx?t=1747912928429:23:27) at RenderedRoute (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:4089:5) at Routes (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:4559:5) at ProjectRoutes at RenderedRoute (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:4089:5) at Routes (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:4559:5) at Provider (https://localhost:5173/node_modules/.vite/deps/react-signalr.js?v=92bf95c6:4103:27) at App (https://localhost:5173/src/app/App.tsx?t=1747912928429:33:17) at Router (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:4502:15) at BrowserRouter (https://localhost:5173/node_modules/.vite/deps/react-router-dom.js?v=92bf95c6:5248:5) at QueryClientProvider2 (https://localhost:5173/node_modules/.vite/deps/react-query.js?v=92bf95c6:2646:21) Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
react-dom.development.js:26962Uncaught TypeError: Cannot perform 'get' on a proxy that has been revoked

раньше эта функция выглядела вот так 
  const handleFilter = useCallback(
    (searchText: string) => {
      if (!objects) {
        return;
      }

      if (searchText?.length > 0) {
        if (objects) {
          const filteredTree = tree.filterNodes(objects, searchText);
          setFilteredTree(collapseNodes(filteredTree));
        }
      } else {
        setFilteredTree(collapseNodes(objects));
      }
    },

    // eslint-disable-next-line
    [objects, searchText],
  );


но сейчас мне надо перевести ее на иммер 
и я сделала протсо замену всех сеттов на апдейты и все упало 
что не так 
исправь