Files
o11y/frontend/index.html
3f0c420f9d fix(frontend): unbreak jest, self-host Geist, revive a dead filter (#41)
Three defects the new o11y SPA e2e (universe#533) surfaced against live.

JEST WAS HIDING 3,706 TESTS. jest.config.ts allowlisted lodash-es in
transformIgnorePatterns, but the regex anchors the FIRST node_modules/, and
pnpm's real path is node_modules/.pnpm/lodash-es@x/node_modules/lodash-es/.
The lookahead saw `.pnpm`, so the file matched the IGNORE and was never
transformed -> raw ESM -> SyntaxError at import. One alternative (`\.pnpm/|`)
lets the allowlist judge the inner node_modules/<pkg>/ segment, which is
identical in both layouts. The allowlist itself is unchanged.

  344 of 479 suites dead-on-import  ->  395 passing, 0 transform-blocked.

The 82 that still fail are ordinary assertion/snapshot failures the import
crash was masking. They are NOT fixed here and NOT new. One suite
(AppRoutes/Private.test.tsx) hangs; it never ran before either, so it has no
baseline to regress from, but a bare `pnpm exec jest` no longer terminates.
Both need owners.

GEIST HAS NEVER RENDERED IN PRODUCTION. index.html loaded it from
cdn.jsdelivr.net, which the deployed CSP (style-src 'self' 'unsafe-inline'
https://fonts.googleapis.com) blocks — and the URL was a hard 404 anyway,
because the geist package ships NO CSS in any version, only Next.js
next/font/local loaders. So prod has been rendering fallback sans-serif.
Now self-hosted: [email protected] pinned, the two <link> tags and the orphaned
cdn.vercel.com preconnect deleted, and two @font-face rules in styles.scss on
the VARIABLE woff2 (2 requests, not 18). Text metrics WILL visibly change —
that is the repair, not a regression; there was no working behavior to keep.
The url() is a relative path because geist's exports map blocks the
geist/dist/... subpath — that is load-bearing, not untidiness.

A DEAD SEARCH FILTER. ServiceTable/Columns/GetColumnSearchProps.tsx computed
`.includes(...)`, discarded it, and unconditionally returned false — that
column's filter never matched anything. Its ServiceApplication twin was always
correct; the body is now byte-identical to it. This is a deliberate behavior
change: the filter starts working.

Also: typed useInitializeOverlayScrollbar's useState so
VirtuosoOverlayScrollbar no longer needs ReactElement<any>, and dropped a
redundant `values as {key: string}` cast in ApplyLicenseForm that the
styled(Form<FormValues>) fix made unnecessary.

Verified: tsgo --noEmit 0 errors; pnpm build exit 0; Geist woff2 emitted into
build/ and zero jsdelivr refs in the emitted CSS.

Not fixed, filed instead: @monaco-editor/loader hardcodes a jsdelivr URL for
the whole editor, so Monaco is CSP-blocked in prod the same way (#89 — the fix
is loader.config({monaco}), NOT a CSP allowance); and 5 unreferenced vendored
fonts ship ~1.6MB to every user (#90).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-16 20:56:39 -07:00

116 lines
3.7 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<base href="[[.BaseHref]]" />
<meta
http-equiv="Cache-Control"
content="no-cache, no-store, must-revalidate, max-age: 0"
/>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title data-react-helmet="true">
Hanzo O11y
</title>
<meta
data-react-helmet="true"
property="og:title"
content="Hanzo O11y"
/>
<meta
data-react-helmet="true"
name="description"
content="Hanzo O11y is a unified observability platform for metrics, traces, and logs with deep filtering and aggregation to find and resolve issues quickly."
/>
<meta
data-react-helmet="true"
property="og:description"
content="Hanzo O11y is a unified observability platform for metrics, traces, and logs with deep filtering and aggregation to find and resolve issues quickly."
/>
<meta
data-react-helmet="true"
property="og:image"
content="/Logos/hanzo-icon.svg"
/>
<meta
data-react-helmet="true"
name="twitter:image"
content="/Logos/hanzo-icon.svg"
/>
<meta
data-react-helmet="true"
name="twitter:image:alt"
content="Hanzo O11y"
/>
<meta
data-react-helmet="true"
name="twitter:card"
content="summary_large_image"
/>
<meta data-react-helmet="true" name="docusaurus_locale" content="en" />
<meta data-react-helmet="true" name="docusaurus_tag" content="default" />
<meta name="robots" content="noindex" />
<link data-react-helmet="true" rel="shortcut icon" href="favicon.ico" />
</head>
<body data-theme="default">
<script>
// Apply theme class synchronously before React renders to prevent flash.
// Mirrors the logic in ThemeProvider (hooks/useDarkMode/index.tsx).
(function () {
try {
// When served under a URL prefix (e.g. /o11y/), storage keys are scoped
// to that prefix by the React app (see utils/storage.ts getScopedKey).
// Read the <base> tag — already populated by the Go template — to derive
// the same prefix here, before any JS module has loaded.
var basePath =
(document.querySelector('base') || {}).getAttribute('href') || '/';
var prefix = basePath === '/' ? '' : basePath;
var theme = localStorage.getItem(prefix + 'THEME');
var autoSwitch =
localStorage.getItem(prefix + 'THEME_AUTO_SWITCH') === 'true';
if (autoSwitch) {
theme = window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
if (theme === 'light') {
document.body.classList.add('lightMode');
} else {
// Default to dark when no preference is stored
document.body.classList.add('dark', 'darkMode');
}
} catch (e) {
document.body.classList.add('dark', 'darkMode');
}
})();
</script>
<script type="application/json" id="o11y-boot-settings">
[[.Settings]]
</script>
<script>
try {
var _el = document.getElementById('o11y-boot-settings');
window.o11yBootData = {
settings: _el ? JSON.parse(_el.textContent) : null,
};
} catch (e) {
window.o11yBootData = { settings: null };
}
</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
NO third-party widgets or trackers are loaded here, and none may be
added. The upstream fork injected a support-chat widget and an
onboarding tracker, both enabled by default — a self-hosted
observability tool must never make outbound calls to third parties
with our users' data. Support chat is Hanzo Chat (utils/supportChat);
analytics is Hanzo Insights. Sentry is opt-in, on our own fork.
-->
<link rel="stylesheet" href="css/uPlot.min.css" />
<script type="module" src="./src/index.tsx"></script>
</body>
</html>