diff --git a/server/static/dashboard.html b/server/static/dashboard.html
index ebcd78c..b3c2093 100644
--- a/server/static/dashboard.html
+++ b/server/static/dashboard.html
@@ -330,6 +330,52 @@
}
.chat-send:hover { opacity: 0.9; }
.chat-send:disabled { opacity: 0.5; cursor: not-allowed; }
+
+ /* Connect Options Modal */
+ .connect-options { padding: 20px; }
+ .connect-option {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ padding: 16px;
+ margin-bottom: 12px;
+ background: hsl(var(--muted));
+ border: 1px solid hsl(var(--border));
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.2s;
+ }
+ .connect-option:hover { border-color: hsl(var(--primary)); background: hsla(var(--primary), 0.1); }
+ .connect-option-icon { font-size: 24px; width: 40px; text-align: center; }
+ .connect-option-info { flex: 1; }
+ .connect-option-title { font-weight: 600; margin-bottom: 4px; }
+ .connect-option-desc { font-size: 12px; color: hsl(var(--muted-foreground)); }
+
+ .native-command {
+ margin-top: 16px;
+ padding: 12px;
+ background: hsl(222.2 84% 2%);
+ border: 1px solid hsl(var(--border));
+ border-radius: 6px;
+ font-family: monospace;
+ font-size: 12px;
+ word-break: break-all;
+ position: relative;
+ }
+ .native-command code { color: hsl(142, 76%, 50%); }
+ .copy-btn {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ padding: 4px 8px;
+ font-size: 11px;
+ background: hsl(var(--primary));
+ color: hsl(var(--primary-foreground));
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ }
+ .copy-btn:hover { opacity: 0.9; }
@@ -528,6 +574,41 @@
+
+
@@ -843,10 +924,65 @@
'
';
}
+ // Connect modal state
+ let connectSessionId = null;
+ let connectMachineName = null;
+
+ const connectModal = document.getElementById("connectModal");
+ const connectClose = document.getElementById("connectClose");
+ const connectWeb = document.getElementById("connectWeb");
+ const connectNative = document.getElementById("connectNative");
+ const nativeCommandContainer = document.getElementById("nativeCommandContainer");
+ const nativeCommandText = document.getElementById("nativeCommandText");
+ const connectMachineNameEl = document.getElementById("connectMachineName");
+
+ connectClose.addEventListener("click", () => {
+ connectModal.classList.remove("active");
+ nativeCommandContainer.style.display = "none";
+ });
+
+ connectModal.addEventListener("click", (e) => {
+ if (e.target === connectModal) {
+ connectModal.classList.remove("active");
+ nativeCommandContainer.style.display = "none";
+ }
+ });
+
+ connectWeb.addEventListener("click", () => {
+ if (connectSessionId) {
+ const viewerUrl = "/viewer.html?session_id=" + connectSessionId;
+ window.open(viewerUrl, "viewer_" + connectSessionId, "width=1280,height=800,menubar=no,toolbar=no,location=no,status=no");
+ connectModal.classList.remove("active");
+ nativeCommandContainer.style.display = "none";
+ }
+ });
+
+ connectNative.addEventListener("click", () => {
+ if (connectSessionId) {
+ const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
+ const serverUrl = protocol + "//" + window.location.host + "/ws/viewer";
+ const cmd = `guruconnect-viewer.exe -i ${connectSessionId} -s ${serverUrl}`;
+ nativeCommandText.textContent = cmd;
+ nativeCommandContainer.style.display = "block";
+ }
+ });
+
+ function copyNativeCommand() {
+ const cmd = nativeCommandText.textContent;
+ navigator.clipboard.writeText(cmd).then(() => {
+ const btn = document.querySelector(".copy-btn");
+ btn.textContent = "Copied!";
+ setTimeout(() => btn.textContent = "Copy", 2000);
+ });
+ }
+
function connectToMachine(sessionId) {
- // Open viewer in new window
- const viewerUrl = "/viewer.html?session_id=" + sessionId;
- window.open(viewerUrl, "viewer_" + sessionId, "width=1280,height=800,menubar=no,toolbar=no,location=no,status=no");
+ const machine = machines.find(m => m.id === sessionId);
+ connectSessionId = sessionId;
+ connectMachineName = machine?.agent_name || sessionId.slice(0, 8);
+ connectMachineNameEl.textContent = connectMachineName;
+ nativeCommandContainer.style.display = "none";
+ connectModal.classList.add("active");
}
async function disconnectMachine(sessionId, machineName) {