/** * GraphicalEditorKeepAlive * * Keeps the GraphicalEditorPage mounted across route changes so the canvas * state, SSE connections, and editor context survive navigation to ANY page * (other features, admin, settings, etc.). * * Persistence is scoped per `(mandateId, instanceId)`: when the user switches * to a DIFFERENT mandate or instance via the navigator, the previous editor * mount is discarded and a fresh page is mounted. Otherwise stale state from * mandate A leaks into mandate B and saves end up hitting the wrong tenant * (HTTP 404 / "not found"). * * Implementation: feeds the cached `(mandate, instance)` tuple into both * `props` and `key`. React reuses the mount as long as the tuple stays * identical and unmounts/remounts on change. */ import React, { useRef } from 'react'; import { useLocation } from 'react-router-dom'; import { GraphicalEditorPage } from './GraphicalEditorPage'; const _GE_EDITOR_ROUTE_RE = /\/mandates\/([^/]+)\/graphicalEditor\/([^/]+)\/editor/; interface GraphicalEditorKeepAliveProps { isVisible: boolean; } export const GraphicalEditorKeepAlive: React.FC = ({ isVisible }) => { const location = useLocation(); const cachedMandateIdRef = useRef(''); const cachedInstanceIdRef = useRef(''); const hasEverMountedRef = useRef(false); const match = location.pathname.match(_GE_EDITOR_ROUTE_RE); if (match?.[1] && match?.[2]) { cachedMandateIdRef.current = match[1]; cachedInstanceIdRef.current = match[2]; hasEverMountedRef.current = true; } if (!hasEverMountedRef.current) return null; const mandateId = cachedMandateIdRef.current; const instanceId = cachedInstanceIdRef.current; const scopeKey = `${mandateId}:${instanceId}`; return (
); }; export default GraphicalEditorKeepAlive;