## What changed
Fixed a mismatch between the request count displayed on a service graph
node label and the request count shown in the tooltip when hovering over
that node in the tree view.
## Why
In the service graph tree view, node labels use a direction-aware
`value` (e.g., requests from service A → service B), while the tooltip
was reading `node.requests` — the backend's node-level aggregate (sum of
all directions). This caused the two displays to show different numbers
for the same node.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## What changed
- **Removed** the native `scrollIntoView()` call from `SpanBlock.vue`'s
`onMounted` hook, which was fighting the user's manual scroll in a
virtualized list.
- **Added** `cancelScroll()` to `TraceTree.vue` — clears pending
timeouts and aborts the TanStack virtualizer retry loop by resetting
`currentScrollToIndex`.
- **Wired cancellations** in `TraceDetails.vue` — calls
`traceTreeRef.value?.cancelScroll?.()` when the sidebar closes, trace
details reset, or a new trace is loaded.
- **Added `onBeforeUnmount`** cleanup in `TraceTree.vue` so a queued
scroll can't fire against a torn-down virtualizer.
- **Added regression tests** in `SpanBlock.spec.ts`,
`TraceTree.spec.ts`, and `TraceDetails.spec.ts` covering all
scroll-cancellation paths.
## Why
When `TraceDetails.vue` is opened with a `span_id` query parameter,
`SpanBlock.vue` called `element.scrollIntoView()` on mount. Because rows
are virtualized via `@tanstack/vue-virtual`, a `SpanBlock` remounts
every time it scrolls into the viewport — so each remount snapped the
viewport back to the pre-selected span, fighting the user's manual
scroll. The issue only manifested when a `span_id` was pre-selected at
page load.
## What changed
- **`web/src/plugins/traces/SearchBar.vue`**: Fixed the Run Query button
by changing `variant="ghost"` to `variant="primary"`, restoring its
primary action styling (matches Logs SearchBar behavior).
- **`web/src/components/TenstackTable.vue`**: Fixed skeleton loader
background color to match the logs version. Added
`bg-(--o2-log-table-row-bg)` and `border-(--o2-log-table-row-border)`
tokens to skeleton rows. Replaced inline shimmer gradients with a
reusable `.o2-skel-pill` CSS class that uses OTable skeleton token
variables (`--color-skeleton-base`, `--color-skeleton-highlight`).
## Why
The Traces Run Query button had lost its primary styling and appeared
visually broken — it was rendering as a ghost button instead of the
prominent primary action button. The generic `TenstackTable.vue`
skeleton loaders had a different background color than the logs-specific
`TenstackTable.vue`, causing visual inconsistency.
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## What this fixes
The scheduled **regression suite** started failing on `main` after
**#12764 (scoped scss styles removal)**, and validating the fix on the
**enterprise build** surfaced several more failures in the same family
(plus a couple unrelated ones). This PR heals **all of them**. Every fix
is either a page-object selector update or a small, inert `data-test`
hook — **no product behaviour changes**.
## Everything fixed
| Area | Test | Root cause | Fix | Verified |
|---|---|---|---|---|
| **Streams** regression | `query expand icon #9337` | #12764 replaced
`.editor-fullscreen` class with inline classes on `isFocused` |
`data-fullscreen` hook on the container + detect via it | ✅ local |
| **Alerts** regression | `Bug #9967 PromQL alert` | #12764 turned the
PromQL operator into `<OSelect
data-test="alert-threshold-operator-select">`, dropping
`.alert-v3-select` | data-test + popover-option pattern (+ fail-fast
fallback) | ✅ local |
| **RUM** (ENT) | 3× `sourcemap-ui` | #12764 moved
`.error-viewer-container` → data-test and dropped `.tags-title` |
rumPage selectors + `data-test="error-tags-title"` hook | ✅ local |
| **Logs-Features** (ENT) | `searchPatterns … wildcard chips` | chip
moved from `.wildcard-chip` class to `<OTag
data-test="pattern-card-wildcard-chip">` | target the data-test hook | ✅
local |
| **Traces** (ENT) | `service-graph` user/search-service status | health
badge moved from `.health-badge.<status>` classes to `<OTag
data-test="service-health-badge">` | read status from the badge's text |
⚙️ ENT CI¹ |
| **Dashboards-Core** | `line chart … camelCase zero values` | *(not
#12764)* a line chart whose series are entirely zero renders "No Data" |
one series counts all rows so the chart always renders | ✅ local |
¹ Traces service-graph needs an enterprise daemon that isn't available
locally; validated against the component's own unit spec
(`ServiceGraphNodeSidePanel.spec.ts`), confirmed on ENT CI.
## Root-cause themes
1. **#12764 (scoped SCSS removal)** deleted/renamed CSS classes that E2E
page objects targeted. It added `data-test` hooks to *some* elements but
not others — so tests anchored on bare `.class` selectors broke. The fix
everywhere is to move those anchors to durable `data-test` hooks.
2. **`OTag`/`OSelect` component migrations on `main`** continued this:
the components gained `data-test` hooks but the (enterprise-only) page
objects were never updated. Because those specs are `@enterprise`, OSS
CI never runs them — so they merged broken and only surfaced on the
enterprise build.
## Product-code touched (test hooks only, inert)
- `SearchBar.vue` — `data-fullscreen` attribute (no CSS/JS/snapshot
consumers; styling still driven by the existing `isFocused` class
binding)
- `ErrorTags.vue` — `data-test="error-tags-title"`
Everything else is under `tests/ui-testing/`.
## Verification
Verified locally against a fresh frontend build (all green): Streams
`#9337`, Alerts `#9967`, RUM (3), Dashboards-Core, Logs-Features
searchPatterns. Traces service-graph is validated via its component unit
spec + the enterprise CI run (it can't run locally without the
service-graph daemon).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
#12854
## What changed
Fixes a race condition where RED (metrics) queries were missing the
error filter on first click when `auto_query_enabled` is true. The root
cause was that `onDataZoom` in `TracesMetricsDashboard.vue` emitted
`"time-range-selected"` *after* `"filters-updated"`, so queries
triggered by the filter change ran with stale time range data. The fix
reorders these two events and adds `await nextTick()` between them.
Additionally, the `filter` and `timeRange` props were removed from
`TracesMetricsDashboard.vue` — the component now reads `editorValue` and
`datetime` directly from `searchObj.data`, and the `setCustomDate.vue`
component moves `markProgrammaticDateChange` to the end of the save
flow.
## Why
The bug (RED queries not receiving the latest error filter on first
auto-query) was caused by event ordering: `"time-range-selected"` fired
after `"filters-updated"`, meaning the query triggered by the filter
change used the previous time range. The second click worked because by
then the cached time range had caught up. The decision to remove
`filter`/`timeRange` props was driven by a dependency on `searchObj`
data that is always available; passing them as separate props introduced
an unnecessary synchronization risk.
Co-authored-by: Claude <noreply@anthropic.com>
Theme selection across light and dark modes is now persisted by name
instead of numeric ID. A shared registry (constants/themes.ts) owns the
single source of truth for all predefined theme definitions, and
utils/themeManager.ts provides a central applyCurrentTheme() /
applyThemeForMode() API that replaces scattered inline resolution logic
in App.vue and PredefinedThemes.vue. Custom themes continue to store
their hex color as the source of truth, marked with the
CUSTOM_THEME_NAME sentinel.
The theme drawer is redesigned: a segmented Light/Dark toggle replaces
the tabs, each theme is a single clickable row (no per-row Apply
button), the applied theme is highlighted with a primary ring plus an
Applied badge, long names truncate instead of wrapping, and the custom
color row opens the picker with an Apply/Cancel dialog.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
- **Service Catalog**: Add progress bars to latency and error rate
columns (P50, P95, P99, Avg Duration, Max Duration, Error Rate), scaled
relative to the column maximum across all filtered services. Raw count
columns (Requests, Errors) kept as plain text to avoid misleading
comparisons.
- **Service Graph Side Panel**: Extend the same progress bar treatment
to the Operations tab and K8s/resource tabs. Remove the outer border box
from RED charts using `:frame="false"` on `RenderDashboardCharts`.
- **Alert History Timeline**: Add a colored strip visualization above
the history table showing firing (red), ok (green), and flapping
(purple) zones across the selected time range. Flapping zones are
detected automatically based on rapid state alternation and shown as a
single collapsed row in the table with transition count and duration.
Status labels normalized — `completed` → Firing,
`condition_not_satisfied` → Ok.
## Changes
### New files
- `web/src/plugins/traces/components/ServiceCatalogBarCell.vue` —
reusable bar cell (label + OProgressBar, scaled to column max)
- `web/src/components/alerts/AlertHistoryTimeline.vue` — state strip
with flapping zone detection, hover tooltips, transition timestamps
### Modified files
- `web/src/plugins/traces/ServicesCatalog.vue` — column maxes computed,
bar cells wired up, column order adjusted
- `web/src/plugins/traces/ServiceGraphNodeSidePanel.vue` — progress bars
on ops/resource tabs, `:frame="false"` on RED charts
- `web/src/components/alerts/AlertHistoryDrawer.vue` — timeline
integrated, flapping row grouping, status label normalization
## Test plan
- [ ] Service Catalog: verify progress bars scale correctly when
filtering services, bars absent on Requests/Errors columns
- [ ] Service Graph side panel: progress bars visible on Operations tab
P95/P99/P75; RED charts have no outer border box
- [ ] Alert History: open an alert with mixed firing/ok history —
timeline strip appears above table
- [ ] Alert History: open an alert with rapid firing↔ok alternation —
purple Flapping zone visible in strip, flapping rows collapsed in table
with expand chevron
- [ ] Alert History: status badges show "Firing" for
completed/error/anomaly, "Ok" for condition_not_satisfied
- [ ] Dark mode: all components render correctly with theme tokens
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: ktx-vaidehi <vaidehi.akhani@kiara.tech>
1. The name is missing on score config list table
datetime error when user is clicking on arrow in quality page / any one
of the score config overview
replace hardcoded badges to obadge in all list page
when user goes to llm sessions it is taking user to traces submenu
## What changed
Adds a streaming progress bar (the same `LoadingProgress.vue` used by
dashboard panels) to the logs results table and histogram chart. The
skeleton loader in `TenstackTable.vue` now hides once any rows exist,
keeping data visible while streaming updates replace values in-place.
## Why
During `streaming_aggs`, hits arrive and replace chunk-by-chunk while
`loading` stays `true` until the stream `end` signal. The full skeleton
covered the table on every refresh, so users couldn't watch the
incremental updates. The progress bar signals an in-progress refresh
without hiding existing data.
## What changed
- **FieldValuesPanel.vue** — Added `tw:relative` to the loading wrapper
so the `OInnerLoading` overlay (which is `absolute inset-0`) is
contained within the expanded section instead of spilling over the
entire field row.
- **IndexList.vue** — Reworked `cancelTraceId` to use
`cancelStreamQueryBasedOnRequestId` (HTTP stream abort) instead of the
now-removed `cancelSearchQueryBasedOnRequestId`. Updated
`cancelFilterCreator` to call `cancelTraceId`, clear `isLoading`, and
empty `traceIdMapper` entries.
- **FieldValuesPanel.spec.ts** — Regression test asserting the loading
wrapper carries `tw:relative`.
- **IndexList.spec.ts** — Un-skipped two previously skipped cancel tests
and updated them to assert on `mockCancelStreamQueryBasedOnRequestId`.
Added new regression tests for the `cancelFilterCreator` →
`cancelTraceId` flow on collapse.
## Why
The loading overlay (`OInnerLoading`) uses `absolute inset-0`
positioning. Without a positioned ancestor, it escaped to the nearest
parent (`.o-field-list__row`), covering the field row and the collapse
toggle. This made it impossible for users to collapse a slow-loading
field to cancel the request. The cancel logic itself was also broken —
it referenced a WebSocket-based cancel function that no longer matched
the actual HTTP-stream transport used for field values.
## What changed
- Created `useWidenRange` composable with extracted `periodToLabel` /
`nextWiderPeriod` pure functions to eliminate duplicate widen-range
logic across `ServiceGraphNoDataState`, `ServicesCatalogNoDataState`,
`TracesNoEventsState`, and `LogsNoEventsState`.
- Added `getEffectiveTimeRange` to `utils/date.ts` to deduplicate inline
datetime-parsing if/else blocks in `ServiceGraph.vue` and
`ServicesCatalog.vue`.
- Created two new animated SVG illustrations (`EmptyServiceGraph.vue` —
horizontal tree topology with one root node calling two children;
`EmptyServicesCatalog.vue` — table card with three service rows and
pulsing status dots), registered them in the OEmptyState preset system,
and added i18n keys across all 12 languages.
- Added dedicated empty-state components `ServiceGraphNoDataState.vue`
and `ServicesCatalogNoDataState.vue` with an "Expand time range" action
card (matching the `TracesNoEventsState.vue` pattern), wired via emit
chain through `ServiceGraph.vue` / `ServicesCatalog.vue` up to
`Index.vue`'s `onWidenTracesRange`.
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## What changed
- Passes `matchedSetId` and `chipDimensions` as new computed props from
`IncidentDetailDrawer.vue` to the embedded
`TelemetryCorrelationDashboard`, enabling the "View by" subject tabs in
the incident view
- Adds an `OBadge` showing the selected subject as `label = value` after
the subject toggle tabs in `CorrelationEventHeader.vue`
- Fixes the responsive overflow logic so the first context chip can
overflow when space runs out, and the overflow indicator shows "N
Fields" when all chips are hidden instead of a bare "+N"
- Renders hidden overflow chips as stacked `OBadge` components in
`OTooltip`'s `#content` slot instead of a `\n`-joined string
## Why
Incidents opened without a source trace or log event had no
`matchedSetId` / `chipDimensions` passed to the correlation dashboard,
so the "View by" subject toggle (Pod, Node, etc.) never rendered. The
badge was also missing to visually indicate which subject is active.
#12703
## What changed
Removed the `showErrorOnly` key from `searchObj.meta` state and replaced
it with a `computed` property that derives from
`activeIncludeFilterValues` — specifically checking whether
`span_status` includes `"ERROR"`. The `SearchResult.vue` component now
receives `showErrorOnly` as a prop from `Index.vue` instead of reading
it from the shared composable state. `TracesMetricsDashboard.vue` had
its own writable `showErrorOnly` computed removed since it no longer
needs to sync a top-level state key.
## Why
The user identified that `showErrorOnly` was redundant state — the
information is already encoded in
`activeIncludeFilterValues["span_status"]`. Keeping both in sync was
unnecessary maintenance burden. Deriving it from the existing filter
state is the single source of truth and eliminates the risk of the flag
and the actual query filters diverging.
## What
In the traces **spans-mode** list view, the query was built as:
```sql
SELECT * FROM "<stream>" [WHERE ...] ORDER BY start_time <dir>
```
`start_time` is a regular column, so the engine has to perform a full
re-sort of the result set. This change makes the query order by the
configured timestamp column (`_timestamp`) whenever the active sort
column is the default `start_time`:
```sql
SELECT * FROM "<stream>" [WHERE ...] ORDER BY _timestamp <dir>
```
## Why
- Span data is physically stored sorted by the timestamp column, and the
backend has a dedicated optimizer for timestamp-sorted segments.
- A span's `_timestamp` is monotonically equivalent to its `start_time`,
so the **visible row order is unchanged**.
- This avoids the costly full re-sort that `ORDER BY start_time` forces,
improving query latency for the trace/spans view.
## Scope / Notes
- Change is contained to `web/src/plugins/traces/Index.vue`
(spans-mode query builder in `getQueryData`).
- Only the default `start_time` sort is remapped. Any explicit
non-`start_time` sort column the user picks is passed through
unchanged.
- The `sortBy` UI state still reports `start_time`, so the sort
indicator and reset logic are unaffected.
- Not in scope: the single-trace span fetch in `TraceDetails.vue` still
uses `ORDER BY start_time` (can be addressed separately).
## Testing
- Verified the generated spans SQL now uses the timestamp column for the
default sort and produces the same visible ordering.
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>