mirror of
https://github.com/MeshCore-Beacon/beacon-web.git
synced 2026-09-17 02:34:18 +00:00
67 lines
3.2 KiB
TypeScript
67 lines
3.2 KiB
TypeScript
export const API_BASE = import.meta.env.VITE_API_BASE ?? "http://localhost:8080/api/v1";
|
|
export const WS_URL = import.meta.env.VITE_WS_URL ?? "ws://localhost:8080/ws";
|
|
|
|
export const LIVE_BUFFER_CAP = 500;
|
|
export const MAX_INFINITE_PAGES = 20;
|
|
export const DEFAULT_PAGE_SIZE = 50;
|
|
|
|
export const SCROLL_TOP_THRESHOLD_PX = 100;
|
|
export const SCROLL_BOTTOM_THRESHOLD_PX = 500;
|
|
|
|
export const WS_PING_INTERVAL_MS = 30_000;
|
|
export const WS_RECONNECT_BASE_MS = 1000;
|
|
export const WS_RECONNECT_MAX_MS = 30_000;
|
|
export const WS_RECONNECT_JITTER = 0.25;
|
|
|
|
// app tab names, in display order; the ?tab URL param is validated against this list
|
|
export const TABS = ["Packets", "Channels", "Map", "Nodes", "Observers", "Routes", "Traces", "Analytics"] as const;
|
|
|
|
// Per-deployment .env config (VITE_* prefix is required so the build can expose it to the browser;
|
|
// the Docker entrypoint sed-substitutes each sentinel at container start — see .build/).
|
|
|
|
// Split a comma-separated env value into trimmed, non-empty entries. An unset var or an
|
|
// un-substituted "__VITE_..__" sentinel yields a harmless single entry that matches nothing.
|
|
export function parseEnvList(raw: string | undefined): string[] {
|
|
return (raw ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
}
|
|
|
|
// Tabs left after removing the disabled ones (case-insensitive), keeping display order.
|
|
export function filterEnabledTabs(tabs: readonly string[], disabledRaw: string | undefined): string[] {
|
|
const disabled = new Set(parseEnvList(disabledRaw).map((t) => t.toLowerCase()));
|
|
return tabs.filter((t) => !disabled.has(t.toLowerCase()));
|
|
}
|
|
|
|
// Truthy env flag: "1"/"true"/"yes"/"on" (case-insensitive). Anything else — empty, unset, or an
|
|
// un-substituted sentinel — is false, so the gated behaviour only turns on when explicitly asked for.
|
|
export function parseEnvBool(raw: string | undefined): boolean {
|
|
return ["1", "true", "yes", "on"].includes((raw ?? "").trim().toLowerCase());
|
|
}
|
|
|
|
// The themes offered in the picker. When VITE_ENABLED_THEMES lists ids it's an EXCLUSIVE allowlist —
|
|
// only those show (e.g. a branded deployment that wants just its own themes). Otherwise every
|
|
// non-hidden theme shows and `hidden` ones (like the MeshMapper pair) stay out.
|
|
export function selectableThemes<T extends { id: string; hidden?: boolean }>(
|
|
themes: readonly T[],
|
|
enabledIds: Set<string>,
|
|
): T[] {
|
|
if (enabledIds.size > 0) {
|
|
return themes.filter((t) => enabledIds.has(t.id.toLowerCase()));
|
|
}
|
|
return themes.filter((t) => !t.hidden);
|
|
}
|
|
|
|
const enabledTabs = filterEnabledTabs(TABS, import.meta.env.VITE_DISABLED_TABS);
|
|
// Floor: an all-disabled misconfig would otherwise leave a blank app.
|
|
export const ENABLED_TABS = enabledTabs.length > 0 ? enabledTabs : [...TABS];
|
|
|
|
export const ENABLED_THEME_IDS = new Set(
|
|
parseEnvList(import.meta.env.VITE_ENABLED_THEMES).map((s) => s.toLowerCase()),
|
|
);
|
|
|
|
// "||" (not "??") so an empty sed substitution falls back to the default too.
|
|
export const APP_NAME = import.meta.env.VITE_APP_NAME || "BEACON";
|
|
export const GITHUB_URL = "https://github.com/MeshCore-Beacon";
|
|
|
|
// Skip the once-per-session load splash entirely (e.g. an embedded/branded deployment).
|
|
export const SKIP_SPLASH = parseEnvBool(import.meta.env.VITE_SKIP_SPLASH);
|