EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
RemoteDesktop.jsx
Go to the documentation of this file.
1import { useState, useEffect, useRef } from 'react';
2import {
3 Dialog,
4 DialogContent,
5 DialogHeader,
6 DialogTitle,
7 DialogDescription,
8} from '@/components/ui/dialog';
9import { Button } from '@/components/ui/button';
10import { Input } from '@/components/ui/input';
11import { Label } from '@/components/ui/label';
12import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
13import { Monitor, X, Loader2, AlertCircle } from 'lucide-react';
14import { Alert, AlertDescription } from '@/components/ui/alert';
15
16/**
17 * RemoteDesktop Component
18 * Provides web-based remote desktop access using MeshCentral
19 */
20export function RemoteDesktop({ agent, open, onClose }) {
21 const [loading, setLoading] = useState(false);
22 const [error, setError] = useState(null);
23 const [connectionUrl, setConnectionUrl] = useState(null);
24 const [meshInfo, setMeshInfo] = useState(null);
25 const iframeRef = useRef(null);
26
27 useEffect(() => {
28 if (open && agent) {
29 loadMeshCentralUrl();
30 }
31 }, [open, agent]);
32
33 const loadMeshCentralUrl = async () => {
34 setLoading(true);
35 setError(null);
36
37 try {
38 // Get MeshCentral URL for this agent
39 const agentId = agent.agent_uuid || agent.agent_id;
40 const response = await fetch(`/api/agent/${agentId}/meshcentral-url`);
41
42 if (!response.ok) {
43 const errorData = await response.json();
44 throw new Error(errorData.error || 'Failed to get MeshCentral URL');
45 }
46
47 const data = await response.json();
48 setMeshInfo(data);
49
50 } catch (err) {
51 console.error('Failed to load MeshCentral URL:', err);
52 setError(err.message);
53 } finally {
54 setLoading(false);
55 }
56 };
57
58 const handleConnect = () => {
59 if (meshInfo?.remoteDesktopUrl) {
60 // Open MeshCentral in new window
61 window.open(meshInfo.remoteDesktopUrl, '_blank', 'width=1400,height=900');
62 }
63 };
64
65 const handleConnectInline = () => {
66 if (meshInfo?.remoteDesktopUrl) {
67 setConnectionUrl(meshInfo.remoteDesktopUrl);
68 }
69 };
70
71 const handleDisconnect = () => {
72 setConnectionUrl(null);
73 };
74
75 const handleClose = () => {
76 handleDisconnect();
77 onClose();
78 };
79
80 if (!agent) return null;
81
82 return (
83 <Dialog open={open} onOpenChange={handleClose}>
84 <DialogContent className="max-w-[95vw] max-h-[95vh] w-[1400px] h-[900px]">
85 <DialogHeader>
86 <DialogTitle className="flex items-center gap-2">
87 <Monitor className="h-5 w-5" />
88 Remote Desktop - {agent.hostname || agent.agent_id}
89 </DialogTitle>
90 <DialogDescription>
91 {agent.last_ip && `Connecting to ${agent.last_ip}`}
92 </DialogDescription>
93 </DialogHeader>
94
95 {!connectionUrl ? (
96 <div className="space-y-4 py-4">
97 {error && (
98 <Alert variant="destructive">
99 <AlertCircle className="h-4 w-4" />
100 <AlertDescription>{error}</AlertDescription>
101 </Alert>
102 )}
103
104 {loading ? (
105 <div className="flex items-center justify-center py-8">
106 <Loader2 className="h-8 w-8 animate-spin text-primary" />
107 <span className="ml-2">Loading MeshCentral connection...</span>
108 </div>
109 ) : meshInfo ? (
110 <div className="space-y-4">
111 <div className="text-sm space-y-2">
112 <p className="font-medium">MeshCentral Remote Desktop</p>
113 <ul className="space-y-1 text-muted-foreground">
114 <li>• Hostname: {meshInfo.hostname}</li>
115 <li>• Agent ID: {meshInfo.agentId}</li>
116 <li>• Node ID: {meshInfo.meshcentralNodeId}</li>
117 </ul>
118 </div>
119
120 <div className="flex gap-2 pt-4">
121 <Button onClick={handleConnect} className="flex-1">
122 <Monitor className="mr-2 h-4 w-4" />
123 Open in New Window
124 </Button>
125 <Button variant="outline" onClick={handleConnectInline} className="flex-1">
126 Open Inline
127 </Button>
128 </div>
129
130 <Button variant="outline" onClick={handleClose} className="w-full">
131 Cancel
132 </Button>
133 </div>
134 ) : (
135 <div className="text-center py-8 text-muted-foreground">
136 <AlertCircle className="h-8 w-8 mx-auto mb-2" />
137 <p>MeshCentral not configured for this agent</p>
138 </div>
139 )}
140 </div>
141 ) : (
142 <div className="flex flex-col h-full">
143 <div className="flex items-center justify-between mb-2">
144 <span className="text-sm text-muted-foreground">
145 MeshCentral Remote Desktop - {meshInfo?.hostname}
146 </span>
147 <Button variant="destructive" size="sm" onClick={handleDisconnect}>
148 <X className="h-4 w-4 mr-1" />
149 Close
150 </Button>
151 </div>
152
153 <div className="flex-1 border rounded-lg overflow-hidden bg-black">
154 <iframe
155 ref={iframeRef}
156 src={connectionUrl}
157 className="w-full h-full"
158 title="MeshCentral Remote Desktop"
159 allow="clipboard-read; clipboard-write"
160 />
161 </div>
162 </div>
163 )}
164 </DialogContent>
165 </Dialog>
166 );
167}
168
169export default RemoteDesktop;