This commit is contained in:
2026-02-02 11:00:40 +03:00
parent 87a1a628d3
commit 2d0f236fa4
22 changed files with 1119 additions and 461 deletions

View File

@@ -3,6 +3,7 @@
import React, { useEffect, useCallback, useState } from 'react'
import { useRouter, useSearchParams } from 'next/navigation'
import Sidebar from '../../../components/ui/Sidebar'
import AnimatedBackground from '../../../components/ui/AnimatedBackground'
import useNavigationStore from '../../store/navigationStore'
import Monitoring from '../../../components/navigation/Monitoring'
import FloorNavigation from '../../../components/navigation/FloorNavigation'
@@ -117,6 +118,8 @@ const NavigationPage: React.FC = () => {
map[String(d.serial_number).trim()] = d.status
}
})
console.log('[NavigationPage] sensorStatusMap created with', Object.keys(map).length, 'sensors')
console.log('[NavigationPage] Sample sensor IDs in map:', Object.keys(map).slice(0, 5))
return map
}, [detectorsData])
@@ -127,21 +130,22 @@ const NavigationPage: React.FC = () => {
}, [selectedDetector, selectedAlert]);
// Управление выделением всех сенсоров при открытии/закрытии меню Sensors
// ИСПРАВЛЕНО: Подсветка датчиков остается включенной всегда, независимо от состояния панели Sensors
useEffect(() => {
console.log('[NavigationPage] showSensors changed:', showSensors, 'modelReady:', isModelReady)
if (showSensors && isModelReady) {
// При открытии меню Sensors - выделяем все сенсоры (только если модель готова)
console.log('[NavigationPage] Setting highlightAllSensors to TRUE')
if (isModelReady) {
// Всегда включаем подсветку всех сенсоров когда модель готова
console.log('[NavigationPage] Setting highlightAllSensors to TRUE (always enabled)')
setHighlightAllSensors(true)
setFocusedSensorId(null)
} else if (!showSensors) {
// При закрытии меню Sensors - сбрасываем выделение
console.log('[NavigationPage] Setting highlightAllSensors to FALSE')
setHighlightAllSensors(false)
// Сбрасываем фокус только если панель Sensors закрыта
if (!showSensors) {
setFocusedSensorId(null)
}
}
}, [showSensors, isModelReady])
// Дополнительный эффект для задержки выделения сенсоров при открытии меню
// ИСПРАВЛЕНО: Задержка применяется только при открытии панели Sensors
useEffect(() => {
if (showSensors && isModelReady) {
const timer = setTimeout(() => {
@@ -155,9 +159,10 @@ const NavigationPage: React.FC = () => {
const urlObjectId = searchParams.get('objectId')
const urlObjectTitle = searchParams.get('objectTitle')
const urlModelPath = searchParams.get('modelPath')
const objectId = currentObject.id || urlObjectId
const objectTitle = currentObject.title || urlObjectTitle
const [selectedModelPath, setSelectedModelPath] = useState<string>('')
const [selectedModelPath, setSelectedModelPath] = useState<string>(urlModelPath || '')
const handleModelLoaded = useCallback(() => {
setIsModelReady(true)
@@ -174,8 +179,12 @@ const NavigationPage: React.FC = () => {
if (selectedModelPath) {
setIsModelReady(false);
setModelError(null);
// Сохраняем выбранную модель в URL для восстановления при возврате
const params = new URLSearchParams(searchParams.toString());
params.set('modelPath', selectedModelPath);
window.history.replaceState(null, '', `?${params.toString()}`);
}
}, [selectedModelPath]);
}, [selectedModelPath, searchParams]);
useEffect(() => {
if (urlObjectId && (!currentObject.id || currentObject.id !== urlObjectId)) {
@@ -183,6 +192,13 @@ const NavigationPage: React.FC = () => {
}
}, [urlObjectId, urlObjectTitle, currentObject.id, currentObject.title, setCurrentObject])
// Восстановление выбранной модели из URL при загрузке страницы
useEffect(() => {
if (urlModelPath && !selectedModelPath) {
setSelectedModelPath(urlModelPath);
}
}, [urlModelPath, selectedModelPath])
useEffect(() => {
const loadDetectors = async () => {
try {
@@ -195,6 +211,8 @@ const NavigationPage: React.FC = () => {
if (!res.ok) throw new Error(typeof payload === 'string' ? payload : (payload?.error || 'Не удалось получить детекторов'))
const data = payload?.data ?? payload
const detectors = (data?.detectors ?? {}) as Record<string, DetectorType>
console.log('[NavigationPage] Received detectors count:', Object.keys(detectors).length)
console.log('[NavigationPage] Sample detector keys:', Object.keys(detectors).slice(0, 5))
setDetectorsData({ detectors })
} catch (e: any) {
console.error('Ошибка загрузки детекторов:', e)
@@ -240,10 +258,8 @@ const NavigationPage: React.FC = () => {
setSelectedDetector(null)
setFocusedSensorId(null)
setSelectedAlert(null)
// При закрытии меню детектора из Sensors - выделяем все сенсоры снова
if (showSensors) {
setHighlightAllSensors(true)
}
// При закрытии меню детектора - выделяем все сенсоры снова
setHighlightAllSensors(true)
}
const handleNotificationClick = (notification: NotificationType) => {
@@ -266,10 +282,8 @@ const NavigationPage: React.FC = () => {
setSelectedAlert(null)
setFocusedSensorId(null)
setSelectedDetector(null)
// При закрытии меню алерта из Sensors - выделяем все сенсоры снова
if (showSensors) {
setHighlightAllSensors(true)
}
// При закрытии меню алерта - выделяем все сенсоры снова
setHighlightAllSensors(true)
}
const handleAlertClick = (alert: AlertType) => {
@@ -378,12 +392,15 @@ const NavigationPage: React.FC = () => {
}
return (
<div className="flex h-screen bg-[#0e111a]">
<Sidebar
activeItem={2}
/>
<div className="relative flex h-screen bg-[#0e111a] overflow-hidden">
<AnimatedBackground />
<div className="relative z-20">
<Sidebar
activeItem={2}
/>
</div>
<div className="flex-1 flex flex-col relative">
<div className="relative z-10 flex-1 flex flex-col">
{showMonitoring && (
<div className="absolute left-0 top-[73px] bottom-0 bg-[#161824] border-r border-gray-700 z-20 w-[500px]">
@@ -439,7 +456,7 @@ const NavigationPage: React.FC = () => {
detectorsData={detectorsData}
onDetectorMenuClick={handleDetectorMenuClick}
onClose={closeListOfDetectors}
is3DReady={isModelReady && !modelError}
is3DReady={selectedModelPath ? !modelError : false}
/>
{detectorsError && (
<div className="mt-2 text-sm text-red-400">{detectorsError}</div>
@@ -456,7 +473,7 @@ const NavigationPage: React.FC = () => {
detectorsData={detectorsData}
onAlertClick={handleAlertClick}
onClose={closeSensors}
is3DReady={isModelReady && !modelError}
is3DReady={selectedModelPath ? !modelError : false}
/>
{detectorsError && (
<div className="mt-2 text-sm text-red-400">{detectorsError}</div>