Restore IssuesVisualizer redesign reverted by merge 67ce419 and re-apply
Needle triage/test additions. Migrate all remaining screens off the MD3
palette, raw Tailwind colors, gradients and Material Symbols. Remove the
legacy theme block and fonts, drop the duplicate tab strip, rebuild
TelemetryFilters on FilterBar, and document status in AGENTS.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
167 lines
9.3 KiB
Markdown
167 lines
9.3 KiB
Markdown
# Agent instructions
|
|
|
|
Instructions for AI agents (and contributors) working in this repo. Currently
|
|
covers the `otel-ui` frontend design system, since that's the active area of
|
|
work; add sections here as other parts of the repo get their own conventions.
|
|
|
|
## otel-ui: design system
|
|
|
|
### The rule
|
|
|
|
**One theme, light and dark - that's it.** `otel-ui/src/index.css` defines a
|
|
single set of `--ds-*` tokens with a dark variant (default) and a light
|
|
variant (`:root[data-theme="light"]`). Never introduce a second palette, a
|
|
third theme variant, or a new token namespace alongside `ds-*`. If a screen
|
|
needs a color, it comes from this table or it doesn't exist yet - extend the
|
|
table, don't invent a one-off.
|
|
|
|
The theme toggle lives in `TopBar.tsx`, persists to `localStorage`
|
|
(`otel.ui.theme`), and is applied before first paint by an inline script in
|
|
`index.html` so there's no flash of the wrong theme.
|
|
|
|
The old MD3-style `--color-surface-container-*` / `--color-on-surface` tokens,
|
|
the Material Symbols icon font and the Geist/Inter/JetBrains fonts have been
|
|
**deleted**. Never reintroduce them, raw Tailwind palette colors
|
|
(`slate-*`, `sky-*`, `rose-*`, `white/10`...), gradients, or shadows. Use
|
|
`lucide-react` for icons.
|
|
|
|
Documented exceptions (data-viz only, never chrome): per-service span colors
|
|
in the trace waterfall (`getSpanColor` in `otel-utils.ts`) and the muted
|
|
chart-series hues for metric lines/pods (`POD_COLORS`).
|
|
|
|
### Token reference
|
|
|
|
Source of truth is `otel-ui/src/index.css` (`:root` and `:root[data-theme="light"]`).
|
|
Tailwind utilities are generated as `bg-ds-*`, `text-ds-*`, `border-ds-*`.
|
|
|
|
| Token | Dark | Light | Used for |
|
|
|---|---|---|---|
|
|
| `ds-bg` | `#0D1014` | `#F4F2ED` | page ground |
|
|
| `ds-chrome` | `#0B0E12` | `#FFFFFF` | icon rail, top bar |
|
|
| `ds-surface` | `#14181E` | `#FFFFFF` | cards, panels |
|
|
| `ds-surface-2` | `#191E26` | `#F7F5F0` | inputs, chips, selected row |
|
|
| `ds-fill` | `#1D232B` | `#EDEAE3` | hairlines inside cards, chart bands, bar tracks |
|
|
| `ds-line` | `#242B34` | `#E3E0D8` | card/control borders |
|
|
| `ds-line-strong` | `#2A313B` | `#D6D2C8` | chip borders, neutral badges |
|
|
| `ds-text` | `#E8ECF2` | `#161A1F` | primary text |
|
|
| `ds-text-2` | `#98A3B2` | `#4F5964` | secondary text |
|
|
| `ds-text-3` | `#8B96A6` | `#6B7480` | labels, metadata, muted text - this is the accessibility floor, don't go dimmer |
|
|
| `ds-critical` / `ds-critical-bg` | `#FF6F5E` / `#2B1512` | `#C4402C` / `#FBE9E5` | breached threshold, open errors |
|
|
| `ds-warn` / `ds-warn-bg` | `#F0B24A` / `#2A2011` | `#8A5D0E` / `#F9EFDA` | degraded but not (necessarily) user-visible |
|
|
| `ds-ok` | `#4FCF9A` | `#1F7A56` | healthy, resolved, recovered |
|
|
| `ds-accent` / `ds-accent-bg` | `#7B8CFF` / `#161B33` | `#3B4FC4` / `#E9ECFB` | the one interactive accent - primary buttons, selected segment, links, focus |
|
|
| `ds-on-accent` | `ds-chrome` value | `#FFFFFF` | text on top of `ds-accent` |
|
|
|
|
**Colour is a signal, not decoration.** Chrome, borders and type are neutral.
|
|
`ds-critical` / `ds-warn` / `ds-ok` only appear where a real measurement is
|
|
out of its expected band or a real state changed (open vs resolved). A
|
|
severity pill's color must correspond to an actual state, never picked for
|
|
visual variety. Don't tint cards, headers or buttons "for interest."
|
|
|
|
### Fonts
|
|
|
|
Three families (`otel-ui/index.html` loads them; `index.css` exposes them as
|
|
`--font-display` / `--font-ui` / `--font-data`, used via Tailwind's
|
|
`font-[family-name:var(--font-display)]` arbitrary syntax):
|
|
|
|
- **Bricolage Grotesque** (`--font-display`) - page/card headings, big metric numbers.
|
|
- **Instrument Sans** (`--font-ui`) - all other UI text and body copy. Also the
|
|
new global default (`index.css`'s `@theme` overrides `--font-body`), so
|
|
unmigrated screens already inherit this typeface even before their colors move.
|
|
- **IBM Plex Mono** (`--font-data`) - anything a person would copy or grep:
|
|
ids, `key=value` attribute pairs, timestamps, durations, service names.
|
|
|
|
Never Inter, Roboto, Arial, or a new font stack.
|
|
|
|
### Layout shell (already built - reuse, don't rebuild)
|
|
|
|
- `otel-ui/src/components/layout/IconRail.tsx` - 72px fixed icon rail, global nav, one `aria-label` per icon.
|
|
- `otel-ui/src/components/layout/TopBar.tsx` - 58px fixed top bar: search, time range, theme toggle, auth.
|
|
- `otel-ui/src/components/FilterBar.tsx` - generic filter bar (optional scope segmented control, removable chips, dashed add-filter, an always-visible match readout, clear-all). Reuse this on every screen that lists things instead of building a bespoke filter row.
|
|
- `App.tsx` wires the shell globally and renders the single page-level `<main>`. Screens render inside it - see pitfall #2 below.
|
|
|
|
### Screen pattern
|
|
|
|
Established by `IssuesVisualizer.tsx` (the triage overview) and
|
|
`RumSessionsVisualizer.tsx` (real-user sessions) - follow this shape for the
|
|
remaining screens:
|
|
|
|
- `<FilterBar />` at the top of the screen's content.
|
|
- A main content column (`flex-1`) plus an optional fixed-width aside
|
|
(~340-420px) for supporting stats/panels.
|
|
- Cards: `rounded-[14px] border border-ds-line bg-ds-surface`, **no shadows,
|
|
no gradients** - depth comes from the border and ground color alone.
|
|
- No per-service rainbow badges. `getServicePalette` in `otel-utils.ts` (the
|
|
gradient hash-to-color picker) is legacy: per the original design spec, a
|
|
muted per-service palette is reserved for trace-waterfall span coloring
|
|
only, never for general UI chrome like service badges. Use a neutral
|
|
`border-ds-line-strong text-ds-text-2` badge instead.
|
|
- Real `<button>` / `<a href>` / `<input>` + `<label>` only. Never `onClick`
|
|
on a `div` or `span[role=button]`. `aria-label` on every icon-only control;
|
|
`aria-hidden="true"` on decorative SVG icons (use `lucide-react`, not the
|
|
Material Symbols icon font - see pitfall below).
|
|
|
|
### Pitfalls hit migrating Issues and RUM sessions - avoid repeating these
|
|
|
|
1. **No nested `<button>` elements.** Browsers implicitly close the outer
|
|
`<button>` the moment they hit an inner one, which silently breaks click
|
|
handling on whatever's after it in the DOM (this shipped once, undetected
|
|
until manual testing). If a row/card needs both "click to expand" and
|
|
inner action buttons, make the expandable area its own `<button>` and put
|
|
the action buttons as **siblings**, not children.
|
|
2. **No nested `<main>` landmarks.** `App.tsx` already renders one `<main>`;
|
|
a screen component must not render its own - use a `<div>`.
|
|
3. **`whitespace-nowrap` + `shrink-0` on fixed-height pills/badges.** Without
|
|
them, a longer label silently wraps onto two lines and blows out the
|
|
pill's height inside its flex row - easy to miss until you test with real
|
|
(longer) data or a narrower viewport.
|
|
4. **Never fabricate data.** Before adding a metric, column, or button, check
|
|
whether the field actually exists in the real data model - the backend API
|
|
response, or for RUM specifically, what `static/otel-rum.js` actually
|
|
sends (see the header comment in `otel-ui/src/lib/rum-utils.ts` for a
|
|
worked example of what's real vs. invented). If a design reference shows
|
|
something with no backing data - the RUM mockup invented rage clicks, geo
|
|
location, a "frustration score", and session replay, none of which this
|
|
pipeline captures - drop it or replace it with the closest real,
|
|
honestly-labeled equivalent. Never wire up a control that looks
|
|
functional but isn't backed by anything.
|
|
5. **Screenshots of a hidden Browser preview pane are unreliable** for
|
|
`position: fixed` elements (stale compositor frame, even after a full
|
|
reload). If a screenshot shows something that contradicts
|
|
`getComputedStyle`, trust the computed style, front the tab, and re-check
|
|
before concluding there's a real bug.
|
|
|
|
## Migration status
|
|
|
|
Whole UI is on `ds-*` (one theme, light + dark). The nav strip in `Tabs.tsx`
|
|
is gone - `IconRail` is the only navigation; `Tabs.tsx` just renders the
|
|
active screen. `TelemetryFilters` is built on `FilterBar`. The Material
|
|
Symbols icons were replaced with lucide.
|
|
|
|
Lessons from getting here:
|
|
|
|
- **Merges can silently revert a redesign.** `67ce419` reverted
|
|
`IssuesVisualizer.tsx` to the old styling (a parallel branch had edited the
|
|
same file). After any merge touching `otel-ui/src`, run the greps below -
|
|
they must return nothing.
|
|
- **A stale `otel-ui/dist` or un-redeployed image hides changes.** The Go
|
|
server serves `otel-ui/dist`, else `./dist`, else the legacy root
|
|
`index.html`. Rebuild (`npm --prefix otel-ui run build`) before concluding a
|
|
screen isn't wired.
|
|
- Still to polish (functional, but not yet re-laid-out to the screen
|
|
pattern): `TraceVisualization`, `MetricsVisualizer`, `StructuredLogTerminal`,
|
|
`SearchAndWatcher`, `TrendsVisualizer`, `SetupPanel`. They use `ds-*`
|
|
colors via a mechanical token swap but keep their old layout/type scale, use
|
|
`onClick` on non-buttons in places, and `CommandAndQueryBar` /
|
|
`WaveformHistogram` still sit above every non-Issues/RUM tab. Restructure
|
|
them onto `FilterBar` + the card/aside pattern when touching them.
|
|
|
|
### Finding old-pattern usages
|
|
|
|
```sh
|
|
grep -rlE "surface-container|text-on-surface|primary-container|bg-error-container|material-symbols-outlined" otel-ui/src
|
|
grep -rnE "(bg|text|border|ring|from|to|via)-(slate|zinc|gray|sky|cyan|blue|violet|indigo|purple|emerald|teal|rose|red|amber|orange)-[0-9]|text-white|border-white|bg-(white|black)/" otel-ui/src
|
|
```
|
|
|
|
Both must print nothing.
|