somratpro commited on
Commit
d9dfa01
·
1 Parent(s): 890b10a

feat: implement server-side dashboard rendering with dynamic status badges and configurable control UI link

Browse files
Files changed (1) hide show
  1. health-server.js +59 -13
health-server.js CHANGED
@@ -9,6 +9,7 @@ const GATEWAY_PORT = 7860;
9
  const GATEWAY_HOST = "127.0.0.1";
10
  const startTime = Date.now();
11
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
 
12
  const TELEGRAM_ENABLED = !!process.env.TELEGRAM_BOT_TOKEN;
13
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
14
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
@@ -35,7 +36,10 @@ function isDashboardScopedPath(pathname, suffix) {
35
  }
36
 
37
  function isDashboardAppRoute(pathname) {
38
- return pathname === DASHBOARD_APP_BASE || pathname.startsWith(`${DASHBOARD_APP_BASE}/`);
 
 
 
39
  }
40
 
41
  function isLocalRoute(pathname) {
@@ -112,7 +116,35 @@ function readGuardianStatus() {
112
  return { configured: true, connected: false, pairing: false };
113
  }
114
 
115
- function renderDashboard() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  return `
117
  <!DOCTYPE html>
118
  <html lang="en">
@@ -464,29 +496,29 @@ function renderDashboard() {
464
  <div class="stats-grid">
465
  <div class="stat-card">
466
  <span class="stat-label">Model</span>
467
- <span class="stat-value" id="model-id">Loading...</span>
468
  </div>
469
  <div class="stat-card">
470
  <span class="stat-label">Uptime</span>
471
- <span class="stat-value" id="uptime">Loading...</span>
472
  </div>
473
  <div class="stat-card">
474
  <span class="stat-label">WhatsApp</span>
475
- <span id="wa-status">Loading...</span>
476
  </div>
477
  <div class="stat-card">
478
  <span class="stat-label">Telegram</span>
479
- <span id="tg-status">Loading...</span>
480
  </div>
481
- <a href="#" id="control-ui-link" class="stat-btn">Open Control UI</a>
482
  </div>
483
 
484
  <div class="stat-card" style="width: 100%;">
485
  <span class="stat-label">Workspace Sync Status</span>
486
- <div id="sync-badge-container"></div>
487
  <div class="sync-info">
488
- Last Sync Activity: <span id="sync-time">Never</span>
489
- <span id="sync-msg">Initializing synchronization...</span>
490
  </div>
491
  </div>
492
 
@@ -660,7 +692,6 @@ function renderDashboard() {
660
  updateStats();
661
  setInterval(updateStats, 10000);
662
  restoreMonitorUiState();
663
- document.getElementById('control-ui-link').setAttribute('href', getDashboardBase() + '/app/');
664
  document.getElementById('uptimerobot-btn').addEventListener('click', setupUptimeRobot);
665
  document.getElementById('uptimerobot-toggle').addEventListener('click', toggleMonitorSetup);
666
  </script>
@@ -908,7 +939,10 @@ const server = http.createServer((req, res) => {
908
  return;
909
  }
910
 
911
- if (pathname === "/uptimerobot/setup" || pathname === DASHBOARD_UPTIMEROBOT_PATH) {
 
 
 
912
  if (req.method !== "POST") {
913
  res.writeHead(405, { "Content-Type": "application/json" });
914
  res.end(JSON.stringify({ message: "Method not allowed" }));
@@ -950,8 +984,20 @@ const server = http.createServer((req, res) => {
950
  }
951
 
952
  if (isDashboardRoute(pathname)) {
 
 
 
 
 
 
 
 
 
 
 
 
953
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
954
- res.end(renderDashboard());
955
  return;
956
  }
957
 
 
9
  const GATEWAY_HOST = "127.0.0.1";
10
  const startTime = Date.now();
11
  const LLM_MODEL = process.env.LLM_MODEL || "Not Set";
12
+ const SPACE_HOST = process.env.SPACE_HOST || "";
13
  const TELEGRAM_ENABLED = !!process.env.TELEGRAM_BOT_TOKEN;
14
  const WHATSAPP_ENABLED = /^true$/i.test(process.env.WHATSAPP_ENABLED || "");
15
  const WHATSAPP_STATUS_FILE = "/tmp/huggingclaw-wa-status.json";
 
36
  }
37
 
38
  function isDashboardAppRoute(pathname) {
39
+ return (
40
+ pathname === DASHBOARD_APP_BASE ||
41
+ pathname.startsWith(`${DASHBOARD_APP_BASE}/`)
42
+ );
43
  }
44
 
45
  function isLocalRoute(pathname) {
 
116
  return { configured: true, connected: false, pairing: false };
117
  }
118
 
119
+ function renderChannelBadge(channel, configuredLabel) {
120
+ if (channel && channel.connected) {
121
+ return '<div class="status-badge status-online"><div class="pulse"></div>Active</div>';
122
+ }
123
+ if (channel && channel.configured) {
124
+ return `<div class="status-badge status-syncing">${configuredLabel}</div>`;
125
+ }
126
+ return '<div class="status-badge status-offline">Disabled</div>';
127
+ }
128
+
129
+ function renderSyncBadge(syncData) {
130
+ let badgeClass = "status-offline";
131
+ let pulseHtml = "";
132
+
133
+ if (syncData.status === "success") {
134
+ badgeClass = "status-online";
135
+ pulseHtml = '<div class="pulse"></div>';
136
+ } else if (syncData.status === "syncing") {
137
+ badgeClass = "status-syncing";
138
+ pulseHtml = '<div class="pulse" style="background:#3b82f6"></div>';
139
+ }
140
+
141
+ return `<div class="status-badge ${badgeClass}">${pulseHtml}${String(syncData.status || "unknown").toUpperCase()}</div>`;
142
+ }
143
+
144
+ function renderDashboard(initialData) {
145
+ const controlUiHref = SPACE_HOST
146
+ ? `https://${SPACE_HOST}`
147
+ : `${DASHBOARD_APP_BASE}/`;
148
  return `
149
  <!DOCTYPE html>
150
  <html lang="en">
 
496
  <div class="stats-grid">
497
  <div class="stat-card">
498
  <span class="stat-label">Model</span>
499
+ <span class="stat-value" id="model-id">${initialData.model}</span>
500
  </div>
501
  <div class="stat-card">
502
  <span class="stat-label">Uptime</span>
503
+ <span class="stat-value" id="uptime">${initialData.uptime}</span>
504
  </div>
505
  <div class="stat-card">
506
  <span class="stat-label">WhatsApp</span>
507
+ <span id="wa-status">${renderChannelBadge(initialData.whatsapp, "Ready to pair")}</span>
508
  </div>
509
  <div class="stat-card">
510
  <span class="stat-label">Telegram</span>
511
+ <span id="tg-status">${renderChannelBadge(initialData.telegram, "Configured")}</span>
512
  </div>
513
+ <a href="${controlUiHref}" id="control-ui-link" class="stat-btn">Open Control UI</a>
514
  </div>
515
 
516
  <div class="stat-card" style="width: 100%;">
517
  <span class="stat-label">Workspace Sync Status</span>
518
+ <div id="sync-badge-container">${renderSyncBadge(initialData.sync)}</div>
519
  <div class="sync-info">
520
+ Last Sync Activity: <span id="sync-time">${initialData.sync.timestamp || "Never"}</span>
521
+ <span id="sync-msg">${initialData.sync.message || "Waiting for first sync..."}</span>
522
  </div>
523
  </div>
524
 
 
692
  updateStats();
693
  setInterval(updateStats, 10000);
694
  restoreMonitorUiState();
 
695
  document.getElementById('uptimerobot-btn').addEventListener('click', setupUptimeRobot);
696
  document.getElementById('uptimerobot-toggle').addEventListener('click', toggleMonitorSetup);
697
  </script>
 
939
  return;
940
  }
941
 
942
+ if (
943
+ pathname === "/uptimerobot/setup" ||
944
+ pathname === DASHBOARD_UPTIMEROBOT_PATH
945
+ ) {
946
  if (req.method !== "POST") {
947
  res.writeHead(405, { "Content-Type": "application/json" });
948
  res.end(JSON.stringify({ message: "Method not allowed" }));
 
984
  }
985
 
986
  if (isDashboardRoute(pathname)) {
987
+ const guardianStatus = readGuardianStatus();
988
+ const initialData = {
989
+ model: LLM_MODEL,
990
+ whatsapp: {
991
+ configured: guardianStatus.configured,
992
+ connected: guardianStatus.connected,
993
+ pairing: guardianStatus.pairing,
994
+ },
995
+ telegram: normalizeChannelStatus(null, TELEGRAM_ENABLED),
996
+ sync: readSyncStatus(),
997
+ uptime: uptimeHuman,
998
+ };
999
  res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
1000
+ res.end(renderDashboard(initialData));
1001
  return;
1002
  }
1003