Загрузка данных


const handleGridContextMenu = (e: React.MouseEvent<HTMLDivElement>) => {
  if (!onRowContextMenu) return;

  // 1. Находим саму строку как DOM-элемент (класс строки в MUI DataGrid всегда .MuiDataGrid-row)
  const rowNode = (e.target as HTMLElement).closest('.MuiDataGrid-row');
  if (!rowNode) return;

  // 2. Игнорируем клики по самой детальной панели (подвалу)
  if (rowNode.classList.contains('row-detail-panel')) return;

  // 3. ЗАЩИТА: Проверяем, принадлежит ли этот узел нашей текущей таблице
  const closestGrid = (e.target as HTMLElement).closest('.MuiDataGrid-root');
  const currentGrid = e.currentTarget.querySelector('.MuiDataGrid-root');
  if (closestGrid !== currentGrid) return; 

  // 4. НАХОДИМ ПРАВИЛЬНЫЙ ИНДЕКС СТРОКИ НА ЭКРАНЕ:
  // Получаем список всех строк текущего DataGrid, которые сейчас выведены в DOM
  const allRenderedRows = Array.from(currentGrid?.querySelectorAll('.MuiDataGrid-row') || []);
  
  // Находим, какой по счету на экране является строка, по которой кликнули
  const visualIndex = allRenderedRows.indexOf(rowNode);

  if (visualIndex !== -1) {
    // 5. Ищем строку в массиве displayRows, который прямо сейчас отображается на экране
    const clickedDisplayRow = displayRows[visualIndex];
    
    if (clickedDisplayRow && !clickedDisplayRow.isDetailPanel) {
      // Находим оригинальный объект строки в базовом стейте по совпадению row_id
      const actualRow = rows.find(r => String(r.row_id) === String(clickedDisplayRow.row_id));
      
      if (actualRow) {
        e.preventDefault(); // Запрещаем стандартное меню браузера
        onRowContextMenu(actualRow as T, e);
      }
    }
  }
};