Spaces:
Sleeping
Sleeping
refactor: update dashboard UI layout, improve sync status handling, and clean up code formatting
Browse files- health-server.js +48 -20
health-server.js
CHANGED
|
@@ -9,7 +9,6 @@ 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 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";
|
|
@@ -31,15 +30,18 @@ function parseRequestUrl(url) {
|
|
| 31 |
}
|
| 32 |
|
| 33 |
function isDashboardRoute(pathname) {
|
| 34 |
-
return
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
}
|
| 40 |
|
| 41 |
function isDashboardAppRoute(pathname) {
|
| 42 |
-
return
|
|
|
|
|
|
|
|
|
|
| 43 |
}
|
| 44 |
|
| 45 |
function isAppRoute(pathname) {
|
|
@@ -143,7 +145,7 @@ function renderSyncBadge(syncData) {
|
|
| 143 |
let badgeClass = "status-offline";
|
| 144 |
let pulseHtml = "";
|
| 145 |
|
| 146 |
-
if (syncData.status === "success") {
|
| 147 |
badgeClass = "status-online";
|
| 148 |
pulseHtml = '<div class="pulse"></div>';
|
| 149 |
} else if (syncData.status === "syncing") {
|
|
@@ -155,7 +157,7 @@ function renderSyncBadge(syncData) {
|
|
| 155 |
}
|
| 156 |
|
| 157 |
function renderDashboard(initialData) {
|
| 158 |
-
const controlUiHref = `${
|
| 159 |
return `
|
| 160 |
<!DOCTYPE html>
|
| 161 |
<html lang="en">
|
|
@@ -333,6 +335,18 @@ function renderDashboard(initialData) {
|
|
| 333 |
|
| 334 |
#sync-msg { color: var(--text); display: block; margin-top: 4px; }
|
| 335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
.helper-card {
|
| 337 |
width: 100%;
|
| 338 |
margin-top: 20px;
|
|
@@ -485,6 +499,11 @@ function renderDashboard(initialData) {
|
|
| 485 |
padding: 16px;
|
| 486 |
}
|
| 487 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 488 |
.helper-row {
|
| 489 |
flex-direction: column;
|
| 490 |
}
|
|
@@ -515,18 +534,20 @@ function renderDashboard(initialData) {
|
|
| 515 |
</div>
|
| 516 |
<div class="stat-card">
|
| 517 |
<span class="stat-label">WhatsApp</span>
|
| 518 |
-
<span id="wa-status">${renderChannelBadge(initialData.whatsapp,
|
| 519 |
</div>
|
| 520 |
<div class="stat-card">
|
| 521 |
<span class="stat-label">Telegram</span>
|
| 522 |
-
<span id="tg-status">${renderChannelBadge(initialData.telegram,
|
| 523 |
</div>
|
| 524 |
<a href="${controlUiHref}" id="control-ui-link" class="stat-btn">Open Control UI</a>
|
| 525 |
</div>
|
| 526 |
|
| 527 |
<div class="stat-card" style="width: 100%;">
|
| 528 |
-
<
|
| 529 |
-
|
|
|
|
|
|
|
| 530 |
<div class="sync-info">
|
| 531 |
Last Sync Activity: <span id="sync-time">${initialData.sync.timestamp || "Never"}</span>
|
| 532 |
<span id="sync-msg">${initialData.sync.message || "Waiting for first sync..."}</span>
|
|
@@ -611,7 +632,7 @@ function renderDashboard(initialData) {
|
|
| 611 |
let badgeClass = 'status-offline';
|
| 612 |
let pulseHtml = '';
|
| 613 |
|
| 614 |
-
if (syncData.status === 'success') {
|
| 615 |
badgeClass = 'status-online';
|
| 616 |
pulseHtml = '<div class="pulse"></div>';
|
| 617 |
} else if (syncData.status === 'syncing') {
|
|
@@ -885,7 +906,13 @@ function serializeUpgradeHeaders(req, remoteAddress) {
|
|
| 885 |
return forwardedHeaders;
|
| 886 |
}
|
| 887 |
|
| 888 |
-
function proxyUpgrade(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 889 |
const proxySocket = net.connect(proxyPort, GATEWAY_HOST);
|
| 890 |
|
| 891 |
proxySocket.on("connect", () => {
|
|
@@ -957,7 +984,10 @@ const server = http.createServer((req, res) => {
|
|
| 957 |
return;
|
| 958 |
}
|
| 959 |
|
| 960 |
-
if (
|
|
|
|
|
|
|
|
|
|
| 961 |
if (req.method !== "POST") {
|
| 962 |
res.writeHead(405, { "Content-Type": "application/json" });
|
| 963 |
res.end(JSON.stringify({ message: "Method not allowed" }));
|
|
@@ -1017,8 +1047,7 @@ const server = http.createServer((req, res) => {
|
|
| 1017 |
}
|
| 1018 |
|
| 1019 |
if (isDashboardAppRoute(pathname) || isAppRoute(pathname)) {
|
| 1020 |
-
const proxyPath =
|
| 1021 |
-
mapAppProxyPath(pathname) + (parsedUrl.search || "");
|
| 1022 |
proxyHttp(req, res, proxyPath, GATEWAY_PORT);
|
| 1023 |
return;
|
| 1024 |
}
|
|
@@ -1035,8 +1064,7 @@ server.on("upgrade", (req, socket, head) => {
|
|
| 1035 |
|
| 1036 |
if (isDashboardAppRoute(pathname) || isAppRoute(pathname)) {
|
| 1037 |
const parsedUrl = parseRequestUrl(req.url || "/");
|
| 1038 |
-
const proxyPath =
|
| 1039 |
-
mapAppProxyPath(pathname) + (parsedUrl.search || "");
|
| 1040 |
proxyUpgrade(req, socket, head, proxyPath, GATEWAY_PORT);
|
| 1041 |
return;
|
| 1042 |
}
|
|
|
|
| 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";
|
|
|
|
| 30 |
}
|
| 31 |
|
| 32 |
function isDashboardRoute(pathname) {
|
| 33 |
+
return (
|
| 34 |
+
pathname === "/" ||
|
| 35 |
+
pathname === DASHBOARD_BASE ||
|
| 36 |
+
pathname === `${DASHBOARD_BASE}/`
|
| 37 |
+
);
|
| 38 |
}
|
| 39 |
|
| 40 |
function isDashboardAppRoute(pathname) {
|
| 41 |
+
return (
|
| 42 |
+
pathname === DASHBOARD_APP_BASE ||
|
| 43 |
+
pathname.startsWith(`${DASHBOARD_APP_BASE}/`)
|
| 44 |
+
);
|
| 45 |
}
|
| 46 |
|
| 47 |
function isAppRoute(pathname) {
|
|
|
|
| 145 |
let badgeClass = "status-offline";
|
| 146 |
let pulseHtml = "";
|
| 147 |
|
| 148 |
+
if (syncData.status === "success" || syncData.status === "configured") {
|
| 149 |
badgeClass = "status-online";
|
| 150 |
pulseHtml = '<div class="pulse"></div>';
|
| 151 |
} else if (syncData.status === "syncing") {
|
|
|
|
| 157 |
}
|
| 158 |
|
| 159 |
function renderDashboard(initialData) {
|
| 160 |
+
const controlUiHref = `${APP_BASE}/`;
|
| 161 |
return `
|
| 162 |
<!DOCTYPE html>
|
| 163 |
<html lang="en">
|
|
|
|
| 335 |
|
| 336 |
#sync-msg { color: var(--text); display: block; margin-top: 4px; }
|
| 337 |
|
| 338 |
+
.card-header {
|
| 339 |
+
display: flex;
|
| 340 |
+
align-items: center;
|
| 341 |
+
justify-content: space-between;
|
| 342 |
+
gap: 12px;
|
| 343 |
+
margin-bottom: 8px;
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
.card-header .stat-label {
|
| 347 |
+
margin-bottom: 0;
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
.helper-card {
|
| 351 |
width: 100%;
|
| 352 |
margin-top: 20px;
|
|
|
|
| 499 |
padding: 16px;
|
| 500 |
}
|
| 501 |
|
| 502 |
+
.card-header {
|
| 503 |
+
align-items: flex-start;
|
| 504 |
+
flex-direction: column;
|
| 505 |
+
}
|
| 506 |
+
|
| 507 |
.helper-row {
|
| 508 |
flex-direction: column;
|
| 509 |
}
|
|
|
|
| 534 |
</div>
|
| 535 |
<div class="stat-card">
|
| 536 |
<span class="stat-label">WhatsApp</span>
|
| 537 |
+
<span id="wa-status">${renderChannelBadge(initialData.whatsapp, "Ready to pair")}</span>
|
| 538 |
</div>
|
| 539 |
<div class="stat-card">
|
| 540 |
<span class="stat-label">Telegram</span>
|
| 541 |
+
<span id="tg-status">${renderChannelBadge(initialData.telegram, "Configured")}</span>
|
| 542 |
</div>
|
| 543 |
<a href="${controlUiHref}" id="control-ui-link" class="stat-btn">Open Control UI</a>
|
| 544 |
</div>
|
| 545 |
|
| 546 |
<div class="stat-card" style="width: 100%;">
|
| 547 |
+
<div class="card-header">
|
| 548 |
+
<span class="stat-label">Workspace Sync Status</span>
|
| 549 |
+
<div id="sync-badge-container">${renderSyncBadge(initialData.sync)}</div>
|
| 550 |
+
</div>
|
| 551 |
<div class="sync-info">
|
| 552 |
Last Sync Activity: <span id="sync-time">${initialData.sync.timestamp || "Never"}</span>
|
| 553 |
<span id="sync-msg">${initialData.sync.message || "Waiting for first sync..."}</span>
|
|
|
|
| 632 |
let badgeClass = 'status-offline';
|
| 633 |
let pulseHtml = '';
|
| 634 |
|
| 635 |
+
if (syncData.status === 'success' || syncData.status === 'configured') {
|
| 636 |
badgeClass = 'status-online';
|
| 637 |
pulseHtml = '<div class="pulse"></div>';
|
| 638 |
} else if (syncData.status === 'syncing') {
|
|
|
|
| 906 |
return forwardedHeaders;
|
| 907 |
}
|
| 908 |
|
| 909 |
+
function proxyUpgrade(
|
| 910 |
+
req,
|
| 911 |
+
socket,
|
| 912 |
+
head,
|
| 913 |
+
proxyPath = req.url,
|
| 914 |
+
proxyPort = GATEWAY_PORT,
|
| 915 |
+
) {
|
| 916 |
const proxySocket = net.connect(proxyPort, GATEWAY_HOST);
|
| 917 |
|
| 918 |
proxySocket.on("connect", () => {
|
|
|
|
| 984 |
return;
|
| 985 |
}
|
| 986 |
|
| 987 |
+
if (
|
| 988 |
+
pathname === "/uptimerobot/setup" ||
|
| 989 |
+
pathname === DASHBOARD_UPTIMEROBOT_PATH
|
| 990 |
+
) {
|
| 991 |
if (req.method !== "POST") {
|
| 992 |
res.writeHead(405, { "Content-Type": "application/json" });
|
| 993 |
res.end(JSON.stringify({ message: "Method not allowed" }));
|
|
|
|
| 1047 |
}
|
| 1048 |
|
| 1049 |
if (isDashboardAppRoute(pathname) || isAppRoute(pathname)) {
|
| 1050 |
+
const proxyPath = mapAppProxyPath(pathname) + (parsedUrl.search || "");
|
|
|
|
| 1051 |
proxyHttp(req, res, proxyPath, GATEWAY_PORT);
|
| 1052 |
return;
|
| 1053 |
}
|
|
|
|
| 1064 |
|
| 1065 |
if (isDashboardAppRoute(pathname) || isAppRoute(pathname)) {
|
| 1066 |
const parsedUrl = parseRequestUrl(req.url || "/");
|
| 1067 |
+
const proxyPath = mapAppProxyPath(pathname) + (parsedUrl.search || "");
|
|
|
|
| 1068 |
proxyUpgrade(req, socket, head, proxyPath, GATEWAY_PORT);
|
| 1069 |
return;
|
| 1070 |
}
|