1import React from 'react';
2import { apiFetch } from '../lib/api';
3import './MeshCentralEmbed.css';
6 * MeshCentral Embed Component
7 * Embeds MeshCentral views directly into the dashboard with automatic authentication
10 * 10 = General (device overview)
11 * 11 = Desktop (remote desktop)
12 * 12 = Terminal (command line)
13 * 13 = Files (file manager)
17 * 17 = Details (hardware info)
20export default function MeshCentralEmbed({ agentId, nodeId, viewMode = 11, title = 'Remote Desktop' }) {
21 const [loading, setLoading] = React.useState(true);
22 const [error, setError] = React.useState(null);
23 const [iframeUrl, setIframeUrl] = React.useState(null);
24 const [sessionInfo, setSessionInfo] = React.useState(null);
25 const iframeRef = React.useRef(null);
27 // Load authenticated MeshCentral session
28 React.useEffect(() => {
29 async function createSession() {
30 if (!agentId && !nodeId) {
31 setError('No agent ID or node ID provided');
40 // Call backend to create authenticated session
41 const response = await apiFetch(`/meshcentral/session/${agentId}`, {
43 body: JSON.stringify({ viewMode })
47 const data = await response.json();
48 throw new Error(data.message || data.error || 'Failed to create MeshCentral session');
51 const data = await response.json();
53 if (!data.iframeUrl) {
54 throw new Error('No iframe URL returned from server');
57 setIframeUrl(data.iframeUrl);
59 console.log('[MeshCentral] Session created:', data.sessionToken);
62 console.error('[MeshCentral] Failed to create session:', err);
63 setError(err.message || 'Failed to connect to MeshCentral');
69 }, [agentId, nodeId, viewMode]);
71 if (!agentId && !nodeId) {
73 <div className="meshcentral-error">
74 <div className="error-icon">⚠️</div>
75 <h3>MeshAgent Not Connected</h3>
76 <p>This device is not connected to MeshCentral.</p>
77 <p className="error-hint">
78 Please ensure the MeshAgent is installed and running on this device.
84 const handleLoad = () => {
87 console.log('[MeshCentral] iframe loaded successfully');
90 const handleError = () => {
91 setError('Failed to load MeshCentral. Please check your connection.');
95 const openInNewWindow = () => {
97 window.open(iframeUrl, '_blank', 'width=1400,height=900');
101 const retry = () => {
102 window.location.reload();
106 <div className="meshcentral-embed-container">
107 <div className="meshcentral-header">
109 <div className="meshcentral-actions">
111 <span className="session-info">
112 Connected to {sessionInfo.agent?.hostname || 'device'}
116 <button onClick={openInNewWindow} className="btn btn-secondary">
117 <span className="material-symbols-outlined">open_in_new</span>
124 {loading && !error && (
125 <div className="meshcentral-loading">
126 <div className="spinner"></div>
127 <p>Connecting to MeshCentral...</p>
128 <p className="loading-hint">Establishing secure session</p>
133 <div className="meshcentral-error">
134 <div className="error-icon">❌</div>
136 <div className="error-actions">
137 <button onClick={retry} className="btn btn-primary">
141 <button onClick={openInNewWindow} className="btn btn-secondary">
142 Open in New Window Instead
153 className="meshcentral-iframe"
155 sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-downloads allow-modals"
157 onError={handleError}
158 style={{ display: loading || error ? 'none' : 'block' }}
165// Export view mode constants for easy use
166export const VIEWMODE = {