Upload folder using huggingface_hub
Browse files- dashboard/index.html +1 -0
- dashboard/src/App.tsx +16 -2
- internal/dashboard/dashboard.go +10 -1
dashboard/index.html
CHANGED
|
@@ -4,6 +4,7 @@
|
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<link rel="icon" type="image/png" href="/favicon.png" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
| 7 |
<title>PinchTab</title>
|
| 8 |
</head>
|
| 9 |
<body>
|
|
|
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<link rel="icon" type="image/png" href="/favicon.png" />
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
+
<meta name="pinchtab-token" content="{{PINCHTAB_TOKEN_INJECT}}" />
|
| 8 |
<title>PinchTab</title>
|
| 9 |
</head>
|
| 10 |
<body>
|
dashboard/src/App.tsx
CHANGED
|
@@ -34,15 +34,29 @@ function AppContent() {
|
|
| 34 |
const navigate = useNavigate();
|
| 35 |
const memoryMetricsEnabled = settings.monitoring?.memoryMetrics ?? false;
|
| 36 |
// Auto-login from ?token= query parameter (e.g. from wizard URL)
|
|
|
|
| 37 |
useEffect(() => {
|
| 38 |
const params = new URLSearchParams(window.location.search);
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
if (urlToken) {
|
| 41 |
setStoredAuthToken(urlToken);
|
| 42 |
const clean = new URL(window.location.href);
|
| 43 |
clean.searchParams.delete("token");
|
| 44 |
window.history.replaceState({}, "", clean.pathname + clean.hash);
|
| 45 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
}
|
| 47 |
}, []);
|
| 48 |
|
|
|
|
| 34 |
const navigate = useNavigate();
|
| 35 |
const memoryMetricsEnabled = settings.monitoring?.memoryMetrics ?? false;
|
| 36 |
// Auto-login from ?token= query parameter (e.g. from wizard URL)
|
| 37 |
+
// or injected meta tag for Hugging Face Spaces integration
|
| 38 |
useEffect(() => {
|
| 39 |
const params = new URLSearchParams(window.location.search);
|
| 40 |
+
let urlToken = params.get("token");
|
| 41 |
+
if (!urlToken) {
|
| 42 |
+
const meta = document.querySelector("meta[name='pinchtab-token']");
|
| 43 |
+
const metaContent = meta?.getAttribute("content") || "";
|
| 44 |
+
// Exclude the unreplaced template literal from injection
|
| 45 |
+
if (metaContent && metaContent !== "{{PINCHTAB_TOKEN_INJECT}}") {
|
| 46 |
+
urlToken = metaContent;
|
| 47 |
+
}
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
if (urlToken) {
|
| 51 |
setStoredAuthToken(urlToken);
|
| 52 |
const clean = new URL(window.location.href);
|
| 53 |
clean.searchParams.delete("token");
|
| 54 |
window.history.replaceState({}, "", clean.pathname + clean.hash);
|
| 55 |
+
// Let the main login flow handle reload if necessary, but actually
|
| 56 |
+
// if we just updated localStorage we want to reload so state is updated
|
| 57 |
+
if (getStoredAuthToken() !== urlToken) {
|
| 58 |
+
window.location.reload();
|
| 59 |
+
}
|
| 60 |
}
|
| 61 |
}, []);
|
| 62 |
|
internal/dashboard/dashboard.go
CHANGED
|
@@ -8,6 +8,7 @@ import (
|
|
| 8 |
"io/fs"
|
| 9 |
"net/http"
|
| 10 |
"os"
|
|
|
|
| 11 |
"sync"
|
| 12 |
"time"
|
| 13 |
|
|
@@ -237,7 +238,15 @@ func (d *Dashboard) handleDashboardUI(w http.ResponseWriter, r *http.Request) {
|
|
| 237 |
_, _ = w.Write([]byte(fallbackHTML))
|
| 238 |
return
|
| 239 |
}
|
| 240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
}
|
| 242 |
|
| 243 |
func (d *Dashboard) withNoCache(next http.Handler) http.Handler {
|
|
|
|
| 8 |
"io/fs"
|
| 9 |
"net/http"
|
| 10 |
"os"
|
| 11 |
+
"strings"
|
| 12 |
"sync"
|
| 13 |
"time"
|
| 14 |
|
|
|
|
| 238 |
_, _ = w.Write([]byte(fallbackHTML))
|
| 239 |
return
|
| 240 |
}
|
| 241 |
+
|
| 242 |
+
htmlStr := string(data)
|
| 243 |
+
token := os.Getenv("PINCHTAB_TOKEN")
|
| 244 |
+
if token == "" {
|
| 245 |
+
token = os.Getenv("BEARER_TOKEN")
|
| 246 |
+
}
|
| 247 |
+
htmlStr = strings.ReplaceAll(htmlStr, "{{PINCHTAB_TOKEN_INJECT}}", token)
|
| 248 |
+
|
| 249 |
+
_, _ = w.Write([]byte(htmlStr))
|
| 250 |
}
|
| 251 |
|
| 252 |
func (d *Dashboard) withNoCache(next http.Handler) http.Handler {
|