Created tickets relating to legends, reserved params, timeline ordering, css, etc

This commit is contained in:
Hugh Kaznowski
2026-09-06 01:41:09 +01:00
parent ac1efd9e53
commit a97bd077a4
7 changed files with 277 additions and 10 deletions
@@ -0,0 +1,48 @@
# 044 — Add `ottyl_fmt` reserved param; rename `sequence`/`timestamp` to `ottyl_seq`/`ottyl_ts`
## Summary
`sequence` and `timestamp` are handled as reserved query metric names in the
filter grammar (`src/filter_parser.rs`, e.g. `parses_reserved_metric_sequence`,
`parses_reserved_metric_timestamp_as_raw_value`) and in alert evaluation
(`src/alerts.rs:199,208`, restricted per the comment at `src/alerts.rs:3` to
`regex/sequence/timestamp/json[field]`), backed by `LogLine { sequence,
timestamp_ms }` in `src/dto.rs:11-12`. These names collide with ordinary
user-declared params and don't signal that they're ottyl-owned. Separately,
there is currently no reserved param exposing which format
(`auto_declare_params`/`auto_derived`, `src/engine.rs` and `src/logfmt.rs`,
added in "Auto derived format") was used to parse a given log line — that
information is computed but not surfaced as a queryable/orderable param.
## Scope
- Add a new reserved param `ottyl_fmt`: a text-enum value recording which
format a line was derived with (e.g. auto-detected key=value/logfmt vs.
JSON vs. plain/none), populated wherever `auto_declare_params`/format
detection currently runs (`src/engine.rs`, `src/logfmt.rs`).
- Rename the reserved metric names `sequence` → `ottyl_seq` and
`timestamp` → `ottyl_ts` everywhere they're recognized: filter grammar
(`src/filter_parser.rs`), alert query restriction and evaluation
(`src/alerts.rs`), and any webapp references to these literal names
(`webapp/src/lib/api.ts`, `webapp/src/components/LogPreview.tsx`).
- Decide and implement backward compatibility: either accept both old and
new names for one release, or treat this as a breaking rename (update
fixtures/docs accordingly) — call this out explicitly in the PR.
- Update any docs/help text (e.g. regex cheat sheet, param declaration UI)
that reference `sequence`/`timestamp` by name.
## Acceptance criteria
- Filters, alert queries, and metric declarations recognize `ottyl_seq`
and `ottyl_ts`; the old bare names either error clearly or continue to
work per the compatibility decision above, but are no longer the
documented names.
- `ottyl_fmt` is queryable/filterable like other reserved params and its
value reflects the actual detected format for a given log line
(verified by a seeded fixture with mixed-format lines).
- Existing tests referencing `sequence`/`timestamp` reserved metrics are
updated and pass.
## Depends on
None.
@@ -0,0 +1,45 @@
# 045 — Timeline/log ordering by params other than `ottyl_ts`, with drop/fallback toggle
## Summary
Log lines are currently rendered in whatever order the backend returns
them, which is ingest order (`sequence`, monotonically increasing per
`src/ingest.rs`) surfaced via `webapp/src/components/LogPreview.tsx:258-261`
(`log.sequence`/`log.timestamp_ms`). `webapp/src/components/LogTimeline.tsx`
only draws pre-bucketed histogram bars from `fetchTimeline`
(`webapp/src/lib/api.ts:257` → `GET /api/timeline`, `src/api.rs:249
get_timeline`) and has no per-line sort control at all. There is no way to
order by a declared param, and no defined behavior for lines missing
whatever param is chosen for ordering.
## Scope
- Default ordering stays by `ottyl_ts` (see ticket 044 for the rename).
- Add the ability to choose a different declared param as the sort key for
the timeline/log list (backend: extend the timeline/log query path in
`src/api.rs`/`src/engine.rs` to accept a sort-by param; frontend: expose
the choice near the timeline/log controls, likely in
`LogTimeline.tsx`/`LogPreview.tsx` or their shared settings).
- Add an explicit toggle controlling how lines lacking the chosen sort
param are handled: (a) fall back to ordering those lines by `ottyl_seq`,
or (b) drop them from view entirely. Persist this toggle alongside other
view settings.
- Ensure the toggle and sort-by selection are scoped sensibly (e.g. per
timeline/session) rather than silently global if that would surprise
users switching between dashboards.
## Acceptance criteria
- User can pick any declared param as the ordering key for the
timeline/log view, in addition to the `ottyl_ts` default.
- With the fallback toggle on, lines missing the sort param appear
ordered by `ottyl_seq` relative to each other; with it off, those lines
are excluded from the view — both verified with a seeded fixture mixing
lines with and without the param.
- Existing default (`ottyl_ts`-ordered) behavior is unchanged when no
alternate sort param is selected.
## Depends on
044 (reserved param naming — this ticket's default sort key and fallback
key should use the renamed `ottyl_ts`/`ottyl_seq`).
@@ -0,0 +1,38 @@
# 046 — Squash bars/legend entries when a chart has too many series
## Summary
`webapp/src/components/PanelChart.tsx` renders one bar (BarChart, lines
103-119) or slice (PieChart, lines 122-145) per `PromqlSeries`, labeled via
`seriesLabel()` (lines 18-23) and colored by cycling through a fixed
8-color palette `COLORS` (line 26). There is no "top N + other" grouping,
bar-squashing, or legend simplification anywhere in this file — with many
series/labels, both charts render an unbounded number of bars/legend rows
and repeat colors once the palette wraps.
## Scope
- Define a threshold above which a panel's series count is considered
"too many" (bars and legend entries alike).
- Above the threshold, squash extra bars into an aggregated "other"
bucket (or equivalent visual simplification) rather than rendering one
bar per series.
- Above the threshold, simplify the legend similarly (e.g. collapse to
top-N + "other", or a compact/paginated legend) instead of listing every
series.
- Apply the same treatment consistently across all chart types in
`PanelChart.tsx` that can have many series (bar, pie), not just one.
## Acceptance criteria
- A panel with a large number of series (seeded fixture) renders a
bounded number of bars/legend entries instead of one per series, with
an "other"/aggregate representation for the rest.
- A panel with few series is visually unchanged from current behavior.
- Color assignment no longer visibly repeats for panels within the
squashed range (i.e. squashing keeps the rendered series count within
the palette size, or palette collisions are otherwise addressed).
## Depends on
None.
@@ -0,0 +1,49 @@
# 047 — Treat presets as full style makeovers (not just color schemes) in UI and impl
## Summary
Tickets 012 and 020 already unified the *data model* for colour schemes
and custom CSS: `src/settings.rs` stores both built-in `ColorScheme`
variants and `CssEntry` (`Imported`/`Linked`) as equally-selectable themes
via `custom_theme_id`, and the doc comment at `src/settings.rs:44` notes
ticket 020 removed the old "use as theme" vs. "always-on overlay"
distinction. However, built-in presets themselves
(`webapp/src/lib/themes.ts` `BUILTIN_THEMES`) are still defined purely as
`ThemeVars` records of `--c-*` color variables — they can only ever
restyle colors, not layout — so the underlying premise of the wishlist
("presets are literally entire style makeovers that just happen to look
like color changes") isn't actually true of the built-ins yet, and the
settings UI may still read as "pick a colour scheme, optionally add CSS on
top" rather than "pick one style, which can be as small as a palette or as
large as a full redesign."
## Scope
- Audit the settings UI (`webapp/src/lib/useSettingsPanel.ts`,
`webapp/src/App.tsx:126` and wherever the panel is rendered) for
language/layout that still implies "colour scheme" and "CSS" are two
separate features, and rework it to present a single list of
interchangeable style presets (built-in or user-provided), any of which
may be pure-palette or a full layout override.
- Confirm/ensure a user-provided style is not constrained to variable
overrides — i.e. an imported/linked CSS entry can target arbitrary
selectors and restructure layout, not just override `--c-*` variables
(verify against `generateThemeCss`/`parseThemeCss` in
`webapp/src/lib/themes.ts` and how `CssEntry` is applied to the
document).
- No new built-in presets need to be layout-altering; this ticket is
about removing the artificial ceiling and the UI framing, not about
shipping a redesigned built-in theme.
## Acceptance criteria
- Settings UI presents colour schemes and custom/imported CSS as one
unified list of selectable "styles," with no leftover UI copy or layout
implying they're separate concepts.
- A user-supplied CSS entry can override layout-affecting rules (not just
color variables) and have it take effect, verified manually with a
sample stylesheet that changes more than colors.
## Depends on
None (builds on tickets 012, 020 — already merged).
@@ -0,0 +1,40 @@
# 048 — Multi-accent and brighter variants for built-in themes
## Summary
`webapp/src/lib/themes.ts` `BUILTIN_THEMES` (dark, light, red, green,
blue, yellow, pink, orange) are each essentially monotone with a single
accent color. The wishlist asks for 2-3 accents per theme, plus brighter
variants of the more muted presets — e.g. keep the current "Green" as-is
but give it added accents, and introduce a new, brighter "Light Green";
similarly add suitable additional accents to the default "Light" and
"Dark" themes.
## Scope
- Extend the `ThemeVars` shape (or the built-in theme records) to carry 2-3
accent colors per theme instead of one, and update anywhere a single
accent variable is consumed (charts, buttons, highlights) to pick from
the accent set appropriately.
- Add accents to existing "Light" and "Dark" defaults.
- Add accents to existing colour presets (red, green, blue, yellow, pink,
orange) without changing their current base look.
- Add new brighter variants alongside the existing muted ones (e.g.
"Light Green" alongside "Green"), following the same naming pattern for
any other presets that warrant a brighter counterpart.
- Update the settings UI preset picker to list the new theme options.
## Acceptance criteria
- Each built-in theme (existing and new) exposes 2-3 accent colors,
consumed by at least the chart palette (see ticket 046) so charts
visibly use more than one accent per theme.
- New brighter variants (at least "Light Green") are selectable in
settings and render distinctly brighter than their muted counterpart.
- Existing theme selections are visually unchanged aside from the added
accents (no unrelated base color shifts).
## Depends on
None (pairs well with 047, since accents should apply to
user-provided/custom styles too where applicable).
@@ -0,0 +1,57 @@
# 049 — Store profiles inline in `settings.json` instead of a separate `profiles.json`
## Summary
Profile data is currently persisted as its own file, separate from
`settings.json`. `Settings` (`src/settings.rs:68`) only holds a `Profiles`
pointer struct (`names`, `active_profile`, `profiles_dir`, `src/settings.rs:56-63`)
while the actual `Profile`/`Dashboard`/param and metric declarations live in
`ProfileStore`, serialized as a single `profiles.json` inside
`profiles_dir` (`src/profile.rs:1` doc comment, `profiles_store_path` at
`src/profile.rs:491-492`, loaded/saved via `ProfileStore::load`/`save` at
`src/profile.rs:503,557`). Every mutation path in `ProfileStore` (create,
delete, record_param_declaration, record_metric_declaration,
create_dashboard, save_dashboard, delete_dashboard, set_active, etc.)
takes both a `store_path` and, separately, `settings`/`settings_path` to
keep the two files in sync. This ticket folds profile storage into
`settings.json` so there's a single source of truth file instead of two
files that must be kept consistent.
## Scope
- Move the profile list (currently `ProfileStore.profiles: Vec<Profile>`)
into `Settings` itself, replacing the `Profiles { names, active_profile,
profiles_dir }` pointer struct with the actual profile data (keep
`active_profile` as a field alongside it).
- Update `ProfileStore` (or fold it directly into `Settings`) so all
mutation methods read/write through the single `settings.json` via
`Settings::save`/`Settings::load`, instead of maintaining a separate
`store_path`/`profiles_store_path`.
- Write a one-time migration: on load, if a legacy `profiles.json` exists
under the configured `profiles_dir` and `settings.json` has no inline
profiles yet, read it in, merge into `Settings`, save, and (after a
successful save) remove or rename the old file so it isn't re-migrated.
- Update every call site currently passing both a settings path and a
profiles store path (`src/api.rs`, `main.rs`, tests in `src/profile.rs`)
to the new single-path API.
- Keep CSS import/export (`src/settings.rs` `import_css`/`link_css`,
which already write separate CSS files referenced from `settings.json`)
as-is — this ticket is scoped to profiles only.
## Acceptance criteria
- A fresh install has exactly one persisted file, `settings.json`,
containing profiles, dashboards, and declarations inline — no
`profiles.json` is created.
- An existing installation with a legacy `profiles_dir/profiles.json` is
migrated automatically on next load: profiles appear inline in
`settings.json`, and the old file is removed/renamed so migration
doesn't repeat on subsequent loads.
- All existing profile/dashboard/declaration CRUD behavior (create,
delete, set active, record param/metric declarations, dashboard CRUD)
is unchanged from the user's perspective, verified by porting the
existing `src/profile.rs` tests to operate against `Settings` directly.
## Depends on
None.