chore: ship the full working frontend + backend
Docker / publish (push) Canceled after 0s
Release / crates-io (push) Canceled after 0s
Release / release (macos-14, aarch64-apple-darwin) (push) Canceled after 0s
Release / release (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Canceled after 0s
Release / release (windows-latest, x86_64-pc-windows-msvc) (push) Canceled after 0s

The crates.io/release build shipped a STALE frontend (committed web/js was behind
the working tree), so the admin console hung on load. Commit the current working
web/js (app, api, dashboard, login, import view, i18n de/es/fr/tr/zh, css) and the
backend WIP (import.rs, admin/assets.rs) so the released console matches the dev
build. Verified: clean `cargo build --release`, empty-pool start, working
dashboard served.
This commit is contained in:
infosave2007
2026-07-08 17:58:31 +03:00
parent 0f89cdaa07
commit 25f93d1a27
15 changed files with 597 additions and 18 deletions
+24 -2
View File
@@ -5,6 +5,7 @@ import { api, getToken, setToken, setUnauthorizedHandler } from "./api.js";
import { renderLogin } from "./views/login.js";
import { renderDashboard } from "./views/dashboard.js";
import { renderModels } from "./views/models.js";
import { renderImport } from "./views/import.js";
import { renderRouting } from "./views/routing.js";
import { renderProtocols } from "./views/protocols.js";
import { renderKeys } from "./views/keys.js";
@@ -14,6 +15,7 @@ import { renderSettings } from "./views/settings.js";
const ROUTES = [
{ id: "dashboard", icon: "▤", view: renderDashboard },
{ id: "models", icon: "▦", view: renderModels },
{ id: "import", icon: "⬇", view: renderImport },
{ id: "routing", icon: "⇄", view: renderRouting },
{ id: "protocols", icon: "⇆", view: renderProtocols },
{ id: "keys", icon: "🔑", view: renderKeys },
@@ -23,6 +25,9 @@ const ROUTES = [
export const appState = { meta: null, health: null, version: "" };
// allaigate site — where router keys are issued and topped up
export const SITE_URL = "https://api.allaigate.com/";
function currentRoute() {
const id = location.hash.replace(/^#\/?/, "") || "dashboard";
return ROUTES.find((r) => r.id === id) || ROUTES[0];
@@ -53,6 +58,13 @@ function sidebar(activeId) {
)
),
h("div", { class: "nav-spacer" }),
h(
"a",
{ class: "nav-item", href: SITE_URL, target: "_blank", rel: "noopener" },
h("span", { class: "ico" }, "◈"),
t("nav.billing"),
h("span", { style: "margin-left:auto;opacity:.55" }, "↗")
),
h("div", { class: "nav-foot" }, t("nav.foot", { v: appState.version || "—" }))
);
}
@@ -61,6 +73,16 @@ function statusPills() {
const h_ = appState.health;
const gwOk = !!appState.meta;
const routerOk = h_?.router?.reachable;
// reachable but no key resolves → warn: routing silently degrades to default
const keyMissing = h_?.router?.key_source === "missing";
const routerDot = h_ ? (routerOk ? (keyMissing ? "warn" : "ok") : "bad") : "warn";
const routerText = h_
? routerOk
? keyMissing
? t("status.noKey")
: t("status.online")
: t("status.offline")
: t("status.checking");
return h(
"div",
{ class: "flex" },
@@ -73,8 +95,8 @@ function statusPills() {
h(
"span",
{ class: "pill", title: h_?.router?.url || "" },
h("span", { class: "dot " + (h_ ? (routerOk ? "ok" : "bad") : "warn") }),
t("status.router") + ": " + (h_ ? (routerOk ? t("status.online") : t("status.offline")) : t("status.checking"))
h("span", { class: "dot " + routerDot }),
t("status.router") + ": " + routerText
)
);
}