import { useEffect, useMemo, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { CircuitBoard, DatabaseZap, RefreshCw } from 'lucide-react'; import { getPublishedDiagramPage, listDiagramPages } from '../../entities/diagram/api'; import { formatDateTime } from '../../utils/format'; import { ElectricalNode } from './ElectricalNode'; import { getCanvasBounds, getEdgePoints, pointsToPolyline } from './geometry'; import { collectBindingTags, createLiveGroups, pickDefaultPage } from './model'; import { useElectricalLiveValues } from './useElectricalLiveValues'; type ElectricalSchematicsPageProps = { edgeId: string; }; /** Отображает опубликованную электросхему и подставляет live-значения через SSE cloud-v3. */ export function ElectricalSchematicsPage({ edgeId }: ElectricalSchematicsPageProps) { const [selectedPageKey, setSelectedPageKey] = useState(''); const pages = useQuery({ queryKey: ['diagram-pages', edgeId], queryFn: () => listDiagramPages(edgeId), enabled: Boolean(edgeId), }); const publishedPages = useMemo(() => pages.data?.filter((page) => page.publishedRevision) ?? [], [pages.data]); const selectedPage = useMemo( () => publishedPages.find((page) => page.pageKey === selectedPageKey) ?? pickDefaultPage(publishedPages, edgeId), [edgeId, publishedPages, selectedPageKey], ); useEffect(() => { if (selectedPage && selectedPage.pageKey !== selectedPageKey) { setSelectedPageKey(selectedPage.pageKey); } }, [selectedPage, selectedPageKey]); const page = useQuery({ queryKey: ['published-diagram-page', selectedPage?.pageKey], queryFn: () => getPublishedDiagramPage(selectedPage!.pageKey), enabled: Boolean(selectedPage?.pageKey), }); const diagramDocument = page.data?.document; const bindingTags = useMemo(() => (diagramDocument ? collectBindingTags(diagramDocument) : []), [diagramDocument]); const liveGroups = useMemo(() => createLiveGroups(bindingTags), [bindingTags]); const nodeMap = useMemo(() => new Map((diagramDocument?.nodes ?? []).map((node) => [node.id, node])), [diagramDocument?.nodes]); const canvasBounds = useMemo(() => getCanvasBounds(diagramDocument), [diagramDocument]); const { connectedSources, liveValues } = useElectricalLiveValues(liveGroups, selectedPage?.pageKey); const liveTagCount = liveValues.size ? Array.from(liveValues.keys()).filter((key) => key.startsWith('tag:')).length : 0; const connected = connectedSources.size > 0; return (
Электросхемы

{page.data?.title || diagramDocument?.title || selectedPage?.pageKey || edgeId}

{publishedPages.length > 1 ? ( ) : null}
{connected ? `SSE · ${connectedSources.size}` : liveGroups.length ? 'подключение SSE' : 'нет привязок'}
{pages.isError ? (
Не удалось загрузить список опубликованных схем: {String(pages.error)}
) : null} {!pages.isPending && !publishedPages.length && !pages.isError ? (
Для {edgeId} пока нет опубликованных схем
) : null} {page.isError ? (
Не удалось загрузить опубликованную схему: {String(page.error)}
) : null} {diagramDocument ? (
{diagramDocument.background?.url ? ( ) : null} {(diagramDocument.edges ?? []).map((edge) => { const points = getEdgePoints(edge, nodeMap); if (points.length < 2) { return null; } return ( ); })} {diagramDocument.nodes.map((node) => ( ))}
) : page.isPending || pages.isPending ? (
Загрузка опубликованной схемы...
) : null}
); }