Compare commits

...

2350 Commits

Author SHA1 Message Date
Abhi Kumar
cd6cb2704b feat(dashboard-v2): group panel values into thousands
Applies `groupThousands` inside `formatPanelValue`, the single seam through
which V2 panels reach `getYAxisFormattedValue`. Large scalars now read as
`1,234,567` instead of an undelimited digit run.

Unitless values were the visible gap: they format through the `'none'` unit,
whose `Intl.NumberFormat` sets `useGrouping: false`. Units that scale their
own value never reach four integer digits, so they are unaffected.

Grouping at the seam covers every consumer — the Number panel, Table value
cells, the threshold-row previews and the table CSV export — rather than one
call site. Table sorting and threshold evaluation read raw cell values, so
neither is affected.

Closes #7669
2026-07-29 13:38:06 +05:30
Abhi Kumar
67c6f447ac fix(dashboard-v2): keep the unit split for thousand-grouped values
The numeric core of `parseFormattedValue` rejected `,`, so a grouped value
matched nothing and fell through to the whole-string fallback, losing its
prefix/suffix unit split: the Number panel would have rendered
`1,234,567 ms` as one undifferentiated blob instead of value + `ms`.

Accepts separators in the numeric core, and adds the suite this util was
missing.
2026-07-29 13:37:43 +05:30
Abhi Kumar
7f6b8abd52 feat(dashboard-v2): add a thousand-separator formatter for panel values
Introduces `groupThousands`, which inserts separators into the integer part
of an already-formatted value so large scalars read as `1,234,567`.

It groups only the first numeric token's integer digits, leaving fractions,
unit labels and the formatter's own scaling (`1.18 MiB`, `1.23 Mil`) intact,
and skips exponent notation where grouping a mantissa would read as noise.
2026-07-29 13:37:07 +05:30
Srikanth Chekuri
bca2370862 test(promql): add upstream promqltest conformance corpus and suite (#12156)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Freezes an absolute-truth oracle from prometheus@v0.311.3's own
promql/promqltest testdata: a generator command (scripts/promqltestcorpus, go run .)
evaluates upstream's load scripts with the vendored reference engine and
writes 755 cases to a committed corpus; a new integration suite replays
the ingestion and asserts /api/v5/query_range responses against it. The
known-divergences ledger is enforced exactly in both directions and is
empty: the serving path matches the reference engine on every case.

Also folds in the last serving-path fix the corpus surfaced: the v5
output filter dropped every __-prefixed label, mangling labelsets that
legitimately carry one (e.g. __address__); it now strips only known
storage keys (__temporality__, __scope./__resource. prefixes).

The metrics fixture writes registration rows per (series, hour bucket)
with hour-floored timestamps, matching the exporter; the queriermetrics
dormant-metric warning test now uses genuinely dormant data (production-
shaped registration shares an hour bucket with recently-stale data).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 03:54:22 +00:00
Gaurav Tewari
591837152e fix(warning-popover): background color to l2 & message alignment (#12302)
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
* fix: update css styles

* feat: add warning popover

* chore: revert bg color change

* feat: update styles

* chore: css conventios

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-28 17:16:05 +00:00
Pandey
2c5b4184c4 feat(querier): log user-authored clickhouse sql after running them through the parser (#12301)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(querier): restrict user-authored clickhouse sql to read-only selects

Validate every user-authored ClickHouse statement before it runs: exactly one
statement, SELECT only, no table functions and no readonly override. Validation
runs on the rendered statement, since substituted variable values are user input
too.

Apply it to both entry points that reach the telemetry store with user SQL, the
clickhouse_sql query type in query_range and the dashboard variables query, and
replace the substring blacklist in the latter, which ran before substitution.

Also run these statements with readonly = 2 as a backstop. The connection is
shared with write paths, so it is opt-in per query and writers never set it.

* fix(querier): address review on clickhouse sql validation

Rename the validator to ValidateReadOnlySelect and collapse the multi-line error
constructions onto single lines.

Carry the parse failure in the message rather than as a wrapped cause. Neither
renderer surfaces the cause: render.Error reads only the message off the base
error, and RespondError reads Error(), which returns the cause alone and drops
the message. Both now show the same text with a 400.

Add unit tests covering statement kinds, table functions nested in joins, CTEs,
subqueries and unions, and readonly overrides.

* fix(querier): reject internal databases in user-authored clickhouse sql

Reading system or information_schema exposes grants, users and server metadata,
and ClickHouse read-only mode does not prevent it, so reject any table reference
into them.

Update the dashboard variables test for the new rejection message and cover both
a statement smuggled through a variable value and a system table read.

* fix(querier): reject unterminated block comments before parsing

The parser loops forever on an unterminated block comment, so validating a query
containing one would spin a request goroutine at full CPU instead of rejecting
it. Detect it up front, skipping comment markers that sit inside string literals.

Cover the parser panicking on a settings clause with no value in its own test,
which asserts the input still panics the parser so the case cannot quietly stop
exercising the recover.

* fix(querier): drop the block comment guard now the parser handles it

The parser no longer loops on an unterminated block comment, so the hand-rolled
scan that worked around it is redundant, and it was the riskier of the two: it
duplicated the lexer's handling of string literals and could have rejected a
legitimate query. Leave the parser as the single source of truth.

The panic case likewise no longer panics, so its test can no longer cover the
recover and is removed. The recover stays as insurance, since this reaches
user-authored SQL and the parser has regressed this way before.

Cover INTERSECT and EXCEPT, which the parser only started accepting in this
version and which reach a second query through the same rules.

* fix(querier): log clickhouse sql validation failures instead of rejecting

The parser's grammar has gaps against SQL that ClickHouse accepts, so rejecting
whatever it cannot read would break working dashboards and alerts. Sampling a
week of production clickhouse_sql found roughly one query in eighteen tripping
one of three gaps, none of them reading anything a telemetry query should not.

Log the failure with the rendered query instead, so the gaps can be told apart
from statements that genuinely break the rules before anything is enforced.

Wrap the parse error rather than formatting it in, so a caller can recover the
parser's *ParseError and read the position off it. The tests use that to pin the
construct each gap stops at, alongside the rewrite that the parser does accept.

* chore(querier): tighten the clickhouse sql validation comments

Condense the comments to single lines, move the recover note inside the defer it
explains, separate the visitor cases, and shorten the log message. Report how
many statements were found when rejecting a multi-statement query.

* fix(querier): log invalid clickhouse sql on the dashboard variables path too

The two callers disagreed: query_range logged and carried on, while dashboard
variables rejected. Given the parser trips on roughly one real query in eighteen,
that path could refuse a legitimate variable query, and being a rejection it left
nothing behind to show it had happened.

Both now go through LogIfStatementIsNotValid. prepareQuery is back to rendering
and nothing else, so the cases that expected it to police the statement move to
where the rules actually live.

* fix(querier): drop the read-only clickhouse session

Setting readonly on the session was defence in depth for a validator that now
only logs, so it guarded nothing while adding a context key and a settings branch
to a connection that is shared with every write path.

Restore the dashboard variables handler to what it was and call the validation
alongside, rather than reworking the rendering to accommodate it.

* chore(querybuilder): drop the redundant suffix from the failing case names

The test they sit in is already named _Fail.
2026-07-28 14:54:42 +00:00
Gaurav Tewari
0b69f5f677 fix: smooth Only/Toggle hover reveal in quick-filters checkbox (#12248)
The Only and Toggle buttons were revealed by overlapping hover triggers
(`.value` for Toggle, `.checkbox-value-section` for Only), so hovering the
label matched both rules and showed the two buttons side by side, shifting
the row layout — the visible hover "jerk".

- Scope the Toggle trigger to the checkbox (`.check-box:hover ~ ...`) so it
  no longer overlaps the label region; Only and Toggle are now mutually
  exclusive by cursor position.
- Stack both buttons in a single grid cell (`.value-actions`) so revealing
  one swaps in place instead of shifting the row.
- Add a fade + slide entry/exit animation (opacity + translateX with
  `@starting-style` and `display` `allow-discrete`), disabled under
  prefers-reduced-motion.

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-28 12:21:39 +00:00
Abhi kumar
a28b95da35 fix(dashboard-v2): keep new-panel Save enabled after running the query (#12311)
* fix(dashboard-v2): keep new-panel Save enabled after running the query

A new panel's Save button re-disabled after Stage & Run: the query-dirty
baseline was derived from the live draft.spec.queries, which the run commits
the current query into, so the baseline drifted onto the just-run query and
isQueryDirty flipped back to false. Freeze the seed used for the new-panel
baseline so a run can't reset it. Existing panels are unaffected (they anchor
to savedQueries).

* fix(dashboard-v2): always allow Save and surface the real save-failure message

Two follow-ups to the new-panel Save regression:

- Decouple the Save button from the dirty check so it is never disabled on
  account of "no changes"; Save is gated only by read-only / in-flight. The
  dirty flag still drives the discard-on-close confirmation.
- On a failed save, show the server's error message in the toast description
  instead of only the generic "Failed to save panel".

* feat(dashboard-v2): show the "Unsaved Changes" badge only when the panel is dirty

Gate the panel-editor header badge on isDirty so it appears only when there
are unsaved edits, and import Badge from the @signozhq/ui/badge subpath.

* chore: replaced toast with the error modal

* fix: dashboard delete calling v1 api
2026-07-28 11:44:55 +00:00
Ashwin Bhatkal
b4b8a9fda0 fix(api): guard ErrorResponseHandlerV2 against non-envelope error bodies (#12209)
* fix(api): guard ErrorResponseHandlerV2 against non-envelope error bodies

The handler assumed every non-2xx response carried the V2 error envelope
and read response.data.error.code directly. During a deployment the
gateway returns a 5xx with an HTML/empty body, so response.data.error is
undefined and the handler threw its own TypeError, masking the real
failure and crashing the caller.

Type the inbound body as unknown and narrow it with an isErrorV2Resp type
guard; when the body isn't a V2 envelope, synthesize an APIError from the
HTTP status instead of throwing. Callers already pass
AxiosError<ErrorV2Resp>, which stays assignable to AxiosError<unknown>.

* refactor(api): keep ErrorV2Resp signature, launder response.data via unknown

Restore the AxiosError<ErrorV2Resp> signature so it documents that this is
the V2 error handler, and confine the runtime uncertainty to the one spot
that matters: launder response.data through a local unknown binding before
narrowing it with the isErrorV2Resp guard.

* fix(api): use UPSTREAM_UNAVAILABLE code for non-envelope error bodies

Address review: when the response body isn't a V2 envelope (e.g. a gateway
5xx during a deploy), throw a stable UPSTREAM_UNAVAILABLE code instead of
the stringified HTTP status, and trim the guard comment.

* fix(api): use UPSTREAM_UNAVAILABLE fallback code in convertToApiError

When the response body carries no error code, fall back to a stable
UPSTREAM_UNAVAILABLE code instead of a stringified HTTP status, mirroring
the ErrorResponseHandlerV2 fallback.

* test(dashboard-v2): update panelStatus fallback code to UPSTREAM_UNAVAILABLE

convertToApiError now returns UPSTREAM_UNAVAILABLE (not a stringified
status) when the response carries no error code; update the panelStatus
fallback assertion to match.

* fix(api): guard generated-API handler + strengthen V2 handler tests

- Guard the deprecated ErrorResponseHandlerForGeneratedAPIs against a
  non-envelope response body (gateway 5xx with HTML/empty body), mirroring
  ErrorResponseHandlerV2 — falls back to UPSTREAM_UNAVAILABLE instead of
  throwing on response.data.error.code.
- Parametrize the V2 handler tests into an { error, expected } table and
  assert the sub-error 'errors' messages, which several UI surfaces rely on.

* revert(api): drop generated-API handler guard from this PR

The deprecated ErrorResponseHandlerForGeneratedAPIs guard broke toAPIError's
defaultMessage fallback (which relied on the handler crashing), regressing the
error UX in ServiceAccount/Roles screens. Moved to a stacked PR + tracked in
engineering-pod#5761. Keeps this PR scoped to ErrorResponseHandlerV2 +
convertToApiError, and the strengthened V2 handler tests remain.

* fix(api): guard deprecated generated-API handler against non-envelope bodies (#12228)
2026-07-28 11:31:26 +00:00
Ashwin Bhatkal
de59c123e1 fix(metrics-explorer): fetch related dashboards from the v3 API (#12312)
The metric details drawer resolved "N dashboards" through
`GET /api/v2/metrics/dashboards`, whose backend walks the raw `data["widgets"]`
array and so only matches v1-schema dashboards. Since #12249 migrated stored
dashboards to the Perses v6 schema and made `/dashboard/:id` render V2
unconditionally, that endpoint has nothing left to match and the popover
silently shows no dashboards.

Switch to `useGetMetricDashboardsV2` (`GET /api/v3/metrics/dashboards`, added in
#11784), which parses the Perses spec. Response items change from
`MetricDashboard` (`widgetId`/`widgetName`) to `DashboardPanelRef`
(`panelId`/`panelName`); the popover only reads `dashboardId`/`dashboardName`,
so the render path is unchanged.

Alerts stay on `/api/v2/metrics/alerts` — there is no v3 counterpart, and it
reads the rule store rather than dashboard schema, so it is unaffected.
2026-07-28 10:33:56 +00:00
Abhi kumar
9aeb9a8240 fix(drilldown): carry the field type through a breakout (#12309)
getBreakoutQuery rebuilt the group-by as `{ key, type }`, dropping `dataType`.
The breakout query then goes out with no field type for the backend to work
from, and a drilldown on the breakout's own result has nothing to branch on —
so a numeric column's filter value gets quoted like a string.

Carrying it through needed the type to be nameable, and it wasn't:
QueryKeyDataSuggestionsProps declared `fieldDataType` as the antlr key-type
enum (`string | number | boolean`), which that endpoint never returns. Five
call sites already cast it back to FieldDataType to get work done.

- declare the suggestions response's `fieldDataType` as FieldDataType, and drop
  the casts that existed only to undo the wrong declaration
- convert where a reported type becomes a query-builder one, so the crossing is
  a function rather than a cast. The table is keyed `Record<FieldDataType, …>`,
  so a type added to the API union fails to compile here instead of going
  missing at runtime
- carry `dataType` through getBreakoutQuery; the object now satisfies
  BaseAutocompleteData on its own, so that cast goes too

Depends on the operator-lookup fix in #12298: a numeric breakout now carries
`float64`, and before that change the menu threw on anything the operator map
didn't have.
2026-07-28 07:38:29 +00:00
Pandey
44828b4185 chore(deps): bump clickhouse-sql-parser to v0.5.2 (#12303)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore(deps): bump clickhouse-sql-parser to v0.5.2

The parser hangs in an infinite loop on an unterminated block comment and panics
on a settings clause with no value, both reachable from user-authored SQL. v0.5.2
fixes those, along with Accept and Walk missing AST children, which anything
walking the tree to inspect a query depends on.

String() on Expr is gone in favour of FormatSQL, so the callers that rendered a
node back to SQL now go through the Format helper, which formats compactly the
way String() did.

* test(querierlogs): cover the rate aggregation family

rate and rate_sum divide by the query window rather than the step, and nothing
exercised that path, so a change to how the aggregation expression is rendered
would have gone unnoticed. Assert both against the inserted logs.

The window is now passed to the request helper instead of relying on its default,
since these are the only assertions in the file that depend on it.

* test(querierlogs): match the response rounding for rate expectations

Scalar responses round floats to three significant figures below one, and the
rates are the only values in this test that do not divide evenly, so compare
against the rounded form rather than the exact quotient.

* test(queriertraces): cover the rate aggregation family

Traces derives the scalar rate window separately from logs, so a divergence
between the two would go unnoticed with only the logs case. rate_sum here is
taken over the intrinsic duration column, which also puts it on the other side
of the response rounding boundary from the logs test.
2026-07-27 20:30:16 +00:00
Abhi kumar
33a0cd043c fix(dashboard-v2): stop the table drilldown crashing on a numeric group-by (#12298)
Clicking a numeric group-by column in a V2 table panel replaced the whole
dashboard with "Something went wrong :/".

getGroupContextMenuConfig indexed QUERY_BUILDER_OPERATORS_BY_TYPES with the
group-by's `dataType` and called `.filter` on the result. That map is keyed by
the V3 data types, but a V2 panel's group-by carries the V5 `fieldDataType`,
and the backend stores every `float64` as `number` — a key the map has never
had. The lookup returned undefined, `.filter` threw during render, and the
page-level error boundary swallowed the dashboard.

The same gap made isNumberDataType miss `number`, so the filter value was sent
as a quoted string instead of a number.

Resolve the operator list through a table that knows `number`, falling back to
the string set so an unmapped type can't white-screen a panel, and treat
`number` as numeric. No query payload changes.
2026-07-27 18:02:18 +00:00
Swapnil Nakade
1a6a693466 refactor(cloud-integrations): remove cloud_integration_id query param (#12300) 2026-07-27 17:57:09 +00:00
Abhi kumar
3e35d1ef64 fix(dashboards-v2): new panel reads clean on open, not dirty (#12297)
The panel-editor dirty check trips a new panel the instant it opens: an
untouched, query-less new panel (e.g. Time Series) showed Save enabled and a
discard-changes prompt with no user edit.

The isDirty third clause `(isNew && draft.spec.queries.length > 0)` gates a new
panel as savable once it carries a query — List auto-seeds one, other kinds open
query-less. It read the live `draft`, but the staged-query sync (added in
f514af469e) commits the builder-seeded query into `draft.spec.queries` on open
for every kind, so the clause tripped even for a query-less panel.

Read the immutable seed `panel.spec.queries` instead — `[]` for non-List (clean
on open), a real query for List / explorer-exports (savable on open). Genuine
edits still surface via isSpecDirty / isQueryDirty.

- PanelEditorContainer test: regression case where the staged sync populated the
  draft but the seed is query-less; the container mock previously returned
  draft === panel, so this class of bug slipped past coverage.
- Query-sync integration tests: a new panel is not query-dirty on mount across
  signals and List.
2026-07-27 17:40:01 +00:00
Aditya Singh
1483fbd2c5 fix(query-builder): coerce table sort values to string to avoid localeCompare crash (#12289)
The QueryTable column sorter called `.localeCompare` on values cast with
`as string`, which is compile-time only. Upstream `processTableRowValue`
normalizes numeric-looking strings to real numbers while null becomes the
string "N/A", so a grouped column can mix numbers and text. Comparing a
number cell against a text cell skipped the numeric branch and invoked
`(200).localeCompare(...)`, throwing "localeCompare is not a function" and
crashing the table on sort.

Extract the compare logic into `compareTableColumnValues` and coerce both
sides with `String(x ?? '')` so any value type sorts safely while
preserving empty-string semantics for null/undefined.

Affects all QueryTable surfaces: Traces/Logs table views, APM Top
Operations, and dashboard Table panels.

Fixes SIGNOZ-UI-5GC
2026-07-27 16:00:29 +00:00
Vikrant Gupta
1255637e25 fix(authz): changelog column type for postgres metastore (#12299) 2026-07-27 15:52:06 +00:00
Naman Verma
38639847be fix: clamp over-wide widgets, drop zero-width widgets, and properly handle invalid order by (#12295) 2026-07-27 15:48:18 +00:00
Aditya Singh
31cb4d7520 feat(logs): unwrap lone message field from json log body (#12206)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-27 13:31:56 +00:00
Ashwin Bhatkal
5ede27e8fb fix(ai-assistant): page context for the V2 panel editor (edit + create) and the v2 dashboards list in the picker (#12291)
* fix(ai-assistant): add page context for the V2 panel editor route

The V2 panel editor lives on `/dashboard/:dashboardId/panel/:panelId`,
which `getAutoContexts` never matched — the three existing dashboard
matchers are all `exact`, so a 4-segment URL fell through every branch
and the assistant opened with no context chip and a page type of
`other`.

A saved panel maps to `panel_edit` with its id. The unsaved `panel/new`
route has no id to attach yet and the schema requires a non-empty
`panel_edit.widgetId`, so it degrades to the dashboard context; the
in-progress query and time range still ride along in shared metadata.

* fix(ai-assistant): use the v2 dashboards list in the context picker

`GET /api/v1/dashboards` is now a stub that returns a V1-deprecated
error, and `useGetAllDashboard` routes errors through `useErrorModal` —
so opening the picker on the Dashboards tab both showed "Failed to load
dashboards" and popped a global error modal.

Switch to `useListDashboardsForUserV2`, the same source the V2 list page
and export picker already use. `resolveAutoContextName` reads the v2
query key from cache too, so auto-context chips resolve to real
dashboard titles again instead of falling back to a generic label.

The assistant was the last live caller of the v1 list: the only other
one, `container/ListOfDashboard`, is unreachable now that the routed
`pages/DashboardsListPage` renders the V2 page.

* fix(ai-assistant): report panel_create on the unsaved panel editor

`/dashboard/:id/panel/new` previously reported `dashboard_detail`, so the
assistant was told the user was looking at a dashboard rather than
creating a panel. It now reports `panel_create`, which renders a "New
panel" chip.

`PageTypeDTO` has no `panel_create` member — `alert_new` is the
precedent it's missing — so `resolvePageType` maps it to `panel_edit`
until the backend adds one. An unmapped key would fall through to
`other` and lose the empty-state chips. The context itself carries no
`widgetId`, which the schema only requires when `metadata.page` is
literally `panel_edit`.

Also drops the `DASHBOARD_WIDGET` matcher. That V1 route is unreachable
— nothing generates a link to it since V2 always builds panel-editor
paths — and it read the `:widgetId` path segment, which V1's own page
ignored in favour of `?widgetId=`, so its `widgetId` was never right.
2026-07-27 13:29:40 +00:00
Ashwin Bhatkal
5d41c5c016 fix(dashboard): variable value hover reveals, readable collapsed-bar tooltips, and Noz in the panel editor (#12286)
* chore(e2e): skip the dashboards specs until they are ported to V2

The V1 -> V2 dashboard migration changes the behaviour those specs assert
against, so they fail as written. Ignore the directory rather than leaving
the suite red, and drop the ignore once the specs are updated.

* feat(ui): add TooltipScrollArea for capped, scrollable hover reveals

A tooltip listing an unbounded number of items (tag chips, variable values)
either grows off-screen or has to truncate. This caps the body at 480px and
scrolls past it, with a thin scrollbar kept visible: a tooltip is transient, so
an auto-hiding one would leave no hint that there is more below.

* feat(NewSelect): reveal a tag's full value on hover

A multi-select tag is cut to maxTagTextLength (and again by CSS in a narrow
control), leaving no way to read what is selected without opening the dropdown.
rc-select sets a `title` on its own tags, but not once a custom `tagRender` is
in play — which this component always supplies.

Wrap each tag in a tooltip carrying the option's untruncated text (the label
handed to tagRender is already cut, so it reads the option instead, falling
back to the raw value for freeform tags). The select provides its own
TooltipProvider so it keeps working wherever it is rendered, rather than
requiring every consumer to sit under an app-level one.

The `+N` overflow is deliberately left alone: several callers already wrap
their own placeholder in a tooltip, and a second one would stack on top.

* fix(dashboard): keep a variable's options across a refetch cycle

A dynamic variable fell back to the "Select value" placeholder whenever a
sibling dynamic's selection changed. The sibling change bumps the variable's
`cycleId`, which is part of its react-query key, so the new key has no data
and the option list blinks empty mid-fetch — and a DYNAMIC ALL selection is
rendered from the options themselves (its value stays null, since ALL travels
as the `__all__` sentinel), so it had nothing to render from.

Keep the previous data across the cycle bump on both fetched-variable queries.
V1 got the same stickiness by holding its options in local state.

* feat(dashboard): make the collapsed variables tooltip readable

The collapsed bar's `+N` tooltip listed each hidden variable as
`name: value`, which runs together — nothing separates the variable from what
it is set to, and a multi-value selection reads as one comma string.

Give each variable two lines instead: `$name` muted above its value, with one
bullet per value when it holds several. Every hidden variable is listed and the
body scrolls, so nothing is truncated out of reach. The tooltip body moves into
its own component, taking the formatting helper out of VariablesBar with it.

* fix(dashboard): reveal the values behind a variable pill's +N on hover

The pill is 180px wide, so only the first selected value gets a tag and the
rest hide behind `+N` — with nothing on hover to say what they are.

Render the overflow as a tooltip listing every hidden value, one bullet each,
scrolling rather than truncating. Each caller owns its own `+N` placeholder,
so this lives here rather than in the shared select.

* feat(dashboard): list the hidden dashboard tags as chips on hover

Hovering the tag cluster's `+N` badge showed the remaining tags comma-joined,
which neither reads as a list nor looks like the tags beside it.

Show them as the same chip used inline, one per line so a long list stays
scannable, scrolling once the list outgrows the tooltip.

* fix(dashboard): offer Noz in the V2 panel editor header

The V2 panel editor is registered as a chromeless full-page route, so AppLayout
drops the side nav — and with it the Noz entry point every other page has. The
assistant panel itself is mounted regardless of full-screen, so only the way in
was missing.

Re-offer it from the editor header, the way V1's own panel editor does.

* fix(ui): sit the hover reveal's scrollbar flush with the tooltip edge

The tooltip body pads 8px all round, so a scroll area inside it left the
scrollbar floating inset from the right edge with dead space beside it.

Give the right padding up on the hosting tooltip and put it back inside the
scroll area, between the content and the bar — the scrollbar now runs along the
tooltip's edge, and a short list keeps the same spacing it had before.

* feat(dashboard): resolve a dashboard icon from a PNG as well as an SVG

The `image` field references an asset by name without an extension, but the
Icons glob only matched SVG, so a PNG dropped in that folder silently fell back
to the default icon. Logos already matched both.

Match `{svg,png}` there too, so either format resolves from the same
extension-less path. No backend change needed — `validateImage` only checks the
`/assets/Icons/` prefix, never the file type.
2026-07-27 08:00:35 +00:00
Abhi kumar
6dcc9f191d fix(query-builder): drop empty having from V5 query payload (V2 panel dirty-on-load) (#12288)
* fix(query-builder): drop empty having from V5 query payload

An empty having (`{ expression: "" }`) — seeded by the query builder for
"no having filter" and produced when an empty having array round-trips
through the URL — was serialized into the V5 query payload instead of being
omitted. A saved panel never carries one, so the V2 panel editor's
live-vs-saved envelope comparison never matched and an untouched panel read
as dirty the instant the editor opened. View mode was unaffected as it
never runs that comparison.

`normalizeHaving` now treats a blank/array/nullish having as absent at both
serializer emission sites (createBaseSpec + createTraceOperatorBaseSpec),
closing the gap in the existing intent that already dropped empty-array
having. An empty having is a no-op filter, so query results, alert
evaluation, and export contents are unchanged; the export payload now omits
it consistently with the already-cleared groupBy.

Tests:
- serializer unit coverage: array / blank / whitespace / nullish having
  serialize to undefined; a real having expression is preserved
- panel-editor query-sync integration test: an untouched no-having panel is
  not dirty on mount (fails without the fix)
- DownloadOptionsMenu assertion updated to the corrected (dropped) shape

* fix(dashboards-v2): scroll panel empty-state instead of clipping actions

When a panel is too small to fit the empty-state icon + text + action
buttons (no query / no data / error), the centred column clipped the
buttons at the panel edge and they became unreachable.

Let the message column scroll (`overflow: auto`) with the shared panel
scrollbar, and use `justify-content: safe center` so the top stays
reachable once content overflows. Cap the actions row at `max-width: 100%`
so it never forces horizontal overflow.
2026-07-27 07:57:56 +00:00
Abhi kumar
52df42511b fix(dashboard-v2): config-pane restyle, section quick-add, pie labels & list pagination (#12262)
* fix(dashboard-v2): align config-pane control borders and switch radius

Give the ConfigSelect and FormattingSection ant-select selectors the
standard --l2-border color so they match the other full-width controls,
and drop the ConfigSwitch container radius from 6px to 2px for parity.

* fix(dashboard-v2): apply legend format template to pie slice labels

When a single value column has a legend format, run it through
getLabelName so {{key}} placeholders resolve to the group-by values
instead of showing the raw template string.

* fix(dashboard-v2): treat a full page as has-more for non-timestamp sorts

The backend only emits nextCursor on the timestamp-ordered window path;
a non-timestamp sort falls back to plain offset paging with no cursor.
Fall back to a full-page heuristic for canNext so list/raw panels can
page past the first page under those sorts, matching the logs/traces
explorers.

* fix(dashboard-v2): restyle config pane (accent marker, dividers, scrollbar)

- Rename header to 'Panel Details' with an accent marker; move the
  Display eyebrow to 'DISPLAY OPTIONS'.
- Switch dividers/section separators to var(--l1-border) and keep the
  divider from collapsing on overflow.
- Adopt the shared custom-scrollbar mixin in the config pane and the
  legend colors list.
- Align the threshold select border with the l2-border control style.

* feat(dashboard-v2): add header quick-add "+" to config sections

- SettingsSection gains a generic headerAction slot and controllable
  open state; the header splits into a toggle button plus action + chevron.
- SectionSlot maps a per-kind header action and wires registerHeaderAction,
  with a pending-action hop so a collapsed section expands then runs the add.
- Thresholds and Context Links register their add handlers; open by default
  only when already populated.

* chore: updated icons

* chore: pr review fixes
2026-07-27 07:36:44 +00:00
Srikanth Chekuri
08715a704a feat(rulestatehistory): populate related logs/traces links in v2 history APIs (#12211)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(rulestatehistory): populate related logs/traces links in v2 history APIs

The v2 rule history timeline dropped the relatedLogsLink/relatedTracesLink
that v1 (getRuleStateHistory) returned per entry, which the alert history
page uses to jump from a state change to the explorer with the rule's
filter and the entry's labels. Load the rule from the rule store in the
module and build the links with contextlinks, scoped to the entry's
evaluation window like v1.

Extract the builder-query filter/group-by selection that the v1 handler
and threshold rule notifications each inlined into
contextlinks.BuilderQueryForSignal and reuse it from both the module and
ThresholdRule.

Also populate the links for top contributors, which both v1 (since #10760)
and v2 returned as always-empty fields even though the UI renders them;
contributor links span the queried range since the counts aggregate it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(contextlinks): remove unused v3 link helpers

PrepareLinksToTraces, PrepareLinksToLogs and PrepareFilters lost their
last callers when the deprecated v3/v4 rule support was removed in #10760;
the v5 equivalents (PrepareParamsFor*V5 and PrepareFilterExpression) are
what all remaining callers use.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: end doc comments with a period to satisfy godot

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(alerts): cover v2 rule history related links for logs and traces

Each test fires a rule with a filter and a service.name group-by, then
asserts the recorded firing entry and top contributor carry a related
explorer link for the rule's signal only, with the label-rewritten filter
expression, the evaluation window on timeline entries and the queried
range on contributors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(contextlinks): shrink explorer links to the minimal payload

The explorer pages read only the data source and filter expression from a
shared link and fill in the rest of the query shape with defaults, so stop
shipping the v3 builder-query ceremony (queryName, aggregateOperator,
aggregateAttribute, stepInterval, paging fields) and the timeRange and
options params nothing reads. Links shrink from ~1.2k to ~450 chars and
contextlinks no longer depends on the v3 model.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(rulestatehistory): derive link windows from the evaluation envelope

Rules created through the current UI store the window in the v2alpha1
evaluation envelope with no top-level evalWindow, so the previous 5m
fallback produced wrong link windows for any non-default rolling window
and could not represent cumulative windows at all. Use the envelope's
NextWindowFor like the rule engine does, keeping the top-level
evalWindow (default 5m) as the fallback for rules without an envelope.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(contextlinks): simplify double-encoding comment

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(alerts): use literal matchType/op in fixtures and drop link unit tests

Replace the numeric matchType/op codes in all alert scenario fixtures
with their literal forms (at_least_once, above, ...) which the API
normalizes to the same canonical values, and remove the rule history
link unit tests since the integration tests cover the behavior
end-to-end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(alerts): move rule history helpers into the shared alerts fixtures

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 06:38:44 +00:00
Naman Verma
41c66f2634 chore: add sql migration for dashboards (#12249)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore: add migration script from current to perses dashboard

* fix: move WrapInV5Envelope to types package

* fix: generate internal name from title

* fix: match with lower case signal for variables

* fix: sanitize tags instead of throwing error

* fix: extract row and widget positions to build expanded sections

* chore: add a catch all panic check to log migration error

* chore: catch typecast errors

* fix: remove nil nil return

* test: fix ut to check for v2 internal name

* chore: remove spec md file

* chore: separate error type for migration

* feat: note down all errors in migration

* fix: allow zero value for threshold values

* fix: ignore react placeholders in layout

* fix: note error in query parsing

* fix: read threshold value properly during migration

* fix: adjust to schema changes in variables

* test: fix unit tests

* fix: catch error from decodeTelemetryFields

* fix: make threshold value non-nullable

* fix: handle list of widget IDs in panel maps

* fix: add better error note down for failed conversions

* fix: normalize having array from v4 schema

* fix: remove metric aggregation from non metric queries (malformed json)

* fix: normalize telemetry field keys in query

* chore: add temporary doc for other malformation handlers needed

* fix: add more malformed query handling

* fix: add more malformation handling

* chore: reuse transition package (adds dependency, need to see what to do)

* fix: fix go lint issue

* revert: remove md file

* fix: make none the default fill mode during migration

* fix: add nil check on limit value when normalizing page size

* fix: validate dashboard spec after migration

* fix: remove unused method

* fix: match shape safe version to existing version

* chore: improve variable names

* chore: better comments and names in layout migrator

* chore: add explanation comment for continuing on empty id widget

* fix: ditch dynamic vars with no attr, rearrange overlapping layouts

* fix: add default aggregation count() if none is present in logs/traces

* fix: add empty list tolerance to v1 variables

* fix: add fixes based on backup migration testing

* chore: skip over unreferenced widgets

* chore: remove widgets that have a single query that has no metric name

* chore: assign missing formula names like ui does

* chore: assign query names to queries if missing

* chore: drop legacy filter fields that ui also ignores

* chore: make migration drop widgets that have no aggregations for metrics

* chore: normalize group by

* chore: remove expressions from metric aggregations

* chore: add more error notes

* chore: replace em dash with hyphen in widget id

* chore: add more panel id sanitization

* chore: replace faulty order by keys with aggregation expression

* chore: fill valid span gaps

* chore: handle misformed threshold operators

* chore: remove repeat occurences of widgets in layouts

* chore: remove limits that cross max limit

* chore: restore function args malformed by v4->v5 migration

* chore: remove invalid functions

* chore: skip variables in wrong type

* chore: add wdiget id type check in layout migration

* chore: add a.count to malformed order by keys list

* chore: remove bad aggregations that accompany valid ones

* chore: drop trace operators with no expression

* chore: drop invalid formulas

* chore: skip unknown panel kind

* chore: drop widgets with >1 and all aggregations as malformed

* chore: skip empty type variables

* chore: pass threshold format raw without typecasting

* chore: add handling for trace operators around wrapinv5env

* chore: handle no string value for variable sort

* test: fix span gaps test

* chore: undo schema change in threshold value

* chore: final set of error fixes/hacks

* fix: fix build errors post merge conflicts

* test: remove test for floating pt value

* test: use appendf instead of sprintf

* feat: add scaffolding to migrate dashboards

* chore: add sql migration for dashboards

* fix: fill in ref path when building grid layout

* feat: handle v1 payloads in v2 create api

* fix: return empty objects instead of null if no variables/panels/layouts are there

* test: fix unit test for empty layouts

* test: fix unit test for empty layouts

* fix: add empty links array in migration

* test: add unit test to show v5  takes precedence over v4

* fix: change EXISTS to exists so that migrateCommon handles it properly

* test: add unit test for count with attributes

* fix: run order by handling after default aggregation handling

* fix: restore formula fields that wrapinv5envelope removes

* fix: keep thresholds that do not have an optional label

* fix: force allowAll to be false if allowMultiple is false

* fix: migrate name column even if data column migration fails

* chore: add orgid name unique index post dashboard migration

* fix: use slog for logging

* refactor(dashboard): re-host ConvertAllV1ToV2 off the Module interface

Mirror base's removal of ConvertAllV1ToV2 from the shared files (Module
interface, v2_module.go, EE delegation, result types) so future base→branch
merges stay conflict-free, and re-host the capability in dedicated branch-only
files (V1ToV2Migrator interface + module method + result types). Migration 103
now obtains it via a dashboard.V1ToV2Migrator type assertion.

* refactor(dashboard): drop ConvertAllV1ToV2 module scaffolding from base

Remove the temporary v1→v2 bulk-conversion module method (ConvertAllV1ToV2 +
migrateOneV1ToV2), its result types (V1ToV2MigrationResult / V1ToV2MigrationItem),
the Module interface entry, and the EE delegation. This scaffolding lives on the
migration feature branches, not the base branch that merges to main.

V1Name and store.UpdateName are kept (small helpers; UpdateName is on the shared
Store interface).

* fix: add image validation and base64 to asset conversion

* fix: move org migration from module to 103

* refactor(dashboard): always use V2, remove use_dashboard_v2 flag (#12252)

* chore: pass tag module and dashboard store from signoz.go into the migration

* chore: run migration in transaction

* test(dashboards-v2): drop V1 export variant from explorer export tests

The use_dashboard_v2 flag was removed on this branch, but #12283 landed on
main making these tests flag-aware (V1 + V2). The merge left the suite
referencing FeatureKeys.USE_DASHBOARD_V2 (type error) and exercising a V1
dashboards API the export hooks no longer call (3 failing tests).

Collapse describe.each to the V2 contract only, matching how the sibling
export-hook tests were de-flagged.

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Ashwin Bhatkal <ashwin96@gmail.com>
Co-authored-by: Pandey <vibhupandey28@gmail.com>
2026-07-26 17:57:39 +00:00
Abhi kumar
503afb13d4 test(dashboards-v2): make explorer export tests flag-aware (V1 + V2) (#12283)
The "Add to dashboard" export dialog is flag-aware via `use_dashboard_v2`:
V1 hits `/api/v1/dashboards`, V2 hits the generated endpoints
`GET /api/v2/users/me/dashboards` and `POST /api/v2/dashboards`, whose
response shapes differ. The tests only mocked V1 and only ran the V1 path
(the flag is off in the default test context), so the V2 contract was
never exercised.

Parametrize the onExport tests over the `use_dashboard_v2` flag, mocking
and asserting per contract so both paths are covered and the suite can't
drift when the default flips. Also sync on the picker's enabled (loaded)
state before clicking the combobox — antd disables the Select while the
list request is in flight and a click on a disabled combobox is a no-op.
2026-07-26 16:30:47 +00:00
Naman Verma
774dfc48ae chore: deprecate v1 dashboard APIs with proper reference to v2 APIs (#12273)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore: deprecate v1 dashboard APIs with proper reference to v2 APIs

* fix: use generic doc for all deprecated APIs

* test: update integratoin tests to account for deprecation
2026-07-26 14:43:51 +00:00
Naman Verma
d013eab29d chore: migrate integration dashboards to v2 (#12242)
* chore: add migration script from current to perses dashboard

* fix: move WrapInV5Envelope to types package

* fix: generate internal name from title

* fix: match with lower case signal for variables

* fix: sanitize tags instead of throwing error

* fix: extract row and widget positions to build expanded sections

* chore: add a catch all panic check to log migration error

* chore: catch typecast errors

* fix: remove nil nil return

* test: fix ut to check for v2 internal name

* chore: remove spec md file

* chore: separate error type for migration

* feat: note down all errors in migration

* fix: allow zero value for threshold values

* fix: ignore react placeholders in layout

* fix: note error in query parsing

* fix: read threshold value properly during migration

* fix: adjust to schema changes in variables

* test: fix unit tests

* fix: catch error from decodeTelemetryFields

* fix: make threshold value non-nullable

* fix: handle list of widget IDs in panel maps

* fix: add better error note down for failed conversions

* fix: normalize having array from v4 schema

* fix: remove metric aggregation from non metric queries (malformed json)

* fix: normalize telemetry field keys in query

* chore: add temporary doc for other malformation handlers needed

* fix: add more malformed query handling

* fix: add more malformation handling

* chore: reuse transition package (adds dependency, need to see what to do)

* fix: fix go lint issue

* revert: remove md file

* fix: make none the default fill mode during migration

* fix: add nil check on limit value when normalizing page size

* fix: validate dashboard spec after migration

* fix: remove unused method

* fix: match shape safe version to existing version

* chore: improve variable names

* chore: better comments and names in layout migrator

* chore: add explanation comment for continuing on empty id widget

* fix: ditch dynamic vars with no attr, rearrange overlapping layouts

* fix: add default aggregation count() if none is present in logs/traces

* fix: add empty list tolerance to v1 variables

* fix: add fixes based on backup migration testing

* chore: skip over unreferenced widgets

* chore: remove widgets that have a single query that has no metric name

* chore: assign missing formula names like ui does

* chore: assign query names to queries if missing

* chore: drop legacy filter fields that ui also ignores

* chore: make migration drop widgets that have no aggregations for metrics

* chore: normalize group by

* chore: remove expressions from metric aggregations

* chore: add more error notes

* chore: replace em dash with hyphen in widget id

* chore: add more panel id sanitization

* chore: replace faulty order by keys with aggregation expression

* chore: fill valid span gaps

* chore: handle misformed threshold operators

* chore: remove repeat occurences of widgets in layouts

* chore: remove limits that cross max limit

* chore: restore function args malformed by v4->v5 migration

* chore: remove invalid functions

* chore: skip variables in wrong type

* chore: add wdiget id type check in layout migration

* chore: add a.count to malformed order by keys list

* chore: remove bad aggregations that accompany valid ones

* chore: drop trace operators with no expression

* chore: drop invalid formulas

* chore: skip unknown panel kind

* chore: drop widgets with >1 and all aggregations as malformed

* chore: skip empty type variables

* chore: pass threshold format raw without typecasting

* chore: add handling for trace operators around wrapinv5env

* chore: handle no string value for variable sort

* test: fix span gaps test

* chore: undo schema change in threshold value

* chore: final set of error fixes/hacks

* fix: fix build errors post merge conflicts

* test: remove test for floating pt value

* test: use appendf instead of sprintf

* chore: migrate integration dashboards to v2

* feat: add scaffolding to migrate dashboards

* fix: fill in ref path when building grid layout

* feat: handle v1 payloads in v2 create api

* fix: return empty objects instead of null if no variables/panels/layouts are there

* test: fix unit test for empty layouts

* fix: add empty links array in migration

* chore: rerun migration after links and signal change

* test: add unit test to show v5  takes precedence over v4

* fix: change EXISTS to exists so that migrateCommon handles it properly

* test: add unit test for count with attributes

* fix: run order by handling after default aggregation handling

* fix: restore formula fields that wrapinv5envelope removes

* fix: keep thresholds that do not have an optional label

* fix: force allowAll to be false if allowMultiple is false

* chore: rerun migration

* fix: migrate name column even if data column migration fails

* fix: use slog for logging

* refactor(dashboard): re-host ConvertAllV1ToV2 off the Module interface

Mirror base's removal of ConvertAllV1ToV2 from the shared files so future
base→branch merges stay conflict-free, and re-host the capability in dedicated
branch-only files (V1ToV2Migrator interface + module method + result types).

* refactor(dashboard): drop ConvertAllV1ToV2 module scaffolding from base

Remove the temporary v1→v2 bulk-conversion module method (ConvertAllV1ToV2 +
migrateOneV1ToV2), its result types (V1ToV2MigrationResult / V1ToV2MigrationItem),
the Module interface entry, and the EE delegation. This scaffolding lives on the
migration feature branches, not the base branch that merges to main.

V1Name and store.UpdateName are kept (small helpers; UpdateName is on the shared
Store interface).

* fix: add image validation and base64 to asset conversion

* fix: remove unneeded interface

* chore: rerun migration

* fix: make ReencodeInlineSVGImage so that migration script can call it

* chore: remove temp script

* fix: remove local laptop default value

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-07-26 14:15:54 +00:00
Abhi kumar
27f47f3ebc fix(dashboard): V2 pie legend format/height + table empty-cell parity with V1 (#12282)
* fix(dashboard): align pie chart legend height with other panels

The pie legend wrapper was missing box-sizing:border-box and
overflow:hidden and applied top padding unconditionally, so its height
exceeded the value from calculateChartDimensions and clipped the donut.
Mirror the shared chart legend wrapper so the height is honored, gating
the top padding to the right-legend position.

* fix(dashboard): render empty table cells as n/a instead of zero

Empty scalar cells (null/undefined/'') were coerced via Number() to 0,
so they rendered as 0, picked up value-column color thresholds, and
sorted as real zeros. Route cells through toCellNumber (NaN for empty)
so empties show n/a, skip threshold coloring, and sort last.

* fix(dashboard): serialise V2 pie legends as {key="value"} for parity with V1

V2's pie renderer joined only the group-by values, showing legends like
"write" where V1 shows {direction="write"}. Route the single-value-column
label through getLabelName (as V1's slicesFromSeries does), reusing the
labels map already built for drilldown. Multi-value-column labels are
unchanged.
2026-07-26 14:09:15 +00:00
Srikanth Chekuri
18f5baafa0 fix: enforce scalar response contract + reject invalid v2 dashboard bodies (#12276)
* fix: enforce scalar response contract for promql and metric builder queries

* fix: reject invalid v2 dashboard bodies instead of migrating them as v1

* fix(dashboards-v2): post legacy v1 dashboards unchanged from the import flow

* fix: add reduce to for scalar requests if not present

---------

Co-authored-by: Naman Verma <naman.verma@signoz.io>
2026-07-26 11:25:01 +00:00
Naman Verma
e728942fec fix: handle malformed reduceTo + pick correct columns for traces in list panel (#12275)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
2026-07-25 14:57:29 +00:00
Naman Verma
5bf95534ad fix: reencode svg images to base64 when migrating dashboards (#12274)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-25 13:01:34 +00:00
Naman Verma
51819d6337 chore: add migration script from current to perses dashboard (#11712)
* chore: add migration script from current to perses dashboard

* fix: move WrapInV5Envelope to types package

* fix: generate internal name from title

* fix: match with lower case signal for variables

* fix: sanitize tags instead of throwing error

* fix: extract row and widget positions to build expanded sections

* chore: add a catch all panic check to log migration error

* chore: catch typecast errors

* fix: remove nil nil return

* test: fix ut to check for v2 internal name

* chore: remove spec md file

* chore: separate error type for migration

* feat: note down all errors in migration

* fix: allow zero value for threshold values

* fix: ignore react placeholders in layout

* fix: note error in query parsing

* fix: read threshold value properly during migration

* fix: adjust to schema changes in variables

* test: fix unit tests

* fix: catch error from decodeTelemetryFields

* fix: make threshold value non-nullable

* fix: handle list of widget IDs in panel maps

* fix: add better error note down for failed conversions

* fix: normalize having array from v4 schema

* fix: remove metric aggregation from non metric queries (malformed json)

* fix: normalize telemetry field keys in query

* chore: add temporary doc for other malformation handlers needed

* fix: add more malformed query handling

* fix: add more malformation handling

* chore: reuse transition package (adds dependency, need to see what to do)

* fix: fix go lint issue

* revert: remove md file

* fix: make none the default fill mode during migration

* fix: add nil check on limit value when normalizing page size

* fix: validate dashboard spec after migration

* fix: remove unused method

* fix: match shape safe version to existing version

* chore: improve variable names

* chore: better comments and names in layout migrator

* chore: add explanation comment for continuing on empty id widget

* fix: ditch dynamic vars with no attr, rearrange overlapping layouts

* fix: add default aggregation count() if none is present in logs/traces

* fix: add empty list tolerance to v1 variables

* fix: add fixes based on backup migration testing

* chore: skip over unreferenced widgets

* chore: remove widgets that have a single query that has no metric name

* chore: assign missing formula names like ui does

* chore: assign query names to queries if missing

* chore: drop legacy filter fields that ui also ignores

* chore: make migration drop widgets that have no aggregations for metrics

* chore: normalize group by

* chore: remove expressions from metric aggregations

* chore: add more error notes

* chore: replace em dash with hyphen in widget id

* chore: add more panel id sanitization

* chore: replace faulty order by keys with aggregation expression

* chore: fill valid span gaps

* chore: handle misformed threshold operators

* chore: remove repeat occurences of widgets in layouts

* chore: remove limits that cross max limit

* chore: restore function args malformed by v4->v5 migration

* chore: remove invalid functions

* chore: skip variables in wrong type

* chore: add wdiget id type check in layout migration

* chore: add a.count to malformed order by keys list

* chore: remove bad aggregations that accompany valid ones

* chore: drop trace operators with no expression

* chore: drop invalid formulas

* chore: skip unknown panel kind

* chore: drop widgets with >1 and all aggregations as malformed

* chore: skip empty type variables

* chore: pass threshold format raw without typecasting

* chore: add handling for trace operators around wrapinv5env

* chore: handle no string value for variable sort

* test: fix span gaps test

* chore: undo schema change in threshold value

* chore: final set of error fixes/hacks

* fix: fix build errors post merge conflicts

* test: remove test for floating pt value

* test: use appendf instead of sprintf

* feat: add scaffolding to migrate dashboards

* fix: fill in ref path when building grid layout

* feat: handle v1 payloads in v2 create api

* fix: return empty objects instead of null if no variables/panels/layouts are there

* test: fix unit test for empty layouts

* fix: add empty links array in migration

* test: add unit test to show v5  takes precedence over v4

* fix: change EXISTS to exists so that migrateCommon handles it properly

* test: add unit test for count with attributes

* fix: run order by handling after default aggregation handling

* fix: restore formula fields that wrapinv5envelope removes

* fix: keep thresholds that do not have an optional label

* fix: force allowAll to be false if allowMultiple is false

* fix: migrate name column even if data column migration fails

* fix: use slog for logging

* refactor(dashboard): drop ConvertAllV1ToV2 module scaffolding from base

Remove the temporary v1→v2 bulk-conversion module method (ConvertAllV1ToV2 +
migrateOneV1ToV2), its result types (V1ToV2MigrationResult / V1ToV2MigrationItem),
the Module interface entry, and the EE delegation. This scaffolding lives on the
migration feature branches, not the base branch that merges to main.

V1Name and store.UpdateName are kept (small helpers; UpdateName is on the shared
Store interface).

* fix: add image validation and base64 to asset conversion

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-07-25 08:41:07 +00:00
Nikhil Mantri
d22ee8f7aa fix(telemetrymetadata): update fallback to false for positive operators in related values queries (#12250)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
* chore: update fallback to false for positive operators

* chore: changed to distributed table

* chore: flip AND to or in outside condition

* chore: added data_source condition

* chore: added integration tests

* chore: simplified comment

* chore: more simplified comment

* chore: test case both columns contain host.name -> resources take precedence
2026-07-25 04:08:25 +00:00
Ashwin Bhatkal
5b004d1efc refactor(dashboard): store system icons as SVG assets with a safe image resolver (#12259)
* feat(dashboard-v2): add file-based dashboard icons and logos with a safe image resolver

* refactor(dashboard-v2): render dashboard icons via the safe resolver

* fix(dashboard-v2): clamp dashboard icon size to 16px

* fix(dashboard-v2): reject invalid dashboard image before saving

* fix(dashboard-v2): validate dashboard image server-side

* test(dashboard-v2): stub the Vite-only icon glob for jest and align image fixtures

* test(dashboard-v2): update patch test for image validation

* refactor(dashboard-v2): hoist dashboard image consts/regex and tidy validation tests

* refactor(dashboard-v2): drop the validateImage doc comment
2026-07-25 03:19:19 +00:00
Naman Verma
ecb77af4cb chore: fix schema and validations based on migration errors (#12263)
Some checks failed
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / staging (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
* chore: fix schema based on migration errors

* test: add rejection based integration tests for new validations

* fix: remove datasource field from schema
2026-07-24 15:37:04 +00:00
Tushar Vats
973429a22f fix(logs): stop hasToken and hasAny/hasAll 500s on separator and big-int needles (#12261)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
hasToken(body, <needle>) returned a 500 whenever the needle contained a
token separator or whitespace (ClickHouse code 36). Validate the needle
up front in conditionForHasToken (the single choke point for both legacy
and JSON modes) and return a clean 400 pointing at CONTAINS instead.

hasAny/hasAll on a legacy body array returned a 500 for a quoted integer
needle >= 2^32: clickhouse-go binds it as a concrete Array(UInt64), which
has no supertype with the Array(Nullable(Int64)) extraction that the
function must unify (code 386). CAST the needle array to Array(Int64) to
match the extraction. Scalar has() and the scalar OR-fallback are
value-level and unaffected.
2026-07-24 12:56:56 +00:00
Swapnil Nakade
9f5ad1ba26 fix: list gcp accounts was missing config (#12175)
* fix: list gcp accounts was missing config

* refactor: updating cloudintegration integration tests

* refactor: moving variables to test file

* chore: removing verbose comments
2026-07-24 10:56:33 +00:00
Naman Verma
b2574e7797 fix: remove requirement for links to be always present (#12260)
* fix: remove requirement for links to be always present

* fix: make links use defined type

* test: add integration test for link omission roundtrip

* test: change not in to None for links in panel

---------

Co-authored-by: Ashwin Bhatkal <ashwin96@gmail.com>
2026-07-24 10:54:47 +00:00
Ashwin Bhatkal
cbde4dca41 fix(dashboard-v2): templates header, long-title handling, variable icon & unified delete modal (#12256)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(dashboard-v2): add "Request a new template" header to templates tab

* fix(dashboard-v2): keep toolbar tags intact when the dashboard title is long

* fix(dashboard-v2): use a subtle outline info icon in the variables bar

* fix(dashboard-v2): truncate long dashboard title in the breadcrumb

* refactor(dashboard-v2): share one delete-confirm modal for views and dashboards

* fix(dashboard-v2): reduce panel area horizontal padding

* fix(dashboard-v2): show loader while deleting a saved view

Deleting a saved view was fire-and-forget: the confirm modal closed instantly
and the row vanished later on refetch, with no loading feedback. Make the
delete awaitable end-to-end (deleteView -> removeView -> handleRemoveView ->
ViewsRail onConfirm) so the shared confirm modal keeps its Delete button
loading until the backend call settles, then closes — matching dashboard
delete. The active view resets only on success.

* fix(dashboard-v2): fire delete success toast after the list refetches

Move the dashboard delete success toast to after the list is invalidated and
refetched, so it appears once the row is gone, and use a plain success message.

* fix(dashboard-v2): centre the delete-confirm alert icon to match v1

The shared delete-confirm modal top-aligned the CircleAlert (align-items:
flex-start + a margin-top nudge) at size 20; centre it against the body
(align-items: center) at size 3xl, matching the v1 dashboard delete button.
2026-07-23 21:36:22 +00:00
Ashwin Bhatkal
aabe59103d fix(dashboard-v2): variable selection (default reset + multiselect commit-on-close) (#12254)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(NewSelect): make multi-select Only/All + Toggle real clickable pills

* fix(dashboard-v2): reset variable default only on real option-set changes

* fix(dashboard-v2): multiselect value selection — commit on close, skip unchanged cascade, allow clear

* fix(dashboard-v2): fix multiselect tag layout in the variable pill

* fix: format issue

* fix(dashboard-v2): clear invalid variable default and fix useVariableForm test OOM

Stabilize the useVariableForm test props so the reset-on-`initial` effect no
longer loops into a heap OOM (the hook relies on a stable `initial` reference,
which memoized callers already provide). With the suite now running, align the
QUERY/CUSTOM default-reset to clear an invalidated default to empty rather than
pinning the first option, matching the DYNAMIC path and letting resolution fall
back to the first option / ALL.

* refactor(NewSelect): extract option-row button handler out of JSX

Pull the repeated stopPropagation/preventDefault/select/reset logic on the
option row's checkbox, Only/All and Toggle buttons into a single
`selectFromButton(e, source)` helper so the JSX stays readable.
2026-07-23 20:08:56 +00:00
Ashwin Bhatkal
6c957d1e8b feat(dashboard-v2): ANTLR-composed apply-to-panels with an impact review dialog (#12181)
* fix(dashboard-v2): compose panel filter via ANTLR so apply/remove respect precedence

* feat(dashboard-v2): review apply-to-panels query changes in the impact dialog

* feat(dashboard-v2): surface non-builder panel queries in the apply-to-panels review

findApplyUsages now emits an editable row for every selected panel query that
does not yet reference the variable — PromQL/ClickHouse rows default to their
current text (never auto-injected) so the review dialog opens for them instead
of silently no-op'ing. Adds isVariableAppliedToAllPanels, a cheap boolean scan
(no ANTLR) for the 'apply to all' disabled state.

* feat(dashboard-v2): route apply-to-all through the review dialog

The list-row 'Apply to all' now opens the same VariableImpactDialog review (all
panels as target) instead of a plain confirm, and is disabled with an 'Already
applied to all panels' tooltip once every panel query references the variable.
Removes the now-redundant ApplyToAllDialog and the dead build*VariableToPanelsPatch
helpers.
2026-07-23 19:42:49 +00:00
Ashwin Bhatkal
de1e21a050 fix(dashboard-v2): variable, panel-layout, and dashboards-list bug-bash fixes (#12178)
* feat(dashboard-v2): compact panel layout before persisting drag and JSON edits

* feat(dashboard-v2): resolve and persist user-typed variable selection across refetch

* feat(dashboard-v2): expose image field and close-on-Escape in the JSON editor

* fix(dashboard-v2): keep a custom dashboard image selectable in the overview picker

* fix(dashboard-v2): variable form & bar fixes

* fix(dashboard-v2): unify section title modal, keep open on error

* refactor(dashboard-v2): dashboard-list tags (popover to tooltip, TagBadge, DashboardRowTags)

* fix(dashboard-v2): sync locked state to the detail cache after list-page toggle

* fix(dashboard-v2): stop the variable value control from showing scrollbars

* fix(dashboard-v2): hide the not-recommended pill below 1280px, not 1024px
2026-07-23 18:21:12 +00:00
Nikhil Soni
85abfd626e fix(tracedetail): correct EndTimestampMillis in flamegraph API response (#12251)
* fix(tracedetail): use span-derived bounds for flamegraph EndTimestampMillis

The trace_summary MV stores max(timestamp) as 'end', which is the maximum
span *start* time. For the final span of a trace, this misses the span's
duration entirely, making EndTimestampMillis shorter than the actual trace end.

FlamegraphTrace already computed the correct end via updateTimeRange
(end = max(span_start + duration)) but only used it internally for bucket
sampling. Add TimeRange() to expose these span-derived bounds and use them
in both getFullFlamegraph and getWindowedFlamegraph instead of summary.End.

The waterfall was unaffected — NewWaterfallTraceFromSpans already computes
endTime = max(span.TimeUnix + span.DurationNano) from actual spans.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GxTqz7CqqmoFEPHFqhJUCa

* chore: remove unnecessary comments

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-23 17:21:29 +00:00
Aditya Singh
66c7e2d157 feat(trace-details): download full trace from trace details page (#12115)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat: add blob-stitching and part-fetch primitives for chunked downloads

* feat: add bounded worker-pool runner for chunked downloads

* feat: add trace download store, query and progress panel

* feat: add download trace option to trace options menu

* feat: update tests
2026-07-23 12:39:27 +00:00
Vinicius Lourenço
3c5c2cdcd9 refactor(infrastructure-monitoring-v2): remove map between dot and underscore attributes (#12214)
* refactor(infrastructure-monitoring-v2): remove map between dot and underscore attributes

* test(entity-metrics): fix test
2026-07-23 11:34:38 +00:00
Gaurav Tewari
cd1861ff87 chore: bump package versions (#12213)
* chore: bump axios version

* chore: bump more packages

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-23 11:03:19 +00:00
Nikhil Mantri
f0a0b95ecd chore: removed code and tests (#12243)
Co-authored-by: Pandey <vibhupandey28@gmail.com>
2026-07-23 10:48:44 +00:00
Ashwin Bhatkal
38340b5027 fix(dashboards-v2): dedicated "all" dynamic-variable signal + required non-nullable links (#12201)
* fix(dashboards-v2): make panel/dashboard links required and non-nullable

* fix: validate links on read from db as well

* fix: allow all as value for signal

* fix: dont allow empty string for signal

* fix(dashboards-v2): dedicated `all` dynamic-variable signal (frontend + client)

* test: add empty links to new payloads in integration tests

---------

Co-authored-by: Naman Verma <naman.verma@signoz.io>
2026-07-23 10:34:18 +00:00
Abhi kumar
fba56e9a64 fix(dashboard): filter-quote escaping, panel export encoding, right-legend width, number-panel query warning (#12246)
* fix(qb): stop doubling escaped quotes on filter round-trip

formatSingleValue escapes ' -> \' when quoting a filter value, but its inverse
(unquote, in formatSingleValueForFilter) stripped the quotes without unescaping.
Each expression <-> filters round-trip therefore added a backslash. "Create
alert from panel" re-reads the query through the URL twice, so a filter like
name = 'it\'s a ribbon' arrived at the alert page as name = 'it\\'s a ribbon'
and failed the filter parser. Unescape \' -> ' so the round-trip is lossless.

* fix(dashboard): double-encode compositeQuery in panel export link

useGetCompositeQueryParam decodes the compositeQuery param twice, so a single
encode left a bare %/+ from a filter expression (e.g. ILIKE 'Inf%') that made
the reader's second decode throw and drop the whole query. Encode twice in
buildExportPanelLink so the query survives the round-trip.

* fix(dashboard): size right legend column to the longest label

A right-positioned legend is a single vertical column, so give it its own width
budget and size it to fit the longest series label, clamped to
[150px, min(320, 40% of container width)], instead of the shared bottom-legend
cap. Long service names no longer ellipsize in the pie/donut legend.

* feat(dashboard): warn when a number panel has more than one query enabled

A Number panel renders only the first query's value, so leaving extra
queries enabled (e.g. a formula plus its inputs) silently shows the wrong
value with no feedback. Surface a warning in the panel editor and on the
rendered panel when a Number panel has more than one enabled query.

Refs #9512
2026-07-23 08:47:25 +00:00
Tushar Vats
cbc8b5424b feat(qb): parse search() in the filter grammar (not yet implemented) (#12129)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Add a search('needle') function to the filter grammar, recognized but not
yet executed - using it returns "search is not yet supported" instead of a
syntax error. Alert links, dashboard variables, and the contradiction check
pass it through untouched. `search` is now reserved, like has/hasAny.
2026-07-22 17:03:30 +00:00
Aditya Singh
7ac6df6fb0 feat(query-builder): fieldContext prefixed key suggestions (#12200)
* feat(query-builder): fieldContext-prefixed key suggestions and type-aware operator filtering

* test(query-builder): extract shared CodeMirror DOM mocks for jsdom specs

* test(query-builder): add CodeMirror+MSW behavior specs for suggestion flows
2026-07-22 13:55:01 +00:00
Swapnil Nakade
8c6a0de8c3 refactor: gcp integration memorystore redis dashboard update (#12229)
Some checks failed
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
2026-07-22 11:42:12 +00:00
Naman Verma
c7abe0fe7b fix: add rank column to tag relations to keep note of tag ordering in dashboards (#12170)
* fix: always sort dashboard tags in alphabetical order

* fix: add rank column to tag relations to keep note of tag ordering in dashboards

* fix: dont disable FK just for adding a new column

* fix: add back tag relation unique index
2026-07-22 11:34:25 +00:00
Abhi kumar
b236273c5f test(e2e): cover alert edit-page threshold persistence (#12227)
* test(e2e): cover alert edit-page threshold persistence

Adds an E2E test that seeds a notification channel + v2 threshold alert
(target 245) via API, opens the alert overview/edit page, and asserts the
condition editor shows the persisted threshold value once loaded.

New helper tests/e2e/helpers/alerts.ts (channel/alert seed + delete +
navigate) mirrors the existing dashboards seeding pattern; the test lives
alongside the existing tabs test in tests/e2e/tests/alerts/alerts.spec.ts.

Verified against a local --with-web stack (passes with the loaded value,
fails when the edit page resets it).

* chore: pr review fixes
2026-07-22 10:13:19 +00:00
Naman Verma
14bb4a8437 fix: remove omitempty/omitzero and explicit empty value handling in dashboard v2 spec (#12197)
* fix: remove omitempty and omitzero where not needed in dashboard v2 spec

* fix: reject explicitly empty enum values if invalid
2026-07-22 09:34:52 +00:00
Swapnil Nakade
842d44d874 feat: adding gcp memorystore redis service (#12118)
* feat: adding gcp memorystore redis service

* refactor: updating dashboard title

* refactor: extending width of uptime gauge panel

* refactor: updating cpu utilization panel

* refactor: updating dashboard panel to use rate function instead of hack
2026-07-22 07:08:26 +00:00
Abhi kumar
0d7aff9ce5 fix(alerts-v2): preserve loaded thresholds on edit-page refresh (#12226)
PR #12137 changed the URL-prefill effect dependency from the primitive
`thresholdsFromURL` string to the memoized `urlPrefill` object, which gets a
fresh reference on every `location.search` change. On the alert overview/edit
page the query builder normalizes the loaded query back into the URL after
mount, so the effect re-ran and its unconditional threshold RESET wiped the
value loaded via SET_INITIAL_STATE (245 -> 0 on refresh).

URL-declared prefill is a create-flow concern; in edit mode the alert state is
owned by SET_INITIAL_STATE. Skip the effect when isEditMode is true.
2026-07-22 06:32:55 +00:00
Naman Verma
fe101a1835 fix: fetch latest monotonicty for metrics instead of any random (#12205)
* fix: fetch latest monotonicty for metrics instead of any random

* test: add integration test for is monotonic flag
2026-07-22 06:01:23 +00:00
Nityananda Gohain
69c2f8d73f feat: span mapper test endpoint (#11795)
* feat: span mapper test endpoint

* feat: integrate with collector

* fix: more cleanup and integration test

* fix: lint

* fix: cleanup go.mod

* fix: update openapi

* fix: more cleanup

* fix: update go.mod

* fix: minor cleanup

* fix: update group_id to groupId

* fix: cleanup integration test

---------

Co-authored-by: Gaurav Tewari <gauravtewari111@gmail.com>
2026-07-22 04:52:13 +00:00
Ashwin Bhatkal
fc6f398828 fix: show the backend error message in the error modal instead of a generic axios error (#12215)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-21 19:29:13 +00:00
Ashwin Bhatkal
8cd2077522 fix(dashboard-v2): validate key:value tags in the editor (inline-edit errors + backend-rule space/char/length checks) (#12062) 2026-07-21 19:27:24 +00:00
Vinicius Lourenço
7b23286aab refactor(infrastructure-monitoring-v2): ui/ux improvements (#12191)
* fix(pods): min width for pod restarts

* fix(disk-usage): not have minimum width correctly

* perf(infra-monitoring-v2): set cache before opening details modal

* feat(tanstack): add custom markers for perf review

* feat(tanstack): add hover tooltip + integrate on infra monitoring

* perf(grouped-status-counts): use tanstack tooltip hover

* fix(k8s-base-list): adding table def to classnames

* perf(grouped-status-counts): reduce node count on DOM

* feat(infrastructure-monitoring): use single component instead of unmount/mount all content

* chore(infrastructure-monitoring-k8s): remove old list components

* fix(hosts): make it double line header

* fix(infrastructure-monitoring): show scrollbar only on hover

* chore(pod-metrics): add docs for charts

* fix(perf-lib): address comments

* fix(infra-monitoring): rename entityConfig to entity.config
2026-07-21 18:51:20 +00:00
Ashwin Bhatkal
6bdf054a05 test(e2e): fix flaky dashboards-detail specs (sidenav overlay + slow hydration) (#12180)
* test(e2e): pin the sidenav so its flyout stops occluding dashboard content

* test(e2e): harden dashboards-detail specs against slow CI hydration
2026-07-21 17:50:44 +00:00
Ashwin Bhatkal
c7f4aa01c4 feat(dashboard-v2): product analytics instrumentation for list + detail pages (#12199)
* feat(dashboard-v2): add analytics event catalog for list + detail

Introduce DashboardListEvents and DashboardDetailEvents enums as the single
source of truth for V2 dashboard product-analytics event names. Grouped
action-discriminator events (RowAction, SectionAction, PanelAction,
DrilldownAction, JsonEditorAction, PublicDashboardAction) mirror the existing
'Dashboard Detail: Panel action' pattern. PanelAction reuses the existing V1
string so panel actions stay comparable across versions.

* feat(dashboard-v2): instrument dashboards list page analytics

Fire logEvent for create/import funnel (tab switch, created success, import
failed), find/navigate (search, filter, sort, columns, pin, pagination),
Views rail (select/save/rename/delete/reset, rail toggle), row actions
(view/open-new-tab/copy-link/rename/edit-tags/duplicate/lock/delete),
legacy-dashboard dialog, and error-state actions.

* feat(dashboard-v2): instrument dashboard detail page analytics

Fire logEvent across the detail page: lifecycle (open, rename, clone, delete,
lock, full-screen, stale-reload, public-url), sections (add/rename/clone/delete,
collapse, reorder, first-section migration), panels (add, edit/clone/delete/move,
export csv/png/svg, view, editor save/discard, type change, search, no-data),
layout drag/resize (rate-limited), variables setup (save/delete/reorder/test/
apply-to-all) and runtime selection (value selected rate-limited, multiselect
clear, options-fetch failed), drill-down (open + view-logs/traces/breakout/
filter/set-variable/create-variable), panel zoom, JSON editor actions, settings
overview save/discard, cursor sync, and public-dashboard actions.

* fix: lint

* refactor(dashboard-v2): extract inline analytics handlers into named functions

Address PR review: pull the inline JSX arrow handlers that wrap logEvent out
into named handlers across both V2 dashboard pages (public-url open, cursor/
tooltip sync, settings/JSON/full-screen actions, panel search, drilldown
view-logs/traces, create-modal tab, error retry/contact-support, row open-in-
new-tab/copy-link, legacy contact-support, save-view actions). Behavior
unchanged. Handlers defined inside .map()/per-row renderers and pre-existing
complex value-mapping handlers (ValueSelector) are intentionally left inline.
2026-07-21 14:13:26 +00:00
Vinicius Lourenço
e93792d427 fix(overlayscrollbars): leaking memory due to img.load event listener (#12179)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-21 12:07:55 +00:00
Vinicius Lourenço
6d0f618a9e feat(infra-monitoring): persist custom time on drawer across categories (#12038)
* feat(globalTime): add method to reset time of child to parent

* refactor(infra-monitoring): extract content from K8sBaseDetails

* feat(entity-details): add support to persist custom time across categories of k8s

* test(entity-details): update existing tests

* test(entity-details): add regression test for time conversion

* fix(k8s-list): ensure default value for list is 30m

* fix(entity-counts-section): address todo around inherit selected time

* fix(pr): missing fix for tab validation, lost of moving/merge
2026-07-21 11:58:26 +00:00
Ashwin Bhatkal
564d479aae test(e2e): fix teardown crashes (network endpoint race + eager keeper lookup) (#12204)
* test(e2e): retry network teardown to survive async endpoint detach

`--teardown` fails on CI with `docker.errors.APIError: 403 ... error while
removing network ... has active endpoints`: containers are torn down before
the network, but Docker detaches endpoints asynchronously, so the network
can still report active endpoints for a moment. Retry the removal,
force-disconnecting any stragglers each round.

* test(e2e): resolve keeper coordinator lazily so --teardown doesn't crash

`create_clickhouse` / `create_clickhouse_cluster` computed
`next(iter(keeper.container_configs.values()))` eagerly. Under `--teardown`
the keeper fixture is empty, so it raised StopIteration during teardown
setup, before any finalizer ran. Move the lookup inside create().
2026-07-21 11:44:30 +00:00
Vikrant Gupta
253ca7dd7e fix(session): validate ref and callback state against global allowed_origins (#12172)
* fix(session): use global external_url instead of ref param for SSO state

The sessions/context endpoint no longer reads the client-controlled ref
query param to build the SSO state and callback URLs. Each callback
authn provider now derives the site URL from the server-configured
global external_url, and siteURL is removed from the CallbackAuthN and
session Module interfaces.

* fix(session): validate ref and callback state against global allowed_origins

Instead of deriving SSO urls from the global external_url, keep the ref
roundtrip and validate its origin against the new optional
global.allowed_origins config. The callback state url is re-validated
before tokens are attached to it, closing the forged RelayState/state
exfiltration path. When allowed_origins is not configured, redirect
targets are not validated, preserving existing installs.

* fix(session): scope ref origin validation to sso auth domains

Move the allowed_origins check from the sessions/context handler to
getOrgSessionContext, right before the SSO login URL is built. A
disallowed ref no longer fails the whole request; only orgs with an
SSO-enabled auth domain get a per-org warning with password fallback.
2026-07-21 10:28:49 +00:00
Ashwin Bhatkal
cc45c1bef1 feat(dashboard-v2): share a dashboard link with the current variable selection (#12198)
* feat(share): support a page-specific extra option in the share dialog

* feat(dashboard-v2): share a dashboard link with the current variable selection
2026-07-21 07:08:20 +00:00
Abhi kumar
e70b3a0b52 chore: pr review fixes for 12137 (#12142) 2026-07-21 06:43:10 +00:00
Abhi kumar
f514af469e fix(dashboards-v2): panel editor Save/dirty, refresh retention, dropdown clipping & time-window fixes (#12146)
* fix(dashboards-v2): carry active time window across panel editor navigation

Opening, creating, or leaving the V2 panel editor now preserves the selected time
range (relative or custom) via URL params derived from Redux global time, so a
custom range picked in the editor isn't reset to the dashboard default on return.

Adds timeParamsFromGlobalTime + useTimeSearchParams; useOpenPanelEditor now takes an
options object ({ handoffState, search }) and appends the time params, and
useCreatePanel routes through it.

* fix(dashboards-v2): sync panel editor preview to the staged query on browser back/forward

The query builder reverts both currentQuery and stagedQuery via initQueryBuilderData on a
URL re-stage (chiefly browser Back/Forward), but the preview kept the last Run's result.
Commit the staged query into the draft whenever it re-stages outside an explicit Run, so the
preview follows. Live edits touch only currentQuery, so they still wait for Run; commitQuery
no-ops when unchanged.

* fix(dashboards-v2): stop query-builder dropdowns being clipped in the panel editor

The panel editor renders the query builder inside an overflow:hidden resizable pane, so
antd Select popups (group-by, order-by, having, metric name, aggregator, units) were cut
off. Make the shared QB filters defer to an ancestor ConfigProvider's popup container
(falling back to trigger.parentNode) via useSelectPopupContainer, and wrap the editor's
builder in a ConfigProvider that portals popups to document.body. Scoped to the editor
host, so the View modal keeps its own container and other surfaces are unchanged.

* fix(dashboards-v2): anchor panel editor dirty check to saved panel; retain query edits on refresh

The editor re-derived its dirty baseline from the incoming panel prop, which
is seeded from transient state — a stale URL compositeQuery after a refresh or
the View-mode handoff spec — instead of the persisted panel. So the draft was
compared against an already-edited baseline: after a refresh the panel showed
the saved query yet read dirty (inverted), and a View->Edit query change read
clean with Save disabled.

- Thread a savedPanel baseline (existingPanel) through PanelEditorPage ->
  PanelEditorContainer -> usePanelEditSession, distinct from the seed panel.
- usePanelEditorDraft compares isSpecDirty against savedPanel; the draft still
  seeds from the (possibly handed-off) panel.
- usePanelEditorQuerySync computes isQueryDirty as a V5-envelope comparison of
  the live query against the saved queries, routing both sides through the same
  fromPerses->toPerses round-trip so builder-added defaults absent from an older
  stored query never read an untouched panel as modified. Replaces the racy
  captured-first-stagedQuery baseline.
- Drop the mount forceReset on useShareBuilderUrl (both its reasons are now
  moot) so a refresh / browser Back-Forward hydrates the edited query from the
  URL and the staged-query effect syncs it into the draft — query edits survive
  a refresh instead of reverting to the saved query.

Add real-QueryBuilderProvider integration tests covering untouched-not-dirty
(incl. an older/minimal stored query), refresh retention, and handoff-dirty;
update the draft + query-sync unit tests.
2026-07-21 06:40:43 +00:00
Vikrant Gupta
806853798d feat(authz): add support for telemetry resource provisioning (#12168)
* feat(authz): provision telemetry roles with plaintext selectors and hashed tuples

Accept a user-facing telemetry selector string (<query_type>/<key>/<value>
with trailing wildcards), validate and canonicalize it, store it as-is in the
role JSON record, and hash it only at the OpenFGA boundary in Object(). Grant
and check both flow through Object() so the hashes match; the plaintext record
stays the readable source of truth for display and recreation.

Because the hash is one-way, role Update diffs at the tuple level via
DiffTuples instead of reconstructing transaction groups from stored tuples.

* refactor(authz): rename telemetry selector helpers and unexport hash

Rename grant_selector.go to selector.go, CanonicalizeTelemetryGrantSelector to
NewTelemetryGrantSelector, and CanonicalTelemetryGrantKey to NewTelemetryGrantKey.
Unexport telemetrySelectorHash since Object() is its only caller.

* fix(authz): expand telemetry ladder in the permission check API

The check API only probed the exact selector plus the full wildcard, so a
scoped grant like builder_query/service.name/* reported a concrete query as
unauthorized even though enforcement allowed it. Relocate the grant selector
ladder to telemetrytypes as NewTelemetryGrantSelectors so both enforcement and
the check API share it, and canonicalize plus fan out the ladder for telemetry
check transactions. Non-telemetry resources keep the exact-plus-wildcard probe.

* refactor(authz): move newCheckSelectors to the bottom of tuple.go

* fix(authz): reject key-scoped selectors for promql and clickhouse_sql

Only builder_query and builder_sub_query extract key-scoped selectors on the
check side, so a grant like clickhouse_sql/service.name/signoz could never
match anything. Track key-scope support per query type and reject the
<query_type>/<key>/<value> form for query types that only emit <query_type>/*.

* test(authz): use a valid promql selector in the check API test

The promql/service.name/service-a case became invalid input after key-scoped
promql/clickhouse_sql selectors were rejected, so the check endpoint returned
400 instead of 200. Use promql/* to keep exercising the different-query-type
denial with a valid selector.

* feat(authz): allow signoz.workspace.key.id as a telemetry grant key

Add signoz.workspace.key.id to the telemetry grant key allowlist so roles can
scope telemetry access by ingestion key, alongside service.name. Grant
validation and check-side extraction both pick it up through the shared
NewTelemetryGrantKey path; bare and resource.-prefixed spellings fold to the
same canonical key.

* Revert "feat(authz): allow signoz.workspace.key.id as a telemetry grant key"

This reverts commit c50d122b54.

* feat(authz): scope telemetry grants by signoz.workspace.key.id

Make signoz.workspace.key.id the sole telemetry grant key instead of
service.name, so roles scope telemetry access by ingestion key. The allowlist
is the only production change; grant validation and check-side extraction are
name-agnostic. Update the querierauthz integration suite and unit tests to the
new key.

* test(authz): update query_range_resources extractor tests to signoz.workspace.key.id

The grant-key switch left this extractor test filtering on and expecting
builder_query/service.name/... IDs, which now fall back to builder_query/*.
Rename the filters and expectations to signoz.workspace.key.id.
2026-07-21 06:13:13 +00:00
Jugal Kishore
f002b29685 fix(onboarding): list Temporal Cloud Metrics under metrics, not APM/Traces (#12203)
Temporal Cloud Metrics scrapes an OpenMetrics endpoint but only showed
under APM/Traces, bundled with the Go and TypeScript SDKs. Split it into
a standalone metrics card and trimmed the Temporal APM card to Go and
TypeScript.

Closes SigNoz/growth-pod#1122
2026-07-21 06:08:36 +00:00
Vinicius Lourenço
a5d4ef4498 fix(uplot): missing destroy uplot on unmount (#12182)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
2026-07-21 03:02:32 +00:00
Tushar Vats
967289ebc6 fix(metrics): resolve any filter key context instead of erroring (#12188)
* fix(metrics): resolve any filter key context instead of erroring

The metrics condition builder hard-errored ("key <name> not found") whenever a
filter key was absent from the metadata keys. This hit the full-text search
column (metric_name in the Metrics Explorer, labels in query_range) and every
explicit label context (resource./scope./attribute.), so a bare/partial filter
token 400'd the Metrics Explorer treemap and metric queries.

Metrics keeps every label in the `labels` JSON with no per-context storage, so
FieldFor already maps any key on its own (intrinsics incl. metric_name to their
column, every label context to a labels JSON extract). Use the key directly in
the len(keys)==0 branch so filters resolve and run instead of 400ing - matching
group-by, which already collapses all label contexts to labels.

Update the label-context test to expect the collapse (resource./scope. now
resolve like bare/attribute.), add unit coverage for the branch, and add a
queriermetrics test that a free-text filter no longer errors.

* fix(metrics): resolve free-text and unregistered filter keys instead of erroring

The metrics condition builder hard-errored ("key <name> not found") whenever a
filter key was absent from the metadata keys: the full-text search column
(metric_name on the Metrics Explorer, labels on query_range) and every explicit
label context (resource./scope.). So a bare/partial filter token 400'd the
Metrics Explorer treemap and metric query-builder filters.

Metrics has no per-context storage - every label lives in the `labels` JSON, and
FieldFor maps any key on its own (intrinsics incl. metric_name to their column,
every label context to a labels extract). Add an opt-in WithIgnoreNotFoundKeys
to the metrics condition builder that resolves such keys directly (matching
nothing) instead of erroring:

- query-builder (querier provider) and Metrics Explorer opt in, so free-text and
  unregistered contexts resolve - matching the statement builder's own fallback
  and group-by, which already collapses all label contexts to labels;
- infra-monitoring list APIs keep the default (strict), so a typo'd attribute
  still surfaces as a 400.

Intrinsics always resolve regardless of the flag. Adds unit coverage for both
modes and a queriermetrics test that a free-text filter no longer errors; the
label-context test now expects the collapse.

* chore: updated integration tests

* fix: dont assert warning == []

* chore: removed warning scaffolding for now

* fix: add back removed integration test

---------

Co-authored-by: nikhilmantri0902 <nikhil.mantri1999@gmail.com>
2026-07-21 01:48:54 +00:00
Srikanth Chekuri
bf0130a983 fix(clickhouseprometheus): resolve __name__ matchers against metric_name and anchor matcher regexes (#12154)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
The read client reduced every __name__ matcher to metric_name = <value>
(empty string when absent), so nameless selectors ({job="api"}), regex
names ({__name__=~".+"}), and negations silently returned empty. Map the
__name__ matcher onto the metric_name column per matcher type, drop the
condition when no __name__ matcher exists, and narrow the samples query
by the metric names the series lookup discovered.

Matcher regexes are now anchored (^(?:...)$) the way Prometheus compiles
them; ClickHouse match() is a substring search, so {job=~"api"} also
matched job="api-server" before.

The lookup and samples SQL is built with huandu/go-sqlbuilder (ClickHouse
flavor) as in telemetrymetrics and the v2 transpiler: the samples query
embeds the series lookup as a nested builder, with argument order merged
by the builder in render position instead of hand-numbered placeholders.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 18:59:34 +00:00
Tushar Vats
9d4349c9d1 fix(querybuilder): resolve data-type collisions for numeric intrinsic columns (#12176)
A span/log query that aggregates or filters a numeric intrinsic column
(e.g. duration_nano) failed with ClickHouse NO_COMMON_TYPE (386) when a
same-named, type-consistent attribute existed in the metadata: field-key
resolution unioned the intrinsic column with the attribute into a multiIf/OR
whose branches had incompatible types (UInt64 intrinsic vs Float64 attribute).
This broke /api/v1/span_percentile on affected tenants.

- fallback_expr: DataTypeCollisionHandledFieldName now handles the unspecified
  data type in the projection/aggregation path (operator Unknown), coercing the
  column so collision multiIf branches share a supertype. Comparison contexts
  are left bare so the column index stays usable.
- telemetrytraces/condition_builder: run collision handling for duration_nano
  (so a same-named string attribute is cast in comparisons) and coerce numeric
  duration values to int64, keeping the intrinsic comparison bare/index-friendly
  while preserving the duration-string QoL parsing.
- tests: add a type-consistent "collision" trace_noise variant; cover it in the
  percentile aggregation test and add a duration_nano QoL filter regression test.
2026-07-20 16:57:39 +00:00
Pandey
d095645d61 fix(querybuildertypesv5): round-trip unset stepInterval and empty field-key values (#12171)
* fix(querybuildertypesv5): omit unset stepInterval on the wire

Step is a struct (struct{ time.Duration }), so omitempty had no effect — an
unset stepInterval serialized as 0 instead of being omitted, so a typed
client reading a query back saw a 0 it never sent (create -> GET drift).

Tag stepInterval with ,omitzero so an unset value is dropped while a set
value still serializes (as seconds), on all three sites: builder query,
trace-operator, and secondary aggregation. Schema-invisible (no OpenAPI /
client change). source and the metric enums were already handled in #12164.

* fix(telemetrytypes): round-trip empty fieldContext/fieldDataType on field keys

A TelemetryFieldKey can deliberately leave fieldContext/fieldDataType empty
to match across any context / data type, but ,omitzero dropped that empty
value on serialize, so a typed client that sent "" read it back as absent
(create -> GET drift).

Make both fields always serialize and add the empty member to their Enum()s
so "" is a valid schema value that round-trips verbatim — the same approach
#12164 used for source. Signal keeps ,omitzero: its empty value is invalid
for the query/variable signal contexts that share the enum (adding "" there
breaks those consumers), and a field key's signal is not deliberately empty.

Regenerate the OpenAPI spec + client (fieldContext/fieldDataType enums gain
"") and update the ScalarData marshal test (column keys now echo the fields).

* fix(telemetrytypes): round-trip empty signal on field keys

Extend the field-key round-trip fix to Signal: add the empty member to
Signal.Enum() and make TelemetryFieldKey.Signal always serialize, so an
empty ("any") field-key signal round-trips as a valid value instead of
being dropped — matching the fieldContext/fieldDataType treatment.

The Signal enum is shared with query/variable signals, where "" is invalid.
Narrow the frontend's TelemetrySignal type to logs/traces/metrics (so the
variable/panel signal selectors stay exhaustive), label the empty member in
the panel type switcher's map, and fold an empty drilldown signal into "all".

Regenerate the OpenAPI spec + client (Signal enum gains ""), and update the
ScalarData marshal test and the querierlogs aggregation label assertions to
include the now-serialized empty signal.
2026-07-20 16:31:47 +00:00
Vinicius Lourenço
429fca62be fix(query-search): do not override token classes (#12139)
* fix(query-search): do not override token classes

* test(token-highlight): add regression test

* fix(pr): address comments
2026-07-20 13:07:07 +00:00
Aditya Singh
20518a98e9 fix(logs-explorer): prevent long json body from overflowing (#12173)
* feat: allow body content to wrap preventing content overflow

* feat: align key name and pin to the top
2026-07-20 13:03:28 +00:00
Gaurav Tewari
0b7c266b09 fix: css fixes for llm o11y model pricing and overview (#12145)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix: css fixes for llm o11y model pricing and overview

* fix: spacing issue

* chore: update modal drawer cost

* chore: remove comments

* chore: spacing between chips right

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-20 11:19:48 +00:00
Gaurav Tewari
8014c065e8 feat: rename llm o11y to ai o11y [2/2] (#12141)
* feat: add llm o11y to side nav

* chore: rename route

* chore: review comments

* chore: update constants

* chore: change name to ai

* chore: rename draft

* chore: move model pricing out of settings

* chore: update comment

* revert: undo LLM->AI file/dir moves, keep constant rename

Reverts the two file-relocation commits (c25060950 rename LLMObservability
dir -> AIObservability; 1a18bc848 move ModelPricing out of Settings) while
preserving the LLM->AI string/constant renames (route constants + paths,
side-nav entry/labels, page titles, permission keys). Component files stay
under container/LLMObservability with their original names.

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-20 11:18:08 +00:00
Gaurav Tewari
c2c2552cc6 feat: add llm observability to side navigation [1/3] (#12123)
* feat: add llm o11y to side nav

* chore: update comment

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-20 08:00:39 +00:00
Pandey
88bd737758 fix(dashboards-v2): round-trip all zero-valued spec fields (#12162)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(dashboardtypes): round-trip zero-valued variable/display fields

omitempty dropped explicit zero values from the create -> GET response, so
a typed client (Terraform/SDK) that sent them read back null and reported
drift. Remove the tag so these always serialize:

- Display.Description ("" round-trips; applies to dashboard/panel/variable
  displays)
- TextVariableSpec.Constant (constant: false, like the disabled fix)
- ListVariableSpec.CustomAllValue / CapturingRegexp ("" round-trips)

Scalars carry no nullability, so the OpenAPI spec and generated client are
unchanged. Sort stays omitzero: its "no sort" value is "none", not "", so
omitzero only omits the invalid unset state.

* fix(dashboardtypes): round-trip panel and dashboard links

`links` used omitempty (dropped an explicit []) and its element type was the
imported perses dashboard.Link, whose own fields tag name/tooltip/
renderVariables/targetBlank omitempty — so a link's false/"" were dropped
too, and a typed client read them back as null.

- Replicate dashboard.Link as a SigNoz Link type (same pattern as
  ListVariableSpec/TextVariableSpec) with every field always serialized.
- Use ,omitzero on PanelSpec.Links and DashboardSpec.Links so an explicit
  [] round-trips while an unset list stays omitted (never null).

Regenerate the OpenAPI spec and frontend client: the element schema is now
DashboardtypesLink (was the perses DashboardLink) and links is nullable.
Update the frontend consumers to the renamed type and coalesce the now
type-nullable spec.links (never null on the wire) at its two boundaries.

* test(dashboard): cover variable/display/link round-trip cases

Extend the v2 dashboard round-trip test with the spec-wide zero values this
PR fixes: a display description "", a text variable's constant false, a list
variable's customAllValue/capturingRegexp "", an explicit [] of panel links
that round-trips, a link whose own zero-valued fields (name/tooltip "",
renderVariables/targetBlank false) echo back, and a linkless panel whose
links stay omitted (never null).

* test(dashboard): accept null-or-absent for unset panel links

A panel with no links round-trips as "links": null rather than being
omitted (the panel serialization path differs from the query slices, which
omit). Both mean "no links" and neither drifts for a typed client, so assert
the value is None (null or absent) instead of strictly absent. The explicit
[] case still asserts a verbatim round-trip, which is the guarantee the fix
provides.

* fix(dashboardtypes): round-trip remaining zero-valued spec fields

Complete the dashboards-v2 create -> GET round-trip audit:

- DashboardSpec.Datasources: ,omitempty -> ,omitzero so an explicit {}
  round-trips (omitempty dropped it) while an unset map stays omitted.
- DashboardV2 Image, DashboardSpec.Duration/RefreshInterval: drop ,omitempty
  so an explicit "" round-trips (same class as Display.Description). The
  server accepts "": DurationString.validate() returns nil for len 0, and
  Image/Duration/RefreshInterval have no create-time validation, so a
  GET-then-PUT of "" is not rejected.

Scalars carry no nullability (no spec change); the datasources map is now
nullable: true in the regenerated OpenAPI spec and client.

* test(dashboard): cover datasources/image/duration/refreshInterval round-trip

Extend the round-trip test with the spec-wide zero values just fixed: a
dashboard-level image "", spec duration/refreshInterval "", and an explicit
empty datasources {} that must echo back as {} (omitzero) rather than being
dropped.
2026-07-19 20:42:27 +00:00
Pandey
8c40d8c2ca fix(querybuildertypesv5): allow empty source, temporality and timeAggregation in the metric query spec (#12164)
* fix(querybuildertypesv5): omit unset metric enum fields on the wire

A metric builder query serialized empty strings for its enum fields
because omitempty has no effect on struct-backed valuer types:

  "source":"", "aggregations":[{"temporality":"","timeAggregation":"","spaceAggregation":""}]

Those "" values are not members of the corresponding OpenAPI enums
(source=[meter], temporality=[delta,cumulative,unspecified], etc.), so a
typed client reading a rule back rejected it (create -> GET round-trip
drift; terraform-provider-signoz generate-config failed schema validation).

Tag Source/Temporality/TimeAggregation/SpaceAggregation with ,omitzero so
an unset value is dropped instead of emitted as an invalid "", matching the
existing convention (dashboardtypes Sort, telemetrytypes field keys). Valid
values still serialize. The OpenAPI spec regenerates byte-identical, which
confirms the enums were already correct.

* test(querybuildertypesv5): cover client-sent empty enum values

A client (e.g. terraform) may send explicit source:"" / temporality:"" for
an unset enum. Assert unmarshaling accepts them, normalizes to the zero
value, and re-marshaling drops them so the round-trip never echoes an
invalid "" back.

* fix(querybuildertypesv5): allow empty metric enum values in the spec

The server accepts and echoes back an unset source, temporality, and
timeAggregation for a metric query (a create -> GET returns "" for them), but
their OpenAPI enums omitted "". A typed client (terraform-provider-signoz
generate-config) therefore rejected the config generated for an imported rule.

Add "" as a valid member of the Source, Temporality, and TimeAggregation enums
so the spec matches what the server actually accepts and returns. spaceAggregation
is left unchanged: an empty value is rejected with 400 at creation (IsValid), so
it is never stored or echoed and "" must stay out of its enum.

Drop the earlier ,omitzero tags: these fields already always-serialize, so an
accepted "" round-trips faithfully instead of being silently dropped (silent
mutation is itself drift). source loses its no-op omitempty for the same reason.

Regenerate the OpenAPI spec and frontend client (both git-diff gated).

* test(querybuildertypesv5): assert accepted empty enums round-trip

Empty source/temporality/timeAggregation are echoed back (not dropped) and are
stable across marshal -> unmarshal -> marshal; spaceAggregation carries a valid
value since an empty one is 400'd at creation.

* test(querybuildertypesv5): merge and rename metric enum round-trip test

Fold the unmarshal-echo case into the table-driven marshal round-trip test
(its marshal -> unmarshal -> marshal check already covers the client-sends-""
path) and rename to TestQueryBuilderQuery_MetricAggregation_MarshalJSONEnumRoundTrip.

* style(metrictypes): drop explanatory comments on enum changes

Remove the comments added to Temporality/TimeAggregation Enum() and the metric
enum round-trip test case.

* style(telemetrytypes): drop explanatory comment on Source enum change

Remove the comment added to Source.Enum(), keeping the pre-existing doc/TODO.
2026-07-19 19:52:51 +00:00
Srikanth Chekuri
7be340ce69 fix(clickhouseprometheus): include hour-floored registration rows at the query window end (#12153)
Some checks failed
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
The series lookup bounded registration rows with unix_milli < end while
the samples query uses <= end. The exporter writes registration rows
hour-floored, so a series first registered in the hour starting exactly
at end was invisible even though its samples were fetchable — queries
ending exactly on an hour boundary missed newly-registered series.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 19:27:13 +00:00
Tushar Vats
852ca779c9 fix: convert key not found to warnings for logs (#12134)
* fix: convert key not found to warnings

* fix(logs): has-family body-only errors, not-found warnings, and condition-builder cleanup

- has/hasAny/hasAll/hasToken on a non-body key now return "supports only body
  JSON search" (both modes); a not-found body path warns and queries the
  underlying data instead of 400 (JSON mode)
- capture the two has-family 500s (hasToken separator/whitespace needle;
  hasAny/hasAll quoted int >= 2^32) as regression tests
- use telemetrytypes.NewTelemetryFieldKey for derived keys (fresh identity-only
  keys, no stale resolved metadata) instead of struct copies of the field key
- rename ConditionForKeys -> ConditionFor and inline conditionsForKeys into it
  across the builders; rename private conditionFor -> conditionForResolvedKey
- move the trace_noise fixture from queriertraces/conftest.py to fixtures/traces.py

* fix: convert trace_noise fixture to util
2026-07-19 18:41:53 +00:00
Srikanth Chekuri
05b35dd4ee fix(clickhouseprometheus): merge fingerprints sharing a labelset instead of injecting a fingerprint label (#12152)
#8563 worked around duplicate-labelset collisions (a label value going
empty re-fingerprints a series; empty-valued labels are dropped at read)
by appending a synthetic fingerprint label to every series and stripping
it from results. The label participates in evaluation before any strip
runs: without() grouped per fingerprint (duplicate identical-labeled
output series) and unaggregated vector matching never matched.

Resolve series identity at the adapter instead: drop empty-valued labels
at unmarshal, merge fingerprints that share the resulting labelset
(timestamp-ordered k-way merge, highest fingerprint wins equal
timestamps), and delete the injection and every RemoveExtraLabels strip.
Engine-semantic duplicates (e.g. rate over {__name__=~"a|b"}) still
error, matching upstream Prometheus.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 17:43:47 +00:00
Srikanth Chekuri
bcea24f449 fix(querybuildertypesv5): keep subnormal values finite in roundToNonZeroDecimals (#12157)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
The sub-1 branch's scale (10^(-order+n-1)) overflows to +Inf for
subnormal inputs (order below ~-308), and Inf/Inf turned a finite stored
value into NaN — which then serializes as the string "NaN". Same guard
as the >=1 branch got in #12151; adds the unit coverage for both.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 09:49:08 +00:00
Pandey
22e55340d7 fix(dashboards-v2): round-trip zero-valued threshold + query fields (#12158)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(dashboardtypes): accept threshold value of 0 on create

A NumberPanel/TimeSeries/Table threshold with `value: 0` (a legitimate
value the SigNoz UI emits by default) was rejected on create with
`dashboard_invalid_input` "Field validation for 'Value' failed on the
'required' tag".

go-playground/validator's `required` treats a numeric field equal to its
zero value as "missing", so `validate:"required"` on the float `Value`
wrongly rejected 0. Drop `validate:"required"` from `Value` on
ThresholdWithLabel and ComparisonThreshold; keep `required:"true"` since
the field is always present in the schema (0 is a valid present value, not
an absent one), so the OpenAPI/generated client are unaffected. `Color`
keeps both tags — an empty colour is genuinely invalid.

Drop the two "missing value" cases from TestValidateRequiredFields, which
asserted the removed invariant.

* fix(querybuildertypesv5): round-trip zero-valued query spec fields

A dashboard/alert query that sets a zero-valued field — `disabled: false`,
`legend: ""`, or an explicit empty `groupBy`/`order`/`selectFields`/etc. —
created fine but the GET response omitted it, so a typed client that echoes
what it sent (Terraform, SDKs, PUT-after-GET) read back `null`/absent and
reported drift. `,omitempty` dropped these zero values on the way out.

Fix the create -> GET asymmetry:

- Slice fields use `,omitzero` instead of `,omitempty`. `omitzero` omits a
  nil slice (field never set stays absent) but keeps an explicit non-nil
  `[]`, so an empty array round-trips as `[]` and there is no `null`
  regression. Applied to groupBy, order, selectFields, aggregations,
  functions, secondaryAggregations and function args across the builder,
  formula, trace-operator and join specs, plus ListPanelSpec.selectFields.
- Scalars `disabled` (bool) and `legend` (string) drop the tag entirely;
  `omitzero`/`omitempty` both suppress false/"", so the only way to
  round-trip them is to always serialize.

Result types in resp.go keep `,omitempty` — they are server-computed and
never round-tripped. Regenerate docs/api/openapi.yml and the frontend
client: the omitzero slices are now `nullable: true` in the schema (never
null on the wire, but the generated types gain `| null`, which existing
consumers already handle via `?? []`).

* test(dashboard): round-trip serialization for zero-valued fields

Add a v2 dashboards integration test that creates one minimal dashboard
(stripped from SigNoz/dashboards cicd-perses.json) and asserts the
create -> GET round-trip preserves every zero-valued field the fix targets:

- threshold value 0 (ComparisonThreshold + ThresholdWithLabel) is accepted
  on create and echoed back
- builder slices set to an explicit [] (groupBy/order/selectFields/functions)
  round-trip as [], while a bare builder's unset slices stay absent (never
  null) on read
- scalars disabled/legend always echo false/""

Table-driven: one equality table for round-tripped values and one absence
table for omitted slices.

* test(dashboard): fold round-trip test into 03_v2_dashboard

Move test_dashboard_v2_roundtrip_preserves_zero_values alongside the other
v2 dashboard tests (test_create_rejects_*, lifecycle, ...) instead of a
standalone file, with the dashboard payload inlined per this suite's style.
2026-07-18 19:52:54 +00:00
Tushar Vats
dd8cbe0844 fix: has function family revamp (#12089)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-18 16:43:26 +00:00
Srikanth Chekuri
6b065aa54c fix(querybuildertypesv5): guard float overflow in roundToNonZeroDecimals (#12151)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
math.Round(val*multiplier)/multiplier overflows to +Inf for finite values
near math.MaxFloat64, turning a valid series value into JSON-unmarshalable
Inf downstream. Return the value unrounded when the scaled intermediate
overflows.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 08:48:33 +00:00
Vikrant Gupta
ac5b5947eb feat(authz): enable FGA for telemetry resources (#12095)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(authz): enable FGA for telemetry resources on v5 query_range

Authorize /api/v5/query_range and /preview at the telemetry-resource level,
derived from the request body:

- coretypes: ResourceWithID + ResourceExtractor as the resource-level analogue
  of the id extractors; NewResolvedResourceWithID/NewResolvedResourceWithError;
  telemetryresource selector regex widened to query-type selectors with up to
  two hashed segments (metric name, where clause) or wildcards
- telemetrytypes: QueryRangeResources maps each query to its telemetry
  resource (signal/source aware: audit-logs, meter-metrics) with a hierarchical
  selector id (query_type/<hash(metric)>/<hash(where)>); PrefixSelector expands
  the id into the grant ladder [exact, prefix/*..., *]
- handler: generic TelemetryResourceDef fans out an injected ResourceExtractor;
  fails closed when extraction errors or resolves nothing
- audit: log and skip resolved resources that carry a resolution error
- querier routes: ViewAccess -> CheckResources with telemetry read scopes;
  substitute_vars stays ViewAccess (no telemetry access)
- sqlmigration 099: backfill telemetry read tuples for existing orgs
  (admin: logs/traces/metrics/audit-logs/meter-metrics; editor/viewer:
  logs/traces/metrics)

* feat(authz): widen telemetry selector segments to 128 bits

64-bit truncation permits chosen-collision attacks at ~2^32 work; 128 bits
pushes this to 2^64. No hashed selector is persisted yet, so the change is
free.

* chore(docs): regenerate openapi spec with telemetry read scopes

* feat(telemetry): add where clause visitor

* refactor(telemetry): restructure normalizer file and quote bare values

* feat(authz): gate v5 query_range on service.name telemetry selectors

* feat(authz): encode telemetry grants as query-type qualified atom selectors

* feat(authz): move telemetry grant key to plaintext selector segment

* feat(authz): use escaped plaintext telemetry selectors with mechanical ladder

* revert(authz): restore transaction group diff in role update

* test(authz): add querierauthz integration suite for telemetry query_range gating

* test(authz): seed logs so service.name resolves in allowed querierauthz cases

* feat(authz): backfill telemetry read tuples for existing orgs

* chore(authz): reword empty composite query error message

* feat(authz): add meter metrics and audit logs to clickhouse sql

* Revert "feat(authz): add meter metrics and audit logs to clickhouse sql"

This reverts commit c9d870e0ee.

* feat(authz): grant meter-metrics to editor/viewer, keep clickhouse admin-only

* feat(authz): remove the audit logs from clickhouse check altogether until it's introduced
2026-07-17 10:59:58 +00:00
Vinicius Lourenço
c563d79ee0 feat(quick-filters): add support for /v1/fields/values (#11788)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(quick-filters): add field values hook

* feat(quick-filters): add support to handle indeterminate state of checkbox

* feat(quick-filters): add checkbox header v2

* feat(quick-filters): add item rules to represent the states of checkbox

* feat(quick-filters): add checkbox row v2

* feat(quick-filters): add sectioned values hook to correctly calculate checkboxes to render

* feat(quick-filters): add hook to get existingQuery for field values

* feat(quick-filters): add checkbox filter v2

* test(quick-filters): add tests for checkbox filter v2

* feat(quick-filters): add flag to enable v2

* feat(infra-monitoring): enable quick filters v2

* fix(infra-monitoring): change the prefix of metric namespaces

* fix(checkbox-v2): update to improve ux

* fix(quick-filters): move from flat list to sections

* fix(quick-filters): render related/all values when searching

* Revert "fix(infra-monitoring): change the prefix of metric namespaces"

This reverts commit 176dc6d3bc.

* Revert "feat(infra-monitoring): enable quick filters v2"

This reverts commit 8902a157c1.

* fix(pr): address comments

* feat(infra-monitoring-v2): enable use new quick filters

* fix(pr): cleanup old file

* fix(quick-filters): avoid flick of old selected value on related value
2026-07-17 07:38:33 +00:00
Aditya Singh
b9b92f951b feat: table export in Logs and Traces explorer table tabs (4) (#12071)
* refactor(data-export): extract the withUnit header helper

Both the timeseries and the upcoming table serializers append units to headers (and skip display-only ids like 'short'/'none') — move the helper to its own module.

* feat(data-export): add generic table-model serializer

exportTableData serializes any prepared antd-style table model ({name, key, isValueColumn} columns + record rows) into a SerializedTable — raw values in display order, units on value columns only, blanks for missing cells. Surface-agnostic: QueryTable-based tables, dashboard tables and plain antd tables all adapt in a line or two.

* feat(data-export): add scalar queryRange serializer

exportScalarData takes the queryRange response object (formatForWeb webTables payload) + the builder query and serializes via createTableColumnsFromQuery — the exact preparer QueryTable renders from — so exports inherit the on-screen merge, naming and column order 1:1.

* feat(data-export): dispatch client exports from the queryRange response

useClientExport now takes the queryRange response object views already hold and picks the serializer from what it carries: rawV5Response (time_series) or the formatForWeb scalar payload (tables) — mounts pass their data without choosing serializers. TimeseriesExportMenu generalizes into components/ExportMenu with the same uniform inputs, so the timeseries views and the table tabs share one menu.

* feat(explorer): enable table export in Logs and Traces table tabs

Mounts ExportMenu on the Logs and Traces Table tabs, feeding the same query the rendered table uses (stagedQuery fallback parity) — exports match the on-screen table's merge, naming and column order. Header rows are class-driven, right-aligned, gated on data presence.

* test(data-export): assert scalar export filename via the naming helper

Same review cleanup as the foundation PR: frozen clock + delegation to getTimestampedFileName instead of a duplicated format regex.
2026-07-17 06:16:53 +00:00
Abhi kumar
6bcc2d66d9 feat(dashboards-v2): pre-populate alert condition from panel Reduce To + thresholds (#5291) (#12137)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* refactor(alerts-v2): extract alert condition normalizers to a leaf module

normalizeOperator/normalizeMatchType move from CreateAlertV2/utils.tsx into a
dependency-free context/conditionNormalizers.ts (re-exported from utils for existing
callers), so the CreateAlert context can consume them without an index<->utils cycle.

* feat(alerts-v2): apply alert-condition prefill declaratively from the URL

The CreateAlertV2 context now resolves a declarative prefill from the URL
(resolveUrlAlertPrefill) and applies each field iff present, instead of branching on
the request source. Producers own their semantics: ingestion settings now explicitly
declares matchType=in_total + evaluationWindowPreset=meter, so adding a new producer
needs no consumer change.

* feat(dashboards-v2): pre-populate alert condition from panel Reduce To + thresholds (#5291)

Creating an alert from a V2 panel now seeds the condition: Reduce To -> occurrence
type (sum->in total, avg->on average; Value panel only), and the highest-danger
threshold (Red>Orange>Green>Blue) -> operator, target value, and unit. Formula panels
apply the reduce only when all queries agree. The seed rides the /alerts/new URL and is
applied by the declarative CreateAlertV2 consumer.
2026-07-16 22:08:24 +00:00
Pandey
5ee1ca7d05 fix(ruletypes): round-trip empty notificationSettings fields (#12138)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(ruletypes): always serialize notificationSettings.usePolicy

usePolicy is a plain bool tagged omitempty, so a false value is dropped
from the GET response. Clients that pin usePolicy to false read it back as
absent/null. Drop omitempty (matching Renotify.Enabled) so false always
serializes and round-trips.

* test(ruletypes): assert usePolicy round-trips in minimal read shape

usePolicy now always serializes, so the minimal read shape includes it with a false value rather than omitting it.

* fix(ruletypes): always serialize notificationSettings.groupBy

Like usePolicy, groupBy dropped its omitempty so an explicitly-set empty value round-trips instead of reading back as absent. A nil groupBy now serializes as null.

* fix(ruletypes): use omitzero for notificationSettings.groupBy

omitzero omits groupBy only when nil (unset) while preserving an explicitly-set empty array as [], so unset and empty stay distinguishable instead of every response carrying groupBy: null. Matches the sibling newGroupEvalDelay tag.

* fix(ruletypes): use omitzero for renotify.alertStates

Symmetric to groupBy: omitzero omits alertStates only when nil (unset renotify configs stay absent, no regression) while echoing an explicitly-set empty array as [].

* chore(ruletypes): regenerate openapi spec and api client

groupBy and renotify.alertStates switched to omitzero, so the generated spec marks both slices nullable and the orval client types them as [] | null.
2026-07-16 18:13:24 +00:00
Gaurav Tewari
98c0c53a2b feat: add dashboard in llm o11y (#12136)
* feat: add locked dashboard

* feat: update test cases

* chore: add comments

* chore: update comment

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-16 15:31:06 +00:00
Gaurav Tewari
6d3861d60f feat(llm-attribute-mapping): group + mapper drawers + diff-save [3-4/5] (#11780)
* fix(llm-pricing): constrain currency dropdown width, drop tab URL param

- Currency SelectSimple stretched to fill the filters bar; give it a fixed
  160px width (min-width couldn't cap the trigger).
- Model costs is the only enabled tab for now, so use Tabs defaultValue
  instead of a URL-backed param. Removes the nuqs tab state plus the now-unused
  TAB_KEYS/TAB_QUERY_KEY constants and TabKey type.

* chore: self review changes

* fix: add skeleton loading

* refactor: self review changes

* refactor: initial prop

* fix: update styling

* fix: add comments in utils

* feat(llm-pricing): add model cost drawer and wire into listing page

* fix(llm-pricing): restrict pricing management to admins

Align the frontend write gate with the backend, which protects the
LLM pricing create/update/delete endpoints with AdminAccess (admin
only). Previously manage_llm_pricing allowed EDITOR/AUTHOR, so those
roles saw the Add/Save affordances but their writes were rejected with
a 403. Also removes the AUTHOR entry, which could never reach the page
(the route gate excludes it).

* fix(llm-pricing): read-only drawer shows View title, hides source picker

Non-managers open the drawer in view mode (write APIs are Admin-only), so:
- the heading reads "View model cost" instead of "Edit model cost"
- the Source (auto vs. override) picker is hidden, since switching source is
  a manager-only action with nothing actionable for a viewer.

* refactor: form in edit / add modal

* chore: update color tokens

* fix: add error handling

* chore: update more self review changes

* chore: self review changes

* chore: self review changes

* fix: minor grammer thing

* fix: route thing

* feat(llm-attribute-mapping): add attribute mapping foundation (route, permission, page shell)

* feat(llm-attribute-mapping): read-only groups and mappers listing

* feat(llm-attribute-mapping): group create/edit/delete via drawer with diff-save

* fix: css styling

* style(llm-attribute-mapping): use design-token css variables for spacing and typography

* fix(llm-attribute-mapping): wrap long condition keys so the context badge isn't clipped

* fix(llm-attribute-mapping): unlock filters column shrink so long keys wrap within the cell

* fix: text overflow in attribute mapping

* fix: fetch data only when tab is open

* feat: add attribute mapping tab

* fix: update col count

* chore: review comments

* fix: input

* fix: update logic

* fix: update drawer

* feat: update draft and mapper

* refactor: migrate to css moduel

* refactor: migrate to css module

* refactor: migrate to css module

* refactor: css module

* feat(llm-attribute-mapping): read-only listing on CSS modules [2/5]

Rebase the listing slice onto the foundation's CSS-module refactor
(which deleted the global stylesheet) and migrate it accordingly:

- Merge listing styles into LLMObservabilityAttributeMapping.module.scss
  (groups/mappers tables, source chips, index badge, error/footer).
- Convert all listing components from global BEM classNames to
  styles.* module access; drop dead/style-less classes (am-table,
  am-row-actions, am-add-row, *_edited, mappers-table__error).
- Adopt theme-aware semantic tokens (--l2/l3-*, --accent-primary,
  --callout-error-*) in place of --bg-* primitives.

* refactor(llm-attribute-mapping): migrate styles to CSS modules

* refactor: migrate to tanstack table

* docs: clarify price precision comment

* chore: remove comment

* feat(llm-attribute-mapping): add attribute mapping foundation (route, permission, page shell)

* fix: css styling

* refactor: css module

* feat(llm-attribute-mapping): read-only listing on CSS modules [2/5]

Rebase the listing slice onto the foundation's CSS-module refactor
(which deleted the global stylesheet) and migrate it accordingly:

- Merge listing styles into LLMObservabilityAttributeMapping.module.scss
  (groups/mappers tables, source chips, index badge, error/footer).
- Convert all listing components from global BEM classNames to
  styles.* module access; drop dead/style-less classes (am-table,
  am-row-actions, am-add-row, *_edited, mappers-table__error).
- Adopt theme-aware semantic tokens (--l2/l3-*, --accent-primary,
  --callout-error-*) in place of --bg-* primitives.

* chore: migrate tanstack table

* chore(llm-attribute-mapping): remove orphaned IndexBadge

The TanStack mappers table dropped the leading index column, leaving
IndexBadge and its .indexBadge style unused. Remove both.

* chore: remove comment

* fix: disable isDirty in case of llm pricing

* refactor: number

* feat: add search , dropdown and flag

* feat: feature flag on entire route and add mode costs tabs

* fix: add isFetchingFeatureFlags

* chore: update flag

* refactor: shell

* fix: add key to route

* feat: add flags

* chore: additional refactor

* chore: add commet in utis

* chore: self review changes

* refactor: types and other things

* refactor: types and other things

* chore: add disable on source id

* empty commit

* chore: empty commit

* fix: add demo side nav on sidenav

* chore: remove demo side nav

* refactor: update routes

* chore: remove usd selector for now

* fix: layout shift

* refactor: styles

* refactor: typography component

* refactor: more changes

* refactor: typograhy

* refactor(llm-pricing): break model-cost drawer into per-component files + tokens

Apply the CSS-module/component conventions to the drawer that came from
drawer-3:
- Move the drawer under ModelCostTabPanel/components/ModelCostDrawer/ to mirror
  the ModelCostsTable structure
- Split the single 395-LOC ModelCostDrawer.module.scss into per-component
  co-located modules; cross-component selectors live in shared.module.scss and
  are pulled in via CSS-modules `composes`
- shared.module.scss is a composes target (parsed as plain CSS), so it is kept
  flat with block comments — no SCSS nesting or // comments
- Use --text-vanilla-* (not --bg-vanilla-*) for text colors, matching the
  listing code

* refactor: more changes

* refactor: styling and components

* refactor: styling and components

* chore: add a tooltip on hover

* feat: add delete confirm modal

* fix: update title

* refactor: css variables

* refactor: use signoz button and minor css update

* chore: sync table

* chore: remove extra comment

* chore: use typograpgy test in table config

* fix: minior issues

* fix: llm pricing listing

* refactor: remove extra classes

* refactor: side nav changes

* fix: update missing styles

* chore: update edit and delete options

* chore: remove extra comment

* chore: revert env changes

* chore: add enable check

* chore: remove divider

* refactor: use delete confirm dialog

* chore: remove scss file

* feat: move ui to easily accessable tabs

* feat: update test cases

* chore: update text

* chore: self review changes

* chore: self review refactor

* chore: self review changes

* chore: remove worktree

* chore: revert env.ts

* chore: add attribute mapping foundation

* chore: update ui and add animation

* refactor: components update

* chore: typography changes

* chore: typography changes

* chore: use badge

* refactor: basic components

* chore: remove hardcoded value

* chore: add comments & tests

* chore: update mapper

* chore: update test

* chore: minior ux update

* chore: lodash isEqual

* chore: use lodash

* chore: update save draft

* chore: update env.ts

* chore: update tests

* chore: self review changes

* chore: update test cases

* chore: remove extra comments

* refactor(llm-pricing): share toast copy via constants

* chore: use constants

* chore: redclared constants

* chore: update test cases

* chore: remove unused component

* chore: update types

* chore: update design

* chore: update ui

* refactor: minor things

* chore: break down thingsinto comps

* chore: update files

* fix: update mapping

* chore: remove draft logic no need for now

* chore: more refactor

* chore: remove comments

* chore: refactor route

* chore: update query refech on mount

* chore: self review changes

* chore: update skeleton

* refactor: code

* chore: sync up with group mappers

* chore: only 1 mapper row at a time

* refactor: code

* refactor: eslint disable

* chore: update selector

* chore: sort

* refactor: review changes

* chore: use refetch group

* feat(llm-attribute-mapping): mapper drawer + persistMappers [4/5] (#11781)

* feat(llm-attribute-mapping): mapper drawer + persistMappers [4/5]

Core of the mapper drawer work: the MapperFormDrawer + SourceAttributeRow
UI, persistMappers store logic, mapper row/actions, and supporting
utils/types/saveDraft changes.

Removes the barrel (index.ts) files introduced by this PR
(MapperFormDrawer, MapperActionsMenu, SourceAttributeRow) and imports
those modules directly instead.

Tests, public locales, the conditions tooltip, and the KeySearchInput
relocation follow in a stacked follow-up PR.

* test(llm-attribute-mapping): tooltip, locales, tests + drop barrels [4/5 follow-up]

Follow-up to the mapper drawer core PR. Contains:
- AttributeMappingsTab + LLMObservabilityAttributeMapping test suites
- public locale (titles.json) updates
- the group ConditionsTooltip and its GroupHeader wiring
- relocation of KeySearchInput to the shared components/ dir
- removal of the remaining barrel (index.ts) files across the
  AttributeMapping feature, importing each module directly

* chore: remove comments

* chore: reduce width

* fix: no refetch on open

* chore: add discard dialog

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>

* chore: remove reduced motion

* chore: self review changes

* chore: c should be capital

* chore: review changes

* refactor: sync server store

* chore: update tests

* Revert "chore: update tests"

This reverts commit 5f39c910df.

* Revert "refactor: sync server store"

This reverts commit b92f902d9f.

* chore: rename to editor

* chore: resolve review comments

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-16 14:32:35 +00:00
Nikhil Mantri
20e13f66e0 fix(infra-monitoring): use proper metric names corresponding to entities to be counted (#12130)
* chore: write proper lists of metricNames to lookup for counts

* chore: updated integration tests
2026-07-16 12:54:21 +00:00
Ashwin Bhatkal
07fe353b94 refactor(dashboard-v2): organize variable subsystem into components/ hooks/ utils/ (#12135)
* chore(dashboard-v2): drop self-explanatory comments from the variable subsystem

Remove comments that restate a well-named symbol or narrate obvious steps, and
trim verbose JSDoc to the non-obvious "why". No behavior change.

* refactor(dashboard-v2): organize VariablesBar into components/ hooks/ utils/

Split the flat VariablesBar directory into components/ (each component in its
own folder, co-locating a component-specific .module.scss), hooks/ (all use*
including useVariableOptions, moved out of selectors/), and utils/ (pure
modules). The bar's shared cross-cutting classes and .control stay in the root
VariablesBar.module.scss. Import paths updated across the subsystem; no
behavior change. Also updates a stale URL assertion in the seed test left over
from the store-source-of-truth change.

* refactor(dashboard-v2): organize DashboardSettings/Variables into components/ hooks/ utils/

Move the loose files out of the Variables root: pure modules into utils/
(rename variableDependencies -> variableCycleDetection to end the name clash
with VariablesBar's graph engine), useSaveVariables into hooks/, and VariableRow
and VariablesList into their own component folders with co-located .module.scss.
The shared model, adapters and types stay at the root as the folder's public
API. Import paths updated across the subsystem; no behavior change.

* refactor(dashboard-v2): factor the variable tooltip ref lists into one directional component

Extract TooltipRefSection so "Depends on" and "Used by" share one component,
differing only by color and an up/down arrow that depicts the dependency
direction (up = parents this variable depends on, down = children that use it).

* refactor(dashboard-v2): stack the variable name above its control

Move each variable's name into a notch label above the control: fixed-width
columns, name truncated with a hover title and a spaced/centered info icon,
single-line multi-select, ~33px control height, and a visible dropdown caret.
Nudge the toolbar spacing so the time selector aligns with the shorter bar.
Also render the impact dialog's "still references" warning via Typography
color="warning" instead of a bespoke CSS class.

* fix: top margin
2026-07-16 10:27:44 +00:00
Ashwin Bhatkal
9fb89fafc8 feat(dashboard-v2): variable runtime — resolver, fetch engine, panel loading, impact dialog (#12125)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(dashboard-v2): single default resolver for variable selection

One source of truth for a variable's value (seed → reconcile → payload), shared by the bar, the fetch gate and the query payload so they can't disagree. Precedence stays URL → store → default; ALL materializes once, without an extra round-trip.

* feat(dashboard-v2): dependency-ordered, value-gated variable fetch engine

Query roots + dynamics fetch immediately; query children unblock only once their parents hold a committed value, so a chain fetches each variable once. The cycle is idempotent per (dashboard·order·time) and resets on page unmount, so a re-mount or editor return can't double it or inherit stale state.

* refactor(dashboard-v2): consolidate variable selectors; add bar tooltip + loading bar

Fold the per-type Query/Dynamic/Custom selectors into one VariableValueControl backed by useVariableOptions. Add a hover tooltip showing a variable's dependencies (Depends on / Used by) and a loading bar flush along the control's bottom edge; refine name/dependency colors to design-system tokens.

* feat(dashboard-v2): hold panels in loading until referenced variables resolve

A panel waits until every QUERY/DYNAMIC variable it references is ready — a concrete pick and a DYNAMIC ALL are ready immediately, an unselected value or a QUERY ALL waits until it resolves. The wait folds into the panel's loading flags (a disabled query reports neither), so it never flashes "no data". Only referenced variables re-key the cache.

* feat(dashboard-v2): rename/delete variable impact dialog

Renaming or deleting a referenced variable is blocked behind a dialog listing every usage (QB / PromQL / ClickHouse panels and other variable defs), with a current → resulting preview, per-usage selection, and inline edits; applied as one JSON-Patch.

* fix(dashboard-v2): don't flash ALL on a multi-select while its options load

CustomMultiSelect derives "all selected" from options + the current value; with options still empty a concrete selection reads as covering everything. Only enable ALL detection once options have loaded.

* refactor(dashboard-v2): make the store the source of truth for variable selection

The persisted store (localStorage) is now the sole source of truth for runtime
variable values. Stop writing ?variables= on every selection change; the URL
param is read once on load (a share link) to seed the store and then dropped,
so dashboard navigation and drilldown no longer round-trip through the URL. The
panel editor reads the selection from the store (a lagging URL snapshot could
clobber a just-changed value). Drops the now-unused withVariablesSearch.

* refactor(dashboard-v2): address review feedback on the variable subsystem

- consolidate the default resolver: one configuredDefault normalizer shared by
  resolveDefaultSelection and configuredDefaultValue, plus a textDefault helper
  for TEXT (drops the dead textValue/empty-string fallbacks)
- reuse computeVariableDependencies for the bar tooltip's depends-on / used-by
- split the fetch machinery out of useVariableOptions into useFetchedVariableOptions
- extract useVariableListActions from the variables settings page
- reuse removeVariableFromExpression for delete-clause removal (handles dangling
  syntax / parentheses) and drop the local removeVariableReferenceClause
- grey the impact dialog's Current field on uncheck; comment + spacing nits;
  guard useIsPanelWaitingOnVariable so it reads variableTypes without optional chaining
- fix the seed test's read-once URL assertion
2026-07-16 08:54:38 +00:00
Abhi kumar
0655328fa9 feat(dashboard-v2): export panels & dashboards from explorers (#12043)
* feat(dashboard-v2): new-panel editor route + query-preserving seed

Add the /dashboard/:id/panel/new route helpers (buildExportPanelLink,
parseNewPanelKind, layoutIndex) and buildNewPanelSeed, which converts an
exported explorer compositeQuery into a seeded panel.

Coerces a builder-only kind (List) to a query-compatible one (PromQL ->
TimeSeries, ClickHouse -> Table) so a non-builder query is preserved rather
than dropped. PanelEditorPage consumes the effective kind; new List panels
seed columns from the query's resolved signal.

* feat(dashboard-v2): flag-aware export-to-dashboard hooks

Add the hooks shared by the explorer "Add to dashboard" flow:

- useGetExportToDashboardLink: builds the V2 panel-editor link (or the V1
  new-widget link) based on the use_dashboard_v2 flag.
- useExportDashboards: flag-aware, search-filtered dashboard source. V2
  searches server-side via the name-contains filter DSL (debounced); V1
  filters its already-complete list in memory.
- useCreateExportDashboard: flag-aware "create a new dashboard" - V2 via the
  Perses createDashboardV2, V1 via the legacy create - normalized to Dashboard.

* feat(dashboard-v2): rebuild "Add to dashboard" export dialog

Replace the antd Modal-based ExportPanel with a @signozhq/ui DialogWrapper
dialog driven by the export hooks. The picker searches server-side and pins the
selected dashboard as an option so it survives a narrowing search; "New
dashboard" creates via the flag-aware hook and navigates to the panel editor.

Removes the old index.tsx / styles.ts.

* feat(dashboard-v2): wire explorers to flag-aware export

Point the Logs/Traces/Metrics explorer "Add to dashboard" actions at
useGetExportToDashboardLink, so an exported query lands in the V2 panel editor
when use_dashboard_v2 is on (the V1 new-widget link otherwise). ExplorerOptions
now renders the rebuilt ExportPanel dialog directly instead of wrapping it in an
antd Modal.

* chore: fixed failing tests

* refactor(dashboard-v2): address explorer-export review feedback

- rename isQueryTypeSupported → isQueryTypeSupportedByPanelKind for clarity
- buildExportPanelLink returns null (no silent TimeSeries default) when a
  panel type has no V2 kind; explorers guard navigation on the null link
- introduce a neutral ExportDashboard {id,title} for the picker instead of
  reusing the V1 Dashboard entity with faked fields
- note why an exported Query's single unit doesn't seed columnUnits

* chore: pr review changes
2026-07-16 05:49:06 +00:00
Vinicius Lourenço
f24102c0db feat(infrastructure-monitoring-v2): pod status/counts & couple more fixes (#12127)
* refactor(infrastructure-monitoring-v2): remove pod phase and add pod status/counts

* fix(column-header): align to left

* fix(cell-value): ensure tooltip is correctly aligned

* fix(entity-traces): use - instead of N/A

* test(entity-traces): fix broken test
2026-07-16 03:34:12 +00:00
Vinicius Lourenço
edee102b52 feat(infrastructure-monitoring): add pod metrics tab (#12106)
* fix(k8s-base-details): do not allow untoggle tabs

* feat(constants): add base queries for all workloads

Ref: https://github.com/SigNoz/engineering-pod/issues/4032#issuecomment-4893103716

* feat(daemon-sets): add pod metrics tab

* feat(deployments): add pod metrics tab

* feat(jobs): add pod metrics tab

* feat(namespaces): add pod metrics tab

* feat(statefulsets): add pod metrics tab

* fix(k8s-base-details): do not keep selected invalid tab

* fix(pod-metrics): add new badge

* Revert "fix(pod-metrics): add new badge"

This reverts commit 09b8624f52c74b2e4dd5895cfc30206c226a1e97.

* chore(k8s-base-details): mark tab as possible null
2026-07-16 03:30:33 +00:00
Srikanth Chekuri
9a26998d18 chore: add integration tests for metrics under reduction - query part (#11979)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore: add integration tests for metrics under reduction - query part

* chore: add to ci

* chore: add todos

* chore: update tests

* chore: trigger build

* chore: address review comments

* chore: undo the changes to tests/fixtures/http.py

* chore: remove __normalized and add fast path

* chore: fix unit tests

* chore: update test

* chore: sunset 25.5.6, update migrator version, and remove version arg

* chore: also update devenv

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 21:27:39 +00:00
Vinicius Lourenço
fbf2e62044 feat(infrastructure-monitoring-v2): add onboarding checks (#12119)
* feat(infrastructure-monitoring): add onboarding checks

* refactor(infrastructure-monitoring): use error content to show error message

* test(infrastructure-monitoring): add tests for onboarding checks
2026-07-15 19:47:30 +00:00
Tushar Vats
62c44f5eac chore: pass org id for flagger (#12126) 2026-07-15 19:47:24 +00:00
Vinicius Lourenço
65fde71b72 feat(infrastructure-monitoring-v2): add counts cards (#12120)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(entity-count): add base structure to show count

* feat(entity-count): add count for clusters

* feat(entity-count): add count for namespaces

* chore(infra-monitoring): move component to be under components folder

* fix(pr): address comments
2026-07-15 13:39:48 +00:00
Vinicius Lourenço
7f5f63b20a feat(infra-monitoring): add docs for every chart (#12037)
* feat(infra-monitoring): add docs for every chart

* fix(docs): add missing docs for each column/chart

* fix(infra-monitoring): keep referer

---------

Co-authored-by: Nikhil Mantri <nikhil.mantri1999@gmail.com>
2026-07-15 13:25:53 +00:00
Tushar Vats
63cfbe8bfb fix: convert key not found to warnings for traces (#12091) 2026-07-15 12:33:47 +00:00
Aditya Singh
0c28b8b251 feat: scalar/table serializers for client-side export (3) (#12070)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* refactor(data-export): extract the withUnit header helper

Both the timeseries and the upcoming table serializers append units to headers (and skip display-only ids like 'short'/'none') — move the helper to its own module.

* feat(data-export): add generic table-model serializer

exportTableData serializes any prepared antd-style table model ({name, key, isValueColumn} columns + record rows) into a SerializedTable — raw values in display order, units on value columns only, blanks for missing cells. Surface-agnostic: QueryTable-based tables, dashboard tables and plain antd tables all adapt in a line or two.

* feat(data-export): add scalar queryRange serializer

exportScalarData takes the queryRange response object (formatForWeb webTables payload) + the builder query and serializes via createTableColumnsFromQuery — the exact preparer QueryTable renders from — so exports inherit the on-screen merge, naming and column order 1:1.
2026-07-15 05:37:15 +00:00
Aditya Singh
10a0d262d9 feat: add download option to trace view (#12116) 2026-07-15 05:36:59 +00:00
Vinicius Lourenço
334155a226 fix(infra-monitoring-v2): ensure workloads has filters by cluster+namespace (#12076)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(tanstack): add support for itemKey be object

* feat(infra-monitoring): add base structure for multiple selected items

* refactor(infra-monitoring): add cluster for namespaces, cluster/namespace for volumes + update other entities

* refactor(infra-monitoring): add cluster + namespace for statefulsets

* refactor(infra-monitoring): add cluster + namespace for jobs

* refactor(infra-monitoring): add cluster + namespace for deployments

* refactor(infra-monitoring): add cluster + namespace for daemonsets

* test(infra-monitoring): add new tests for changes of k8s base list

* fix(pr): address comments
2026-07-14 18:24:42 +00:00
Pandey
42de840534 fix(rules): scope alert rule store operations by org (#12117)
* fix(rules): scope alert rule store operations by org

The rule store predicates filtered on the rule id only, so on multi-org
deployments (Cloud/EE/multi-org self-hosted, where orgs share the
instance via the noop sharder) an authenticated user could read, edit or
delete another org's alert rules by supplying the target rule UUID.
ViewAccess/EditAccess only check the caller's own-org role, never the
resource's org, so nothing enforced tenant isolation on the rule itself.

Enforce org scoping at the store layer, which is the durable fix:

- GetStoredRule and DeleteRule now take the caller's orgID and add
  `org_id = ?` to their predicates.
- EditRule adds `org_id = ?` (from the model, which is now always
  sourced from an org-scoped read).
- The manager passes claims.OrgID on every by-id path; GetRule now
  derives the org from claims (it previously fetched by id alone).

Cross-org ids now resolve to NotFound instead of leaking or mutating
another org's rule. Single-org OSS instances are unaffected.

CWE-639 (authorization bypass through user-controlled key).

* refactor(rules): derive claims org id with valuer.MustNewUUID

Claims are pre-validated by the auth middleware, so the NewUUID error
branch is dead code. Follow the handler convention (docs/contributing/
go/handler.md) and use the Must constructor on the by-id rule paths.
2026-07-14 18:00:09 +00:00
Nityananda Gohain
891106d1ca fix: set correct openapi response struct for span mapper list (#12094)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix: set correct opapi response model for span mapper list

* fix: change group_id to groupId in response

* fix: format properly

* fix: update fixtures
2026-07-14 15:34:52 +00:00
Naman Verma
707f01bd9c chore: support non-dsl search in dashboards v2 list apis (#12051)
* chore: support non-dsl search in dashboards v2 list apis

* chore: move free text compilation to visitor

* chore: shorten comments

* fix: support both plain text and dsl together

* fix: ensure empty description dashboards are not excluded in NOT checks
2026-07-14 13:02:58 +00:00
Vinicius Lourenço
3cd0c21703 feat(daemonsets): add ready/misscheduled columns (#12102) 2026-07-14 12:33:21 +00:00
Abhi kumar
181feb3eb9 fix(dashboard-v2): only refetch on-screen panels on time change/auto-refresh (#12113)
Panel visibility was latched (isObserverOnce), so once every panel had
scrolled into view they all stayed query-enabled. A time change or
auto-refresh re-keys every panel's query, refetching all of them at once.

Track the live viewport instead so off-screen panels stay query-disabled
and skip the refetch; they fetch lazily when scrolled back in. Add
staleTime: Infinity so re-entering an unchanged window serves cache rather
than thrash-refetching (key changes and manual refetch still run).
2026-07-14 12:23:04 +00:00
Naman Verma
bf35d12398 chore: add functional unique index for tags (#12029)
* feat: add functional unique index

* chore: add tag migration

* chore: add failing scratch test (to discuss)

* chore: fetch expressions as well in getindices call

* fix: remove tag unique index (will be added in a separate PR)

* fix: remove tag unique index (will be added in a separate PR)

* chore: remove temporary tests

* chore: add functional unique index for tags

* fix: go lint fix

* fix: go lint fix

* chore: better comment for unique index

* test: add test for case insensitive expression equality

* test: add equality test for columns with quotes and capital letters

* test: add test for quoted columns

* chore: add separate type for unique indices with expressions

* fix: update migration file to use correct index

* test: add test for postgres provider

* test: add test for postgres provider

* fix: remove round trip tests
2026-07-14 11:08:59 +00:00
Abhi kumar
1a1f7b2d78 fix(dashboard-v2): bug bash fixes IV (#12056)
* fix(context-menu): keep overlay clickable when opened inside a modal

Portal the popover to body and set pointer-events:auto so a modal's dialog/backdrop can't trap it.

* fix(dashboard-v2): center scrolled-to panels and sections

Default the scroll block to 'center' so a targeted panel lands mid-viewport.

* fix(dashboard-v2): make the view modal refresh button secondary

Use outlined/secondary so refresh doesn't compete with the primary action.

* fix(dashboard-v2): fetch only on-screen panels on dashboard load

RGL unfolds panels from the top-left origin on mount, briefly piling them into the viewport.

The latched observer then marked all visible; suppress the item transition for the first frame.

* chore: readded entry animation
2026-07-14 10:43:14 +00:00
dependabot[bot]
a2778aa45f chore(deps): bump golang.org/x/net from 0.54.0 to 0.55.0 (#11965)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.54.0 to 0.55.0.
- [Commits](https://github.com/golang/net/compare/v0.54.0...v0.55.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.55.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 10:01:13 +00:00
Srikanth Chekuri
16c1fce326 fix(ruletypes): address rule read round-trip gaps (#12110)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-14 08:36:30 +00:00
Gaurav Tewari
06b762b7ef fix(llm o11y): update unpriced models tab test case (#12108)
* fix: update unpriced models tab test case

* chore: update ci timming

* chore: update comment

* chore: remove comment

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-14 08:22:03 +00:00
Aditya Singh
466edf1f1c feat: timeseries export in logs, traces and metrics explorers (2) (#12055)
* feat(data-export): surface raw V5 response and legend map from GetMetricQueryRange

Keeps the pre-conversion V5 queryRange response and the per-query legend map on the returned MetricQueryRangeSuccessResponse so explorer views can feed client-side export without a refetch. Additive optional fields; the legacy V3 render path is untouched. One chokepoint covers Logs, Traces and Metrics.

* fix(data-export): omit display-only format ids from export headers

'short'/'none' are Grafana-style display formats, not physical units — meaningful on a chart axis but misleading as 'value (short)' in a CSV header. Real units (ms, bytes, ...) are unchanged.

* feat(data-export): timeseries export menu and opt-in TimeSeriesView header

New TimeseriesExportMenu (csv/jsonl, LONG shape default; same look as DownloadOptionsMenu, which stays raw/list-only) rendered from a new opt-in TimeSeriesView header row: unit selector left (onYAxisUnitChange — rendering only, unit state stays with each view), download right (allowExport, needs the surfaced raw V5). Both default off, so views opt in explicitly. Includes gating + menu tests.

* feat(explorer): enable timeseries export in Logs, Traces and Metrics

Logs and Traces pass allowExport + onYAxisUnitChange and drop their external unit-filter headers (one header row: unit left, download right). Metrics passes allowExport only, per chart — its YAxisUnitSelector stays screen-level (persists to the metric, spans N charts). convertDataValueToMs now converts the raw V5 tree too, so Traces duration exports carry the ms values the chart shows instead of raw nanoseconds.

* refactor(data-export): use @signozhq/ui components in the export popover

Review feedback: swap antd Button/Popover/Tooltip for the design-system equivalents (radix-style Popover with controlled open, TooltipSimple, Button with native loading). Styles restructured for the DS DOM with periscope font tokens; test renders via tests/test-utils for the TooltipProvider.
2026-07-14 06:54:51 +00:00
Nikhil Mantri
849353b5c0 feat(infra-monitoring): counts query for counting related entities (#12000)
* chore: added types and open api spec changes

* chore: added method to calculate reason

* chore: per group pod status counts with req metric checks method added

* chore: wired up pod status counts

* chore: pod restarts type added

* chore: added restart counts for the group

* chore: bug in query fix

* chore: onboarding API changes

* chore: integration tests added

* chore: added podcountsbyphase in other entities

* chore: added pod status counts for other entities

* chore: added integration tests for other entities

* chore: added checks api changes for other entities

* chore: rearrangement

* chore: removed succeeded status and mark it as completed

* chore: query beautified

* chore: corrected metrics list for metadata lookup

* chore: removed dead constants

* chore: goroutines for ListHosts

* chore: goroutines for ListPods

* chore: goroutines for ListNodes

* chore: goroutines for ListNamespaces

* chore: goroutines for ListClusters

* chore: goroutines for ListDeployments

* chore: goroutines for ListStatefulsets

* chore: added goroutines for ListStatefulsets, ListJobs and ListDaemonsets

* chore: added function

* chore: added struct changes

* chore: added count attr keys

* chore: wired counts to the response fields

* chore: regenerated API spec

* chore: merged main, resolved conflicts

* chore: nodes count surfacing

* chore: integration tests added

* fix: use tuple mapping to uniquely identify attrs:

* chore: integration tests update
2026-07-14 06:38:27 +00:00
Ashwin Bhatkal
8e4d7c68b3 feat(dashboard-v2): query-first DSL filter for the dashboards list (#12046)
* feat(dashboard-v2): stage-aware DSL autocomplete engine for the list filter

* feat(dashboard-v2): single query-string list-filter state with reflect/splice

* feat(dashboard-v2): drive saved/built-in views off the query string

* feat(dashboard-v2): CodeMirror query box with DSL autocomplete popup

* feat(dashboard-v2): antd Created-by/Updated filter selects, drop the Tags dropdown

* feat(dashboard-v2): wire the DSL filter into the dashboards list (sticky header, pagination)

* fix: small css elevation

* refactor(dashboard-v2): reuse shared operator constants in the DSL grammar

Build STRING_OPS / OPERATOR_MATRIX / VALUELESS_OPERATORS from the shared OPERATORS + negateOperator (constants/antlrQueryConstants) instead of hardcoded strings; drop a stale lint-disable in FilterChips. Addresses review comments.

* fix(dashboard-v2): wrap IN/NOT IN autocomplete values in a bracketed list

Picking a value for an IN/NOT IN clause in the DSL search box inserted a
bare literal ('x') instead of a list (['x']). The value stage now wraps a
fresh pick in a closed bracketed list, appends subsequent picks inside the
existing brackets (deduping already-entered values), and keeps the caret
inside the list so multi-select continues.

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-07-14 05:29:21 +00:00
Gaurav Tewari
2704317c6a feat(llm-pricing): add Unpriced Models tab with billing-model mapping [6/6] (#11813)
* feat(llm-pricing): add model pricing foundation (route, permission, page shell)

* feat(llm-pricing): add listing page and table

* chore(llm-pricing): drop search + source filters from list request

The list API does not honour the q (search) and source params yet, so
the controls did nothing. Remove the search input and source dropdown
along with the params we sent, and trim useModelPricingFilters to the
URL-backed page state that pagination still needs. Currency dropdown,
tabs, table and pagination are unchanged. Filters will return once the
backend supports them.

* refactor(llm-pricing): extract getRelativeTime helper in utils

Pull the relative-time formatting out of getRelativeLastSeen into a
small local getRelativeTime helper. Kept feature-local (not in the
shared utils/timeUtils) so the LLM pricing module owns its own dayjs
config; the local relativeTime extend stays for test self-sufficiency.

* refactor(llm-pricing): drop dead NaN guard in formatPricePerMillion

Pricing fields are typed as required numbers and JSON can't carry NaN,
so Number.isNaN was unreachable. Keep the null/undefined guard as API
defensiveness (toFixed on a missing value would crash the row). Also
trims the now-redundant dayjs.extend comment.

* refactor(llm-pricing): centralize constants and shared types

Extract PAGE_SIZE, PAGE_KEY, COLUMN_COUNT and CURRENCY_OPTIONS into a
new constants.ts, and move the ModelPricingFilters contract into
types.ts. Component prop interfaces stay colocated with their
components, matching the convention in the drawer PR.

* refactor(llm-pricing): use nuqs for list pagination URL state

Replace the hand-rolled useHistory + URLSearchParams plumbing in
useModelPricingFilters with nuqs useQueryState, matching the convention
used by the dashboards, alerts and k8s list pages. Behaviour is
unchanged: parseAsInteger.withDefault(1) keeps ?page=1 out of the URL
and history:'replace' avoids polluting the back-stack.

* refactor(llm-pricing): inline pagination, drop useModelPricingFilters

The hook had shrunk to a one-line nuqs wrapper after search/source were
removed, so inline the useQueryState call into the container and remove
the hook file plus the now-unused ModelPricingFilters type. When the
filters return (once the API honours them) they can move back into a
dedicated hook.

* feat(llm-pricing): disable currency selector (USD-only for now)

Only USD is priced today, so render the currency SelectSimple in a
disabled state pinned to USD. A disabled select can't fire onChange, so
the currency useState is dead — drop it (and the now-unused useState
import).

* refactor(llm-pricing): render model costs inside its tab + tab URL param

The listing was rendered outside the Tabs, so the tab was decorative.
Move all model-cost content (currency control, list query, table,
pagination, footer) into a ModelCostsTab component rendered as the
'Model costs' tab's children, and drive the active tab from a 'tab' URL
query param (nuqs). The container is now just the page shell. Unpriced
models stays a disabled placeholder for a later PR.

* style(llm-pricing): target @signozhq table slots, drop dead antd/leftover rules

The component uses @signozhq/ui Table/Tabs (Radix-based), not antd, so the
.ant-table-* and .ant-tabs-nav selectors never matched — the intended
uppercase/muted header styling wasn't applied. Retarget header/cell rules to
[data-slot='table-head'|'table-cell'] (no !important needed). Also remove dead
rules left over from the removed search/source/add UI (.filters-bar__search,
__source, __add, .page-header__actions) and the unused .source-badge--auto/
--override modifiers.

* fix(llm-pricing): constrain currency dropdown width, drop tab URL param

- Currency SelectSimple stretched to fill the filters bar; give it a fixed
  160px width (min-width couldn't cap the trigger).
- Model costs is the only enabled tab for now, so use Tabs defaultValue
  instead of a URL-backed param. Removes the nuqs tab state plus the now-unused
  TAB_KEYS/TAB_QUERY_KEY constants and TabKey type.

* chore: self review changes

* fix: add skeleton loading

* refactor: self review changes

* refactor: initial prop

* fix: update styling

* fix: add comments in utils

* feat(llm-pricing): add model cost drawer and wire into listing page

* fix(llm-pricing): restrict pricing management to admins

Align the frontend write gate with the backend, which protects the
LLM pricing create/update/delete endpoints with AdminAccess (admin
only). Previously manage_llm_pricing allowed EDITOR/AUTHOR, so those
roles saw the Add/Save affordances but their writes were rejected with
a 403. Also removes the AUTHOR entry, which could never reach the page
(the route gate excludes it).

* fix(llm-pricing): read-only drawer shows View title, hides source picker

Non-managers open the drawer in view mode (write APIs are Admin-only), so:
- the heading reads "View model cost" instead of "Edit model cost"
- the Source (auto vs. override) picker is hidden, since switching source is
  a manager-only action with nothing actionable for a viewer.

* refactor: form in edit / add modal

* chore: update color tokens

* fix: add error handling

* chore: update more self review changes

* chore: self review changes

* chore: self review changes

* fix: minor grammer thing

* fix: route thing

* refactor: migrate to css moduel

* refactor: migrate to css module

* refactor: migrate to css module

* refactor: migrate to tanstack table

* docs: clarify price precision comment

* chore: remove comment

* chore: remove comment

* fix: disable isDirty in case of llm pricing

* refactor: number

* feat: add search , dropdown and flag

* feat: feature flag on entire route and add mode costs tabs

* fix: add isFetchingFeatureFlags

* feat: llm pricing unpriced model

* chore: update flag

* refactor: shell

* fix: add key to route

* feat: add flags

* chore: additional refactor

* chore: add commet in utis

* chore: self review changes

* refactor: types and other things

* refactor: types and other things

* chore: add disable on source id

* empty commit

* feat: add search to search model name

* chore: empty commit

* fix: add demo side nav on sidenav

* chore: remove demo side nav

* refactor: update routes

* chore: remove usd selector for now

* fix: layout shift

* refactor: styles

* refactor: typography component

* refactor: more changes

* refactor: typograhy

* refactor(llm-pricing): break model-cost drawer into per-component files + tokens

Apply the CSS-module/component conventions to the drawer that came from
drawer-3:
- Move the drawer under ModelCostTabPanel/components/ModelCostDrawer/ to mirror
  the ModelCostsTable structure
- Split the single 395-LOC ModelCostDrawer.module.scss into per-component
  co-located modules; cross-component selectors live in shared.module.scss and
  are pulled in via CSS-modules `composes`
- shared.module.scss is a composes target (parsed as plain CSS), so it is kept
  flat with block comments — no SCSS nesting or // comments
- Use --text-vanilla-* (not --bg-vanilla-*) for text colors, matching the
  listing code

* refactor: more changes

* refactor: styling and components

* refactor: styling and components

* chore: add a tooltip on hover

* feat: add delete confirm modal

* fix: update title

* refactor: css variables

* refactor: use signoz button and minor css update

* chore: sync table

* chore: remove extra comment

* chore: use typograpgy test in table config

* fix: minior issues

* fix: llm pricing listing

* refactor: remove extra classes

* refactor: side nav changes

* fix: update missing styles

* chore: update edit and delete options

* chore: remove extra comment

* chore: revert env changes

* chore: add enable check

* chore: remove divider

* refactor: use delete confirm dialog

* chore: remove scss file

* feat: move ui to easily accessable tabs

* feat: update test cases

* chore: update text

* chore: self review changes

* chore: self review refactor

* chore: self review changes

* feat(llm-pricing): batch-map unpriced models via top Save + confirm drawer

Replace the per-row "Map to model" button + inline confirm with a single
top-level Save button that opens a confirm drawer listing every pending
mapping in a table (model -> billing model + pricing).

- Batch the save: group selections by target rule so multiple models mapped
  to the same rule append their patterns in one PUT instead of clobbering
- Capped, skeleton-loaded unpriced table (max-height) to avoid layout shift,
  matching the model-costs table
- Restore the dropped .modelCellName style; drop dead inline-confirm styles
- Tests: batch/clobber hook test, tab integration flow, and fix the stale
  'unpriced tab disabled' assertion (the tab is now enabled)

* chore: remove worktree

* chore: revert env.ts

* chore: update llm pricing

* chore: update ui

* chore: sync unpriced modal

* chore(llm-pricing): address Copilot review on unpriced confirm table

- formatSpanCount: use Intl.NumberFormat compact so 999,999 renders as
  "1M" (not "1000.0K") and trailing ".0" is dropped
- confirm drawer extra-buckets container: non-wrapping inline-flex so
  buckets stay on one line at the fixed row height
- soften the misleading "renders identically" comment (extra buckets are
  plain inline text here, not the model-costs Badge chips)

* chore: flex wrap

* chore: self review changes

* feat: add support to remove model

* chore: update ux

* chore: update test cases

* chore: remove unused test cases

* chore: update tests

* chore: remove extra integration

* chore: refactor

* refactor: imports

* refactor: un priced modal

* chore: update unpriced modal

* chore: update map billing mode select

* refactor: code

* refactor: remove comments

* chore: make bg great again

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-14 04:43:28 +00:00
Vinicius Lourenço
9476d8f70f feat(infrastructure-monitoring-v2): add button to open chart at metrics explorer (#12107)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-13 19:29:46 +00:00
Vinicius Lourenço
69a240fdb2 chore(frontend): bump deps (#12052)
* chore(frontend): bump deps

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* chore(pnpm-lock): missing update

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-13 17:14:22 +00:00
Vinicius Lourenço
6975c4d90c chore(codeowners): update infra monitoring file owner (#12073)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-13 11:47:09 +00:00
Vikrant Gupta
9bfa6e6d59 feat(authz): store role transaction groups as JSON document (#12028)
* feat(authz): store role transaction groups as document of record

Persist a role's transaction groups as JSON on the role row so the role
details page is reconstructed deterministically from SQL instead of being
rebuilt from OpenFGA tuples (which will soon carry opaque hashed telemetry
selectors):

- authtypes: TransactionGroups gains Value/Scan (validated via
  NewTransactionGroups) and MarshalJSON (nil renders as []); NewRole takes
  transactionGroups; NewManagedRoles fills managed docs from the registry;
  RoleWithTransactionGroups removed - Role carries the wire field and the
  AuthZ interface, handler, and OpenAPI responses use *Role; GettableRole
  (without transactionGroups) is the list response
- sqlmigration 099: add role.transaction_groups, backfill custom roles from
  their permission tuples (dual dialect) and managed roles from the registry
- sqlmigration 059: pin insert columns so the live Role model addition does
  not break fresh installs (059 runs before 099)
- ee provider: writes persist the doc alongside FGA tuples (FGA first, SQL
  second, as before); GetWithTransactionGroups reads the doc; the per-type
  ReadTuples fan-out (readAllTuplesForRole) is removed
- audit middleware: log and skip resolved resources carrying a resolution
  error
- frontend: regenerated OpenAPI spec and API types; role list consumers
  retyped to GettableRole; role GET keeps transactionGroups

* fix(authz): reconcile role tuples from openfga state, decouple migration 059

- Update and Delete derive their diff/deletion base from the tuples openfga
  actually holds for the role (readAllTuplesForRole) instead of the stored
  JSON record, so every mutation sweeps drift and residue; the record stays
  a display-only artifact written after the tuple write
- ReadTuples restored on the AuthZ interface with plain passthroughs in both
  providers and the ee server
- TransactionGroups.Value marshals unconditionally (nil renders as [] via
  MarshalJSON) instead of returning a nil driver.Value
- migration 059 uses a migration-local role struct and constructor so live
  Role model changes cannot alter its insert; migration 099 drops the manual
  column-exists guard (AddColumn emits IF NOT EXISTS)

* refactor(authz): split role into domain Role and StorableRole

Replace the Scan/Value/MarshalJSON codecs on TransactionGroups with the
storable pattern: StorableRole is the bun model carrying transaction groups
as raw JSON text, Role is the pure domain/wire type, and
NewStorableRoleFromRole/NewRoleFromStorableRole convert at the store
boundary (nil groups persist as [], reads parse through the validating
constructor). RoleStore and sqlauthzstore speak StorableRole; both
providers convert; handlers and the wire contract are unchanged.

* revert(authz): restore TransactionGroups codecs over the storable split

Role is a bun relation target (UserRole.Role, ServiceAccountRole.Role), so
splitting it into StorableRole/Role cascaded: relations must point at the
bun model, which broke the user-roles join and leaked the storable shape
into user and service account responses. Keep the single Role model with
Scan/Value/MarshalJSON on TransactionGroups; the storable split fits leaf
models only.

This reverts commit 73aa7d32b1 and keeps transaction_test.go deleted.

* refactor(authz): use bun models in migration 099, wire oss role get

- migration 099 follows the migration-local row struct pattern: bun
  NewSelect/NewUpdate for the role table reads and backfill writes; the
  openfga store and tuple lookups stay raw like 081/083
- oss provider Get reads the role from the store instead of returning
  unsupported

* refactor(authz): org-scoped backfill in migration 099, empty groups on null scan

- migration 099 iterates organizations: per org it backfills custom roles
  from their permission tuples (readRoleTuples helper) and managed roles
  from the registry (JSON precomputed per role name)
- TransactionGroups scans SQL NULL as an empty slice so the api always
  renders transactionGroups as []; nullzero keeps writing NULL for nil

* fix(authz): pass unique constraints to add column in migration 099
2026-07-13 11:42:42 +00:00
Swapnil Nakade
86313ae561 feat: clousql - adding metrics in definition and dashboard JSON (#12072)
* feat: adding metrics in definition and dashboard JSON

* refactor: renaming cloudsql to cloudsql_postgres

* refactor: generating openapi specs
2026-07-13 09:57:49 +00:00
Gaurav Tewari
f764a8d9af feat(llm-attribute-mapping): read-only listing [2/5] (#11779)
* feat(llm-pricing): add model pricing foundation (route, permission, page shell)

* feat(llm-pricing): add listing page and table

* chore(llm-pricing): drop search + source filters from list request

The list API does not honour the q (search) and source params yet, so
the controls did nothing. Remove the search input and source dropdown
along with the params we sent, and trim useModelPricingFilters to the
URL-backed page state that pagination still needs. Currency dropdown,
tabs, table and pagination are unchanged. Filters will return once the
backend supports them.

* refactor(llm-pricing): extract getRelativeTime helper in utils

Pull the relative-time formatting out of getRelativeLastSeen into a
small local getRelativeTime helper. Kept feature-local (not in the
shared utils/timeUtils) so the LLM pricing module owns its own dayjs
config; the local relativeTime extend stays for test self-sufficiency.

* refactor(llm-pricing): drop dead NaN guard in formatPricePerMillion

Pricing fields are typed as required numbers and JSON can't carry NaN,
so Number.isNaN was unreachable. Keep the null/undefined guard as API
defensiveness (toFixed on a missing value would crash the row). Also
trims the now-redundant dayjs.extend comment.

* refactor(llm-pricing): centralize constants and shared types

Extract PAGE_SIZE, PAGE_KEY, COLUMN_COUNT and CURRENCY_OPTIONS into a
new constants.ts, and move the ModelPricingFilters contract into
types.ts. Component prop interfaces stay colocated with their
components, matching the convention in the drawer PR.

* refactor(llm-pricing): use nuqs for list pagination URL state

Replace the hand-rolled useHistory + URLSearchParams plumbing in
useModelPricingFilters with nuqs useQueryState, matching the convention
used by the dashboards, alerts and k8s list pages. Behaviour is
unchanged: parseAsInteger.withDefault(1) keeps ?page=1 out of the URL
and history:'replace' avoids polluting the back-stack.

* refactor(llm-pricing): inline pagination, drop useModelPricingFilters

The hook had shrunk to a one-line nuqs wrapper after search/source were
removed, so inline the useQueryState call into the container and remove
the hook file plus the now-unused ModelPricingFilters type. When the
filters return (once the API honours them) they can move back into a
dedicated hook.

* feat(llm-pricing): disable currency selector (USD-only for now)

Only USD is priced today, so render the currency SelectSimple in a
disabled state pinned to USD. A disabled select can't fire onChange, so
the currency useState is dead — drop it (and the now-unused useState
import).

* refactor(llm-pricing): render model costs inside its tab + tab URL param

The listing was rendered outside the Tabs, so the tab was decorative.
Move all model-cost content (currency control, list query, table,
pagination, footer) into a ModelCostsTab component rendered as the
'Model costs' tab's children, and drive the active tab from a 'tab' URL
query param (nuqs). The container is now just the page shell. Unpriced
models stays a disabled placeholder for a later PR.

* style(llm-pricing): target @signozhq table slots, drop dead antd/leftover rules

The component uses @signozhq/ui Table/Tabs (Radix-based), not antd, so the
.ant-table-* and .ant-tabs-nav selectors never matched — the intended
uppercase/muted header styling wasn't applied. Retarget header/cell rules to
[data-slot='table-head'|'table-cell'] (no !important needed). Also remove dead
rules left over from the removed search/source/add UI (.filters-bar__search,
__source, __add, .page-header__actions) and the unused .source-badge--auto/
--override modifiers.

* fix(llm-pricing): constrain currency dropdown width, drop tab URL param

- Currency SelectSimple stretched to fill the filters bar; give it a fixed
  160px width (min-width couldn't cap the trigger).
- Model costs is the only enabled tab for now, so use Tabs defaultValue
  instead of a URL-backed param. Removes the nuqs tab state plus the now-unused
  TAB_KEYS/TAB_QUERY_KEY constants and TabKey type.

* chore: self review changes

* fix: add skeleton loading

* refactor: self review changes

* refactor: initial prop

* fix: update styling

* fix: add comments in utils

* feat(llm-pricing): add model cost drawer and wire into listing page

* fix(llm-pricing): restrict pricing management to admins

Align the frontend write gate with the backend, which protects the
LLM pricing create/update/delete endpoints with AdminAccess (admin
only). Previously manage_llm_pricing allowed EDITOR/AUTHOR, so those
roles saw the Add/Save affordances but their writes were rejected with
a 403. Also removes the AUTHOR entry, which could never reach the page
(the route gate excludes it).

* fix(llm-pricing): read-only drawer shows View title, hides source picker

Non-managers open the drawer in view mode (write APIs are Admin-only), so:
- the heading reads "View model cost" instead of "Edit model cost"
- the Source (auto vs. override) picker is hidden, since switching source is
  a manager-only action with nothing actionable for a viewer.

* refactor: form in edit / add modal

* chore: update color tokens

* fix: add error handling

* chore: update more self review changes

* chore: self review changes

* chore: self review changes

* fix: minor grammer thing

* fix: route thing

* refactor: migrate to css moduel

* refactor: migrate to css module

* refactor: migrate to css module

* refactor: migrate to tanstack table

* docs: clarify price precision comment

* chore: remove comment

* feat(llm-attribute-mapping): add attribute mapping foundation (route, permission, page shell)

* fix: css styling

* refactor: css module

* feat(llm-attribute-mapping): read-only listing on CSS modules [2/5]

Rebase the listing slice onto the foundation's CSS-module refactor
(which deleted the global stylesheet) and migrate it accordingly:

- Merge listing styles into LLMObservabilityAttributeMapping.module.scss
  (groups/mappers tables, source chips, index badge, error/footer).
- Convert all listing components from global BEM classNames to
  styles.* module access; drop dead/style-less classes (am-table,
  am-row-actions, am-add-row, *_edited, mappers-table__error).
- Adopt theme-aware semantic tokens (--l2/l3-*, --accent-primary,
  --callout-error-*) in place of --bg-* primitives.

* chore: migrate tanstack table

* chore: remove comment

* fix: disable isDirty in case of llm pricing

* refactor: number

* feat: add search , dropdown and flag

* feat: feature flag on entire route and add mode costs tabs

* fix: add isFetchingFeatureFlags

* chore: update flag

* refactor: shell

* fix: add key to route

* feat: add flags

* chore: additional refactor

* chore: add commet in utis

* chore: self review changes

* refactor: types and other things

* refactor: types and other things

* chore: add disable on source id

* empty commit

* chore: empty commit

* fix: add demo side nav on sidenav

* chore: remove demo side nav

* refactor: update routes

* chore: remove usd selector for now

* fix: layout shift

* refactor: styles

* refactor: typography component

* refactor: more changes

* refactor: typograhy

* refactor(llm-pricing): break model-cost drawer into per-component files + tokens

Apply the CSS-module/component conventions to the drawer that came from
drawer-3:
- Move the drawer under ModelCostTabPanel/components/ModelCostDrawer/ to mirror
  the ModelCostsTable structure
- Split the single 395-LOC ModelCostDrawer.module.scss into per-component
  co-located modules; cross-component selectors live in shared.module.scss and
  are pulled in via CSS-modules `composes`
- shared.module.scss is a composes target (parsed as plain CSS), so it is kept
  flat with block comments — no SCSS nesting or // comments
- Use --text-vanilla-* (not --bg-vanilla-*) for text colors, matching the
  listing code

* refactor: more changes

* refactor: styling and components

* refactor: styling and components

* chore: add a tooltip on hover

* feat: add delete confirm modal

* fix: update title

* refactor: css variables

* refactor: use signoz button and minor css update

* chore: sync table

* chore: remove extra comment

* chore: use typograpgy test in table config

* fix: minior issues

* fix: llm pricing listing

* refactor: remove extra classes

* refactor: side nav changes

* fix: update missing styles

* chore: update edit and delete options

* chore: remove extra comment

* chore: revert env changes

* chore: add enable check

* chore: remove divider

* refactor: use delete confirm dialog

* chore: remove scss file

* feat: move ui to easily accessable tabs

* feat: update test cases

* chore: update text

* chore: self review changes

* chore: self review refactor

* chore: self review changes

* chore: remove worktree

* chore: revert env.ts

* chore: add attribute mapping foundation

* chore: update ui and add animation

* refactor: components update

* chore: typography changes

* chore: typography changes

* chore: use badge

* refactor: basic components

* chore: remove hardcoded value

* chore: add comments & tests

* chore: update env.ts

* chore: update tests

* chore: self review changes

* chore: update test cases

* chore: remove extra comments

* refactor(llm-pricing): share toast copy via constants

* chore: use constants

* chore: redclared constants

* chore: update test cases

* chore: remove unused component

* chore: update types

* chore: update ui

* refactor: minor things

* chore: break down thingsinto comps

* chore: update files

* fix: update mapping

* chore: remove draft logic no need for now

* chore: more refactor

* chore: remove comments

* chore: refactor route

* chore: update query refech on mount

* chore: update skeleton

* refactor: code

* refactor: code

* refactor: eslint disable

* chore: update selector

* chore: sort

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-13 09:48:51 +00:00
Abhi kumar
3e971a902a fix(dashboard-v2): carry unsaved panel edits into view mode (#12049)
* fix(dashboard-v2): carry unsaved panel edits into view mode

Switching from the panel editor to View Mode dropped un-saved config edits
(thresholds, units, columns, legend, formatting, axes) — the View modal
re-seeded from the saved panel spec, carrying only the live query.

Hand the live draft spec off via a tab-scoped sessionStorage handoff,
correlated to the panel by dashboardId + panelId. The query stays in the URL
(compositeQuery) so the query builder hydrates; the rest of the spec rides in
sessionStorage so the edits survive a refresh without bloating the URL. The
handoff is cleared on plain View, grid drilldown, and close so it can't seed
a stale view.

* fix(dashboard-v2): hide 'Switch to Edit Mode' without edit permission

The View panel modal is reachable by read-only users, so gate the
Switch to Edit Mode button on canEditDashboard && !isLocked, mirroring
how the panel actions menu gates the Edit panel item.

* feat(dashboard-v2): track panel view/edit mode switch events

Add DashboardEvents enum and log SWITCH_TO_EDIT_MODE (View modal) and
SWITCH_TO_VIEW_MODE (panel editor) when the user toggles between the
two panel modes.

* fix(dashboard-v2): bound query cacheTime to 0 under auto-refresh

Under auto-refresh each cycle mints a fresh time-keyed query, so unused
entries accumulate and can OOM the tab. Drop cacheTime to 0 when
auto-refresh is enabled (V1 parity) for panel queries and the query/
dynamic variable selectors; keep DASHBOARD_CACHE_TIME otherwise.
2026-07-13 09:27:40 +00:00
Srikanth Chekuri
e0a0f49fb4 fix(alerts): surface individual validation errors in API response (#11756)
* fix(alerts): surface individual validation errors in API response

* chore: address lint
2026-07-13 09:23:28 +00:00
Shivam Gupta
03abb3ca90 fix: update stale docs links in backend and remaining frontend (#12096)
Repairs 10 broken signoz.io/docs links (5 hard 404s + 5 dead anchors)
that survived the frontend-only sweep in #11319 because they live in
the Go backend and two frontend files it did not cover.

- infra-monitoring readiness checks: drop the removed `user-guides/`
  path segment and remap to the current hostmetrics/k8s-metrics anchors
- querybuilder / telemetrylogs search-troubleshooting errors: point to
  the reworded Q&A anchors (update matching test assertion)
- alert generatorURL fallback: `alerts-management/#generator-url` ->
  `alerts/` (anchor removed in docs restructure)
- missing-spans banner: -> traces-management troubleshooting FAQ anchor
- agent-skills install link: `#installation` -> `#install-the-plugin`

Every changed URL verified live (200 + anchor present).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 08:49:31 +00:00
Aditya Singh
e4f9daf7d2 feat(qb): add time_series export support + data-export foundation for other format supports (#12025)
* feat: rename existing export logic to follow the new export data structure

* feat(data-export): add time_series serializer

Pure serializer that walks the V5 time_series tree (results → aggregations → series) into a format-agnostic SerializedTable — tidy layout, one row per (series, timestamp), labels as columns, raw values, y-axis unit in the value header. Series names match the chart legend (getLabelName + getLegend resolve legend templates and aggregation aliases/expressions from the builder query).

* feat(data-export): add csv/jsonl formatters and timestamped client download

toCsv/toJsonl turn a SerializedTable into CSV or newline-delimited JSON; downloadFile triggers a client-side blob download with a timestamped filename (base-YYYY-MM-DD_HH-mm-ss.ext) so repeated exports never collide and record when they were taken.

* feat(data-export): add useClientExport dispatch hook

Frontend-driven export hook: narrows a V5 queryRange response by request type, serializes time_series (scalar lands with the next sub-issue), formats as csv/jsonl and downloads. Takes the builder query for chart-parity series naming. Backend-driven export stays in useServerExport.

* test(data-export): assert timestamped filenames via the naming helper

Review feedback: the filename-format regexes duplicated the format spec across tests. The hook tests now freeze the clock and assert delegation to getTimestampedFileName; the format itself stays pinned by the single exact-string test beside the function.

* feat: comment update

* feat: use exsiting request type
2026-07-13 08:05:27 +00:00
Vinicius Lourenço
d1a06a91bf test(service-account): mock motion lib & change drawer open/close detection (#12077)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* test(service-account): mock motion lib & change drawer open/close detection

* test(serviceaccount): remove getByRole & use wait for instead of waitForElementToBeRemoved
2026-07-13 06:03:15 +00:00
Naman Verma
cede9ffc4c fix: make span gaps accept day and week as units (#12065)
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
* fix: make span gaps accept day and week as units

* fix: only check for fill less than based on fill only below flag
2026-07-11 09:04:00 +00:00
Naman Verma
4fe311cb0e feat: add functional unique index (#11307)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat: add functional unique index

* chore: add tag migration

* chore: add failing scratch test (to discuss)

* chore: fetch expressions as well in getindices call

* fix: remove tag unique index (will be added in a separate PR)

* fix: remove tag unique index (will be added in a separate PR)

* chore: remove temporary tests

* fix: go lint fix

* chore: better comment for unique index

* test: add test for case insensitive expression equality

* test: add equality test for columns with quotes and capital letters

* chore: add separate type for unique indices with expressions

* test: add test for postgres provider
2026-07-10 19:10:10 +00:00
Naman Verma
66f4a63978 fix: don't return error in v2 list dashboard api if there is a v1 dashboard (#12020)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix: don't return error in v2 list dashboard api if there is a v1 dashboard

* chore: generate api specs

* feat(dashboard-v2): surface legacy dashboards in the v2 list (#12024)

* feat(dashboard-v2): add legacy dashboard dialog

Surfaces a copyable dashboard ID and a Contact Support action for a
pre-v2 (legacy) dashboard that has no v2 spec to render.

* feat(dashboard-v2): hide v2-only actions for legacy dashboards

A legacy dashboard has no v2 spec, so view/open/copy-link/rename/
duplicate/lock don't apply. Gate them behind !isLegacy, leaving only
Delete (and dropping its now-orphan leading divider).

* feat(dashboard-v2): surface legacy dashboards in the v2 list

Flag legacy rows with a badge, block navigation, and open the legacy
dialog on click instead. Disable the pin action with an explanatory
tooltip and gate the row's actions menu to legacy-safe items.

---------

Co-authored-by: Ashwin Bhatkal <ashwin96@gmail.com>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
2026-07-10 14:41:30 +00:00
Vinicius Lourenço
7d29a22e32 feat(infra-monitoring): use v2 APIs (#12036)
* feat(query-v2): add metricNamespace prop

* feat(tanstack): add way to modify header padding

* feat(infra-monitoring): add new components for v2 refactor

* refactor(infra-monitoring): add docs prop for entity group header

* refactor(infra-monitoring): remove old props of empty state

* refactor(infra-monitoring): use column header to show on filter side panel

* refactor(infra-monitoring): update header to use new v2 components

* refactor(infra-monitoring): update utils and types

* refactor(infra-monitoring): update k8s base list to accept v2 apis

* refactor(infra-monitoring): update k8s base details to v2 apis

* refactor(infra-monitoring): couple fixes and refactors on components

* refactor(infra-monitoring): migrate hosts to v2

* refactor(infra-monitoring): migrate clusters to v2

* refactor(infra-monitoring): migrate daemon sets to v2

* refactor(infra-monitoring): migrate deployments to v2

* refactor(infra-monitoring): migrate jobs to v2

* refactor(infra-monitoring): migrate namespaces to v2

* refactor(infra-monitoring): migrate nodes to v2

* refactor(infra-monitoring): migrate pods to v2

* refactor(infra-monitoring): migrate statefulsets to v2

* refactor(infra-monitoring): migrate volumes to v2

* refactor(infra-monitoring): cleanup on entity details

* refactor(infra-monitoring): refactor infra monitoring to use v2

* refactor(infra-monitoring): date time border with better contrast

* chore(infra-monitoring): remove todo, placeholders are valid

* fix(pr): address comments

---------

Co-authored-by: Nikhil Mantri <nikhil.mantri1999@gmail.com>
2026-07-10 14:39:46 +00:00
Nikhil Mantri
1e257a5b26 feat(infra-monitoring): daemonsets ready and misscheduled nodes count (#12008)
* chore: types and constants added

* chore: update buildDaemonSetRecords

* chore: updated orderBy:

* chore: wired in checks API:

* chore: generated api spec:

* chore: update integration tests

* fix: checks constants updated in integration tests
2026-07-10 13:10:50 +00:00
Vinicius Lourenço
7fd6852fa6 refactor(authz): use new authz components for roles (#12011) 2026-07-10 12:19:09 +00:00
Vinicius Lourenço
b5567d1550 refactor(authz): use new authz components for service accounts (#12007) 2026-07-10 12:18:55 +00:00
Yunus M
2017660eb8 feat(quick-filters): add end-to-end tests and helper functions for qu… (#12063)
* feat(quick-filters): add end-to-end tests and helper functions for quick filters settings panel

* chore: fix formatting issues

* fix: add classname to skeleton and assert on the classname

* fix: address review comments

* chore: fix formatting issues
2026-07-10 11:54:14 +00:00
Aditya Singh
ca5d888970 feat(trace-details): restore Open in Logs Explorer in span details Logs tab (#11941)
* feat(trace-details): add Open in Logs Explorer to span details Logs tab

Restores the Open in Logs Explorer action (removed with V2 in #11805): a
toolbar button above the log list and an inline action in the no-trace-logs
empty state. Also tightens the empty-state RESOURCES card layout (stacked,
content-width, no extra height).

* feat: add logs explorer btn in footer

* test(trace-details): cover Open in Logs Explorer footer button in span details

* test(trace-details): assert log-row click opens Logs Explorer with trace/span query

* style(trace-details): fix oxfmt formatting in SpanLogs test

* fix(trace-details): pin Open in Logs Explorer footer to the panel bottom

The footer lived inside the scrolling tab content, so it was pushed below
the fold whenever the span summary above the tabs was in view. Render it as
a sibling of the scrolling panelBody instead (Logs tab only), making it a
true fixed footer that is always visible.
2026-07-10 07:36:05 +00:00
Yunus M
76b4d249e2 chore: update package dependencies in package.json and pnpm-lock.yaml (#12066)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-10 05:56:13 +00:00
Pandey
ef892f3361 fix(ruletypes): tag rule threshold targets as format: double (#12061)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(ruletypes): tag rule threshold targets as format: double

BasicRuleThreshold.{TargetValue,RecoveryTarget} and RuleCondition.Target are
*float64 but emitted a bare 'type: number' (swaggest sets format: double only for
non-pointer floats). Bare number makes oapi-codegen clients generate float32, so a
value like 0.8 loses precision on round-trip. Tag them format:double to match
non-pointer float64 fields (e.g. MetrictypesComparisonSpaceAggregationParam).

* chore(frontend): regenerate API client for rule threshold format: double

Reflects the format: double schema change on the rule threshold/condition
targets in the orval-generated client (oxfmt + oxlint applied).
2026-07-09 22:09:25 +00:00
Yunus M
9c4046d84a fix: revert the resizeable quick filter changes (#12058) 2026-07-09 19:00:19 +00:00
Vikrant Gupta
a91cee2b95 chore(sql): enable txlock immediate by default (#12048)
* chore(sql): enable txlock immediate by default

* chore(sql): remove the redundant flag from integration tests
2026-07-09 16:05:13 +00:00
Ashwin Bhatkal
51036d6cc4 feat(public-dashboard): integrate v2 (Perses-spec) public dashboards (#12032)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(public-dashboard): detect v1 vs v2 schema for the public viewer

Anonymous public viewers have no feature flags, so the schema can't be read from
use_dashboard_v2. Probe the v2 model endpoint first and fall back to v1 only on the
'dashboard_invalid_data' (HTTP 501) schema-mismatch signal. Probing v2 first also stops
the v1 endpoint from serving v2 dashboards with un-redacted queries.

* feat(public-dashboard): fetch v2 public panel data by key

Adds a by-key fetcher over the anonymous /api/v2/public/dashboards/{id}/panels/{key}/query_range
endpoint (the generated client omits the startTime/endTime params) and a store-free
usePublicPanelQuery that mirrors usePanelQuery's PanelQueryData shape. No variables and no
pagination — the public endpoint supports neither.

* feat(public-dashboard): render v2 public dashboards read-only

Adds a read-only v2 viewer that reuses the authenticated V2 panel renderers
(PanelHeader with hideActions, PanelBody, panel registry) and the pure layoutsToSections
util, with a forked read-only grid. The public page branches on the resolved schema:
v1 keeps the existing container, v2 renders the new viewer. Dashboard variables are not
rendered — the public endpoint does not substitute them.

* feat(public-dashboard): match the standard auto-refresh control

Replace the hand-rolled 'Off' select (which was styled inconsistently and clipped its
options) with a PublicAutoRefresh that mirrors the app's DateTimeSelectionV2 refresh cluster:
a grouped refresh button + auto-refresh popover (Auto Refresh checkbox + full interval list),
portal-rendered so nothing clips. It's prop-driven — the public viewer keeps managing its own
time window — so the container now tracks enabled + interval and exposes a manual refresh.
Also nudge the header-right gap 8→12px.

* feat(public-dashboard): declare v2 query_range params, drop the wrapper, address review

Declare startTime/endTime as query params on the v2 public query_range endpoint via
RequestQuery and regenerate the OpenAPI spec + orval client, so the generated
getPublicDashboardPanelQueryRangeV2 carries them. usePublicPanelQuery now calls the
generated fetcher directly and the hand-written wrapper is removed.

Also from review: drop the defensive panelDefinition guard so an unsupported kind
surfaces loudly, use lodash noop, and trim excessive comments across the v2 files.

* fix: bind query params from PublicWidgetQueryRangeParams

---------

Co-authored-by: Naman Verma <naman.verma@signoz.io>
2026-07-09 13:27:17 +00:00
Abhi kumar
f7bfd0eba6 fix(dashboard-v2): bug bash fixes III (#12041)
* fix(dashboard-v2): scroll the saved, cloned, or added panel/section into view

Saving a panel, closing the editor, cloning a panel, or adding a section
now reveals the affected panel/section instead of leaving the dashboard
scrolled to the top. Save resolves with the persisted panel id, a small
scroll-target store hands it to the grid, and a shared
scrollIntoViewWhenReady util polls for the optimistic DOM commit.

* fix(dashboard-v2): seed the metric unit per the kind's formatting controls

Replaces useMetricYAxisUnit with useSeedMetricUnit, driven by the kind's
Formatting controls (the same source buildPluginSpec reads): kinds with a
panel-wide unit seed formatting.unit; Table, which has none, seeds each
resolved value column's formatting.columnUnits instead. Column unit
selectors now also surface the metric-unit mismatch warning. Spec
read/write goes through a shared formattingSpec util.

* fix(dashboard-v2): stop grid placement from overlapping tall panels

findFreeSlot now probes the last-row candidate against every existing
item (mirroring the backend's overlap rejection) before placing there — a
tall panel from an earlier row can reach down into the last row — and
falls back to a fresh bottom row otherwise. Move-to-section reuses the
same primitive instead of always dropping to the bottom.

* fix(dashboard-v2): carry supported config across panel type switches

Switching visualization kind used to keep only formatting and thresholds,
dropping axes entirely and resetting legend/visualization/chartAppearance
to defaults. Each section seed now carries the old spec's fields the
target kind's controls declare: axes softMin/softMax/log scale, the time
preference, stacking/fillSpans, legend position, and chart appearance.
Unsupported fields (and legend customColors, keyed by series labels the
new kind may not reproduce) are still dropped.

* fix(dashboard-v2): keep context link editor alive on undecodable URL params

A literal % in a query value (e.g. ?search=95%) is not valid
percent-encoding, so decodeURIComponent threw URIError while seeding the
edit dialog and unmounted the page. Fall back to the raw string when a
key or value fails to decode.

* fix(dashboard-v2): don't auto-run the preview when a query is added

The query-type/datasource effect re-commits the draft on any structural
builder change, so adding a query immediately refetched the preview for
a still-empty query. Track the previous datasource list and skip the
commit when the change is a pure append — the new query commits on Run
Query as usual.

* fix(dashboard-v2): bootstrap variables and edit context on the editor route

A hard refresh (or direct URL) of the full-page editor mounts without
DashboardContainer or the variables bar, so the preview fetched with
unresolved variables and the store's edit context stayed cold. The
selection seeding moves out of useVariableSelection into a standalone
useSeedVariableSelection (URL → persisted store → default, with stale
URL entries pruned), which PanelEditorPage now mounts alongside
useResolvedVariables and the edit-context seed. The ?variables= param
is carried across dashboard ↔ editor navigation (withVariablesSearch)
so the selection survives the round trip (V1 parity).

* fix(dashboard-v2): carry thresholds and units onto table columns

Switching timeseries/number → table carried thresholds with an empty
columnName, which the save API rejects (TablePanelSpec.Thresholds[]
.ColumnName is required), and dropped the panel-wide unit entirely
(Table has no formatting.unit).

The renderer's keying rule is extracted as getAggregationColumnKey
(query name, or name.expression on multi-aggregation queries), and
getTableColumnKeys derives every enabled query's value-column keys
from the spec's queries alone, before any data exists — skipping
clickhouse_sql, whose columns key by the response's SQL alias.
Carried thresholds key onto the first derivable column and are
dropped when none exists instead of blocking the save; the panel-wide
unit fans out to every value column via formatting.columnUnits. The
carry is one-way: per-column units never seed a panel-wide unit back.

* chore: pr review changes

* chore: qb sticky header in view mode fix

* chore: pr review changes

* chore: pr review changes

- Unify panel/section reveal-scroll into one useScrollIntoView(id, ref, block)
  hook backed by a single scrollTargetId store (was two hooks + two ids).
- buildPluginSpec seeds return their slice (empty {}/[] when nothing to carry)
  instead of undefined; the omit-empty decision is centralized.
2026-07-09 12:44:44 +00:00
Nikhil Mantri
da250bfd3e fix: commented out container metrics to surface k8s.pod.start_time (#12042) 2026-07-09 12:09:53 +00:00
Nikhil Mantri
67007e2902 feat(infra-monitoring): Kubernetes Container Monitoring List API (#11946)
* chore: added types for containers

* chore: added querier query and constants

* chore: added helper queries

* chore: added wiring

* chore: added open api spec

* chore: endpoint and variable rename

* chore: use recency for container status.reason as well

* chore: pass orgID to getMetadata for containers (adapt to rebased main)

* chore: add metrics to the containers list for metadata and earliest time

* chore: corrected metrics list for metadata lookup

* chore: added changes to the checks API for new kube containers section

* chore: containers query modified

* chore: added integration tests

* chore: integration tests

* chore: goroutines in container monitoring

* chore: constants deduplication

* chore: inlined requests.Post call for this PR instead of wrapping in a function
2026-07-09 11:42:24 +00:00
Ashwin Bhatkal
ff3ec133b4 fix(dashboard-v2): stop false 'updated elsewhere' prompts on your own edits (#12035)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(dashboard-v2): close the 'updated elsewhere' dialog on reload

Reload set dismissedAt to null and relied on the refetched loaded copy's updatedAt
converging with the freshness query's serverUpdatedAt to hide the prompt. Those are two
separate queries and the convergence is racy, so the dialog often stayed open across
repeated reloads until Dismiss was clicked. Make Reload acknowledge the current version
(like Dismiss) and then refetch, so it closes on click; a genuinely newer server version
still re-prompts.

* fix(dashboard-v2): only prompt when the server copy is strictly newer

The stale-check compared the loaded and freshness copies of updatedAt with !==. Your own
edits advance the loaded copy immediately (the optimistic patch writes the PATCH response's
new updatedAt into the render cache), while the freshness query only re-fetches on window
focus. So right after creating a panel, renaming, or editing a variable, loaded jumped ahead
while freshness lagged, and !== flagged your own change as 'updated elsewhere' — a false
prompt that persisted across in-app navigation until a real window-focus refetch.

Compare with a strictly-newer (>) check so the prompt only fires when the server has a
version we have not loaded. A genuine external change still trips it; our own edits (loaded
ahead of the lagging freshness copy) no longer do.

* fix(dashboard-v2): probe freshness on visibilitychange, not refetchOnWindowFocus

The freshness check used a separate react-query query with initialData + refetchOnMount:false
so the first load made no extra request. But a query that only holds seeded data and never
fetched isn't reliably eligible for react-query's focus refetch, so on tab return no request
fired and external changes went undetected.

Drop the separate query and probe the server's updatedAt explicitly on 'visibilitychange'
(guarded to the visible transition): zero requests on first load, exactly one per tab return,
no dependence on react-query focus heuristics or staleTime bookkeeping. Comparison and
reload/dismiss behaviour are unchanged (strictly-newer; reload = dismiss + refetch).

* fix(dashboard-v2): probe on window focus too, and gate stale prompt on spec content

Two fixes to the freshness probe:

- Also listen to window 'focus', not just document 'visibilitychange'. Switching to
  another app (e.g. the editor) and back keeps the browser tab 'visible', so
  visibilitychange never fires and no probe ran — the reported 'no call when coming
  back to the page'. focus covers that; visibilitychange still covers tab switches.

- Prompt only when the server's spec actually differs (deep-equal), gated by
  strictly-newer. updatedAt is bumped by metadata-only writes like lock/unlock that
  don't change what the viewer sees; keying on spec makes those a non-event without
  needing the (void) lock/unlock call to return the new updatedAt. Hook now takes the
  loaded dashboard so it has both updatedAt and spec to compare.

* docs(dashboard-v2): clarify stale-check probes on both tab switch and app focus

* docs(dashboard-v2): trim useDashboardStaleCheck comments

* fix(dashboard-v2): detect external tag and lock changes too

Widen the stale-check content comparison from spec-only to spec + tags + lock state, so an
external tag edit or lock/unlock by another user surfaces the reload prompt. Own actions still
don't trip it: the render cache advances with them (optimistic patch / cache sync), so loaded
matches server.
2026-07-09 04:32:00 +00:00
Ashwin Bhatkal
0ea5399c15 feat(dashboard-v2): bug bash fixes II (list, dashboard page, create modal) (#12040)
* fix(dashboard-v2): source Home recent dashboards from the v2 list under the flag

* fix(dashboard-v2): keep same-key:value tags from collapsing to one word in the list

* fix(dashboard-v2): commit the inline dashboard-title edit on outside click

* fix(dashboard-v2): cap variable multi-select pills so the bar doesn't overflow

* fix(dashboard-v2): persist the variables-bar expand state and show "Less" when it loads expanded

* feat(dashboard-v2): reusable dashboard image picker for details + create modal

Extract the icon/image picker into a shared DashboardImagePicker used by both the dashboard settings form and the create-dashboard modal. Patch `/image` with add (not replace) when the field is absent, and lift the inline dropdown above the create-modal form fields.

* feat(dashboard-v2): simplify the create-modal templates tab to browse-and-request

Drop the placeholder gallery (search + category list + preview) for a clean, centered browse-and-request block: link out to the published template library, and let cloud users request a template we haven't built yet.

* fix(dashboard-v2): contain Escape/Enter and pass Cmd+Enter through the tag editor

Escape/Enter no longer bubble to close the host drawer/modal; Cmd/Ctrl+Enter passes through so a host form can submit on it (plain Enter still adds/commits a tag).

* feat(dashboard-v2): add/edit a dashboard's tags from the list

Add an "Add Tags"/"Edit Tags" kebab action (labelled by whether the dashboard has tags) opening the shared key:value editor, saving via an `add /tags` patch, with Cmd/Ctrl+Enter save. Gated on edit permission, disabled while locked. Also guard row navigation so clicks inside portaled overlays (menu/modals) don't open the dashboard.
2026-07-09 04:27:43 +00:00
Abhi kumar
f7aa3cee9c fix(dashboard-v2): view-modal, pie chart, and panel fixes (#12033)
* fix(dashboard-v2): tint chart-legend checkbox with its series color

The @signozhq/ui Checkbox declares --checkbox-checked-background on the
element itself via its data-color rule, so a value set on an ancestor was
shadowed and the per-series tint never applied. Feed the color through a
private --series-color var and override the vars on the element with a
selector that out-specifies the library rule.

* fix(dashboard-v2): make antd popups usable inside the view panel modal

The editor's antd Selects/pickers portal to document.body, outside the
modal Radix dialog, where Radix disables pointer events and traps focus, so
their menus opened but couldn't be clicked. Wrap the modal body in an antd
ConfigProvider whose getPopupContainer points at the dialog content, so all
antd popups render inside the interactive, focus-trapped layer.

* feat(dashboard-v2): add the list columns editor and pagination loader to the view modal

Surface the List panel's columns editor in the View modal (as in the full
editor) by exposing setSpec from useViewPanelMode and wiring it into the
query-builder footer. Its add-column combobox portals to body, so inside
the modal it opened behind the dialog — lift its z-index above the
query-builder popups so it stacks on top.

Also thread isPreviousData into PreviewPane so the List panel's page-change
loader shows during pagination, matching the full editor and dashboard.

* fix(dashboard-v2): measure chart dimensions before first paint

useResizeObserver seeded its size to 0 and only reported real dimensions
after paint via its debounced observer, so charts rendered once at 0 then
jumped — most visibly the pie legend, which rendered left-aligned then
re-centered once it learned it fit on one row. Add a useLayoutEffect that
measures the element synchronously before paint. In jsdom clientWidth is 0,
so tests are unaffected.

* feat(dashboard-v2): support per-slice color overrides for pie charts

Enable the legend colors control for pie charts. The control is fed by
useLegendSeries, which only handled time-series data, so pie returned no
series. Resolve pie legend series from the same scalar slices the renderer
draws (without overrides, for default colors) so the color keys match what
the chart looks up.

Extract the series resolution into utils/legendSeries.ts (a shared dedupe
primitive plus a pie and a time-series resolver) and reduce the hook to a
kind switch that returns none for kinds without a colors control.

* feat(dashboard-v2): offer dashboard root and every section in the move menu

Rework the "Move to section" submenu to list the dashboard root plus every
titled section (minus the panel's own), instead of only titled sections with
a separate "move out of section" entry. Hide it entirely when there is
nowhere to move.

* fix(dashboard-v2): hide the empty panel header in editor preview

When a panel has no title, description, or status and the actions menu is
suppressed (editor preview), render nothing instead of an empty header bar.
Add a min-height so the header keeps a stable size when it does render.

* fix(dashboard-v2): lazy-load panels per-panel instead of per-section

Move the viewport intersection observer down from Section to a new
SectionGridItem wrapper so each panel gates its own fetch. A board with
many panels now only queries the ones actually on screen, instead of
loading every panel in any section that scrolls into view.

* fix(dashboard-v2): hide "Extend time range" for panels with a fixed time preference

A panel locked to a non-global timePreference queries a fixed relative span
anchored to the dashboard end, so widening the ambient window can't surface
data for it — the "Extend time range" CTA was a no-op. NoData now takes the
panel and, via panelHasFixedTimePreference, drops the global extender for such
panels (only Retry remains). The View modal's local extender still wins.

* refactor(dashboard-v2): read panel time preference via shared helper

Panel.tsx read visualization.timePreference through an inline cast; replace it
with getPanelTimePreference so the header pill and NoData's extend gate share
one reader.

* feat(dashboard-v2): support per-series legend colors for bar and histogram panels

Route BarChartPanel and HistogramPanel through the time-series legend path in
useLegendSeries and enable the Legend `colors` control in both kinds' sections,
extending the per-series color overrides to these kinds.

* feat(dashboard-v2): pin the query-type tabs to the top of the editor scroll area

Make the query-type tab nav + Run Query button sticky so they stay visible
while the query body scrolls underneath; move the top padding onto the nav so
it keeps its spacing at rest and when pinned.
2026-07-09 04:23:37 +00:00
Tushar Vats
cd8bf27da7 chore: refactor qb to lossen tight coupling of querybuilder with other modules (#11911)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-08 18:07:03 +00:00
Vinicius Lourenço
dde4a3abc7 feat(infra-monitoring): add v2 initial files (#12034)
* feat(infra-monitoring-v2): duplicate current infra monitoring code

* feat(infra-monitoring-v2): enable v2 via feature flag
2026-07-08 18:05:35 +00:00
Nikhil Mantri
1d441b63cf chore: added infraMonitoringV2 feature flag (#12031) 2026-07-08 16:59:08 +00:00
Aditya Singh
f26c8adb3b feat(trace-details): Span Details overhaul — width-driven layout, percentile & shared metadata (#11914)
* feat(trace-details): full-width span percentile panel with visible borders

* refactor(trace-details): give TraceIdField its own CSS module

* fix(trace-details): single borders for docked span details

* feat(trace-details): rework span details panel

Extract the summary into a SpanSummary component, place it by panel width
(above the tabs when narrow, inside Overview when wide), single-scroll sticky
tabs, and fix service/status-message badge overflow + truncation.

* feat(trace-details): share metadata row across header and span summary

* test: update test cases
2026-07-08 15:11:34 +00:00
Vinicius Lourenço
f5a395f229 fix(infra-monitoring-details): remove process/containers tab on hosts & better color for http status on traces (#12019)
* refactor(infra-monitoring): remove tabs for containers/processes from hosts

* fix(traces): parse http code to int instead of just render sakura color

* test(entity-details): add tests for entity traces

* fix(pr): address comments
2026-07-08 14:40:26 +00:00
Gaurav Tewari
b1dcbe87fe feat(llm-attribute-mapping): foundation — route, permission, page shell [1/5] (#11778)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(llm-pricing): add model pricing foundation (route, permission, page shell)

* feat(llm-pricing): add listing page and table

* chore(llm-pricing): drop search + source filters from list request

The list API does not honour the q (search) and source params yet, so
the controls did nothing. Remove the search input and source dropdown
along with the params we sent, and trim useModelPricingFilters to the
URL-backed page state that pagination still needs. Currency dropdown,
tabs, table and pagination are unchanged. Filters will return once the
backend supports them.

* refactor(llm-pricing): extract getRelativeTime helper in utils

Pull the relative-time formatting out of getRelativeLastSeen into a
small local getRelativeTime helper. Kept feature-local (not in the
shared utils/timeUtils) so the LLM pricing module owns its own dayjs
config; the local relativeTime extend stays for test self-sufficiency.

* refactor(llm-pricing): drop dead NaN guard in formatPricePerMillion

Pricing fields are typed as required numbers and JSON can't carry NaN,
so Number.isNaN was unreachable. Keep the null/undefined guard as API
defensiveness (toFixed on a missing value would crash the row). Also
trims the now-redundant dayjs.extend comment.

* refactor(llm-pricing): centralize constants and shared types

Extract PAGE_SIZE, PAGE_KEY, COLUMN_COUNT and CURRENCY_OPTIONS into a
new constants.ts, and move the ModelPricingFilters contract into
types.ts. Component prop interfaces stay colocated with their
components, matching the convention in the drawer PR.

* refactor(llm-pricing): use nuqs for list pagination URL state

Replace the hand-rolled useHistory + URLSearchParams plumbing in
useModelPricingFilters with nuqs useQueryState, matching the convention
used by the dashboards, alerts and k8s list pages. Behaviour is
unchanged: parseAsInteger.withDefault(1) keeps ?page=1 out of the URL
and history:'replace' avoids polluting the back-stack.

* refactor(llm-pricing): inline pagination, drop useModelPricingFilters

The hook had shrunk to a one-line nuqs wrapper after search/source were
removed, so inline the useQueryState call into the container and remove
the hook file plus the now-unused ModelPricingFilters type. When the
filters return (once the API honours them) they can move back into a
dedicated hook.

* feat(llm-pricing): disable currency selector (USD-only for now)

Only USD is priced today, so render the currency SelectSimple in a
disabled state pinned to USD. A disabled select can't fire onChange, so
the currency useState is dead — drop it (and the now-unused useState
import).

* refactor(llm-pricing): render model costs inside its tab + tab URL param

The listing was rendered outside the Tabs, so the tab was decorative.
Move all model-cost content (currency control, list query, table,
pagination, footer) into a ModelCostsTab component rendered as the
'Model costs' tab's children, and drive the active tab from a 'tab' URL
query param (nuqs). The container is now just the page shell. Unpriced
models stays a disabled placeholder for a later PR.

* style(llm-pricing): target @signozhq table slots, drop dead antd/leftover rules

The component uses @signozhq/ui Table/Tabs (Radix-based), not antd, so the
.ant-table-* and .ant-tabs-nav selectors never matched — the intended
uppercase/muted header styling wasn't applied. Retarget header/cell rules to
[data-slot='table-head'|'table-cell'] (no !important needed). Also remove dead
rules left over from the removed search/source/add UI (.filters-bar__search,
__source, __add, .page-header__actions) and the unused .source-badge--auto/
--override modifiers.

* fix(llm-pricing): constrain currency dropdown width, drop tab URL param

- Currency SelectSimple stretched to fill the filters bar; give it a fixed
  160px width (min-width couldn't cap the trigger).
- Model costs is the only enabled tab for now, so use Tabs defaultValue
  instead of a URL-backed param. Removes the nuqs tab state plus the now-unused
  TAB_KEYS/TAB_QUERY_KEY constants and TabKey type.

* chore: self review changes

* fix: add skeleton loading

* refactor: self review changes

* refactor: initial prop

* fix: update styling

* fix: add comments in utils

* feat(llm-pricing): add model cost drawer and wire into listing page

* fix(llm-pricing): restrict pricing management to admins

Align the frontend write gate with the backend, which protects the
LLM pricing create/update/delete endpoints with AdminAccess (admin
only). Previously manage_llm_pricing allowed EDITOR/AUTHOR, so those
roles saw the Add/Save affordances but their writes were rejected with
a 403. Also removes the AUTHOR entry, which could never reach the page
(the route gate excludes it).

* fix(llm-pricing): read-only drawer shows View title, hides source picker

Non-managers open the drawer in view mode (write APIs are Admin-only), so:
- the heading reads "View model cost" instead of "Edit model cost"
- the Source (auto vs. override) picker is hidden, since switching source is
  a manager-only action with nothing actionable for a viewer.

* refactor: form in edit / add modal

* chore: update color tokens

* fix: add error handling

* chore: update more self review changes

* chore: self review changes

* chore: self review changes

* fix: minor grammer thing

* fix: route thing

* refactor: migrate to css moduel

* refactor: migrate to css module

* refactor: migrate to css module

* refactor: migrate to tanstack table

* docs: clarify price precision comment

* chore: remove comment

* feat(llm-attribute-mapping): add attribute mapping foundation (route, permission, page shell)

* fix: css styling

* refactor: css module

* chore: remove comment

* fix: disable isDirty in case of llm pricing

* refactor: number

* feat: add search , dropdown and flag

* feat: feature flag on entire route and add mode costs tabs

* fix: add isFetchingFeatureFlags

* chore: update flag

* refactor: shell

* fix: add key to route

* feat: add flags

* chore: additional refactor

* chore: add commet in utis

* chore: self review changes

* refactor: types and other things

* refactor: types and other things

* chore: add disable on source id

* empty commit

* chore: empty commit

* fix: add demo side nav on sidenav

* chore: remove demo side nav

* refactor: update routes

* chore: remove usd selector for now

* fix: layout shift

* refactor: styles

* refactor: typography component

* refactor: more changes

* refactor: typograhy

* refactor(llm-pricing): break model-cost drawer into per-component files + tokens

Apply the CSS-module/component conventions to the drawer that came from
drawer-3:
- Move the drawer under ModelCostTabPanel/components/ModelCostDrawer/ to mirror
  the ModelCostsTable structure
- Split the single 395-LOC ModelCostDrawer.module.scss into per-component
  co-located modules; cross-component selectors live in shared.module.scss and
  are pulled in via CSS-modules `composes`
- shared.module.scss is a composes target (parsed as plain CSS), so it is kept
  flat with block comments — no SCSS nesting or // comments
- Use --text-vanilla-* (not --bg-vanilla-*) for text colors, matching the
  listing code

* refactor: more changes

* refactor: styling and components

* refactor: styling and components

* chore: add a tooltip on hover

* feat: add delete confirm modal

* fix: update title

* refactor: css variables

* refactor: use signoz button and minor css update

* chore: sync table

* chore: remove extra comment

* chore: use typograpgy test in table config

* fix: minior issues

* fix: llm pricing listing

* refactor: remove extra classes

* refactor: side nav changes

* fix: update missing styles

* chore: update edit and delete options

* chore: remove extra comment

* chore: revert env changes

* chore: add enable check

* chore: remove divider

* refactor: use delete confirm dialog

* chore: remove scss file

* feat: move ui to easily accessable tabs

* feat: update test cases

* chore: update text

* chore: self review changes

* chore: self review refactor

* chore: self review changes

* chore: remove worktree

* chore: revert env.ts

* chore: add attribute mapping foundation

* refactor: basic components

* chore: update env.ts

* chore: update tests

* chore: self review changes

* chore: update test cases

* chore: remove extra comments

* refactor(llm-pricing): share toast copy via constants

* chore: use constants

* chore: redclared constants

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-08 14:12:49 +00:00
Vinicius Lourenço
a36081b00c fix(query-builder): ensure contrast/border/colors are consistent (#11992)
* refactor(query-builder-v2): ensure query builder has consistent colors and allow customization

* fix(query-builder-v2-usages): ensure each place using query builder v2 has consistent colors

* fix(alert): revert l3 for v2 ui
2026-07-08 13:57:05 +00:00
Aditya Singh
48d2460c8e feat(trace-details): waterfall timeline crosshair and VQA styling fixes (#11926)
* fix(trace): remove double border at flamegraph/waterfall juncture

* fix(trace): square accordion header corners

* fix(trace-waterfall): scope span hover-card to the span-name column

* feat(trace): move missing-spans banner to header using Callout

* feat(trace): use Lucide chevrons for accordion expand icons

* fix(trace-waterfall): keep hovered rows at full opacity when dimmed

* fix(trace-waterfall): strengthen selected/hover highlight into one continuous band

* fix(trace-waterfall): soften row-action button gradient

* fix(trace-waterfall): extend span-name divider to the top of the container

* fix(trace): use neutral info icon for flamegraph sampling notice

* fix(trace): tighten timeline ruler ticks and labels

* feat(trace-waterfall): enable timeline crosshair aligned to padded ruler

* fix(trace): match crosshair badge unit to ruler ticks
2026-07-08 12:57:52 +00:00
Tushar Vats
14d9bbfce9 chore: refactor querier integration tests (#12006)
* test(querier): move querier tests into per-signal suites

Pure git renames into querier{logs,traces,metrics,scalar,common} + CI matrix;
monoliths are split in the next commit. Preserves history (git log --follow).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rt2Xi6TdBDBAc3mhYZAb9q

* test(querier): split querier monoliths into theme files

Split 01_logs/04_traces/03_metrics/06_order_by_table into theme files
(functions moved verbatim, 249 tests unchanged); scalar helper -> fixtures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rt2Xi6TdBDBAc3mhYZAb9q

* test(querier): add coverage for filter/function/aggregation gaps

hasToken + has/hasToken misuse errors, ILIKE/NOT LIKE/NOT CONTAINS,
key:number, key-not-found (logs+traces), min/max, HAVING, metric reduceTo.
hasAny/hasAll over body arrays are marked xfail: they 500 in legacy body
mode (ClickHouse type error) and work only with use_json_body on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rt2Xi6TdBDBAc3mhYZAb9q

* test(querier_json_body): add hasAny/hasAll positive coverage

Body-JSON array functions hasAny/hasAll (string + numeric arrays) succeed in
JSON-body mode (body_v2 -> ClickHouse Array via dynamicElement), complementing
the legacy-mode xfail in querierlogs/09. Verified on ClickHouse 25.12.5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rt2Xi6TdBDBAc3mhYZAb9q

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 11:09:37 +00:00
Ashwin Bhatkal
9c48d17fed fix(dashboards): render logs/traces list panels on public dashboards (#11937)
* fix(dashboards): render logs/traces list panels on public dashboards

Public list panels rendered nothing even though the query returned data:
ListPanelWrapper bails with an empty fragment when setRequestData is
undefined, and the public Panel never forwarded one.

Back requestData with state and forward the setter to WidgetGraphComponent,
mirroring the authenticated GridCard. The per-panel request builder is
extracted to utils.ts.

Fixes SigNoz/engineering-pod#3646

* fix(dashboards): hide pagination controls on public list panels

Public widget data is fetched by index and the payload redacts each
widget's limit, so LogsPanelComponent/TracesTableComponent always showed a
pager that can't page (the endpoint takes no pagination params). Thread an
optional hidePagination flag from the public Panel through
WidgetGraphComponent -> PanelWrapper -> ListPanelWrapper to both list
components; default off, so authenticated dashboards are unchanged.

* fix(dashboards): guard against missing orderBy in useLogsData

Public dashboards redact the widget query (orderBy/filter/limit are
stripped), so a LIST query can reach useLogsData with no orderBy. The
optional chain guarded listQuery but not orderBy, so listQuery?.orderBy.find
threw once the public logs panel started rendering. Guard orderBy with ?..
2026-07-08 09:23:00 +00:00
Ashwin Bhatkal
33c6cbecda feat(dashboard-v2): variables table redesign + apply dynamic variables to panels (#12009)
* feat(dashboard-v2): patch builders to apply/sync a dynamic variable's filter across panels

* feat(dashboard-v2): two-column variables table with dynamic apply-to-panels

* fix(dashboard-v2): normalize dynamic variable signal so the source field always shows

* fix(dashboard-v2): keep field-key options during search refetch (smooth typing)

* fix(dashboard-v2): center and show the default-value clear icon

* fix(dashboard-v2): keep the add-variable + on one line when the bar is collapsed

* fix(dashboard-v2): variable selection flow correctness (#12013)

* fix(dashboard-v2): correct "ALL" variable selection end-to-end

- Materialize a query/custom ALL selection to the full option array so it reaches
  the query payload (was stored as value:null → dropped); tracks option growth.
- Default a multi-select allow-ALL variable (and the __ALL__ sentinel) to ALL,
  matching V1.
- ValueSelector hands CustomMultiSelect the expanded option set when all-selected,
  so it no longer renders a literal __ALL__ row.
- Keep a still-valid multi-select subset when options re-scope (was collapsing to
  the first option).
- Fix the dead configuredDefault fallback (read defaultValue as string|string[]).

* fix(dashboard-v2): variable selector robustness

- Surface option-fetch errors with a retry in the variable bar (Query/Dynamic) —
  a first-fetch failure is no longer a silent, stuck-empty selector.
- Custom variables now auto-select their default/first option (via a CustomSelector
  that runs useAutoSelect) instead of rendering blank.

* fix(dashboard-v2): variable fetch-engine correctness

- Ignore a stale/late fetch settle for a variable no longer actively fetching
  (restores V1's active-state guard).
- Unblock a waiting query child only once ALL its parents are settled (diamond
  dependencies no longer fetch against a stale parent).
- A value change no longer refetches the changed variable's own options, and only
  a dynamic change refreshes the other dynamics (query/custom/text changes don't
  touch dynamics — they don't depend on those values).
- Enqueue cycle-dropped query variables as best-effort roots instead of leaving
  them (and any waiting dynamics) silently stuck.

* fix(dashboard-v2): variable selection edge cases

- Read the __ALL__ URL sentinel as "ALL" only for variables that support it, so a
  literal "__ALL__" value (e.g. a text variable) isn't misread.
- Prune URL selections for variables that no longer exist (rename/remove), so a
  shared link can't leak a stale value into a later variable.
- Bound option-query cache churn with a cacheTime on the query/dynamic fetches.
2026-07-08 09:14:55 +00:00
Ashwin Bhatkal
9429c9e632 feat(dashboard-v2): show empty sections & clone a section with its panels (#12023)
* fix(dashboard-v2): render a newly-created empty titled section instead of the dashboard empty state

* feat(dashboard-v2): clone a section with all its panels
2026-07-08 07:21:40 +00:00
Ashwin Bhatkal
7821961a6f feat(dashboard-v2): detect external dashboard changes on tab focus and prompt to reload (#12022) 2026-07-08 07:21:08 +00:00
Abhi kumar
08de39cdbd fix(dashboard-v2): panel drilldown fixes + New Panel modal one-click create (#12026)
* fix(dashboard-v2): disable panel drilldown for non-builder queries

Drilldown was armed whenever the panel had at least one builder query,
even for PromQL / ClickHouse panels (a mixed CompositeQuery, or the
QUERY_BUILDER fallback of deriveQueryType). Those modes carry no builder
context to refine, so the click produced an empty/invalid drilldown.

Gate enableDrillDown on getPanelQueryType(panel) === QUERY_BUILDER in
addition to the existing capability + builder-query-count checks.

* fix(dashboard-v2): hide "Click to drilldown" hint when drilldown is disarmed

TooltipFooter's canDrilldown defaults to true, and the time-series / bar
renderers never passed it — so the hint showed even in the panel editor
preview (where drilldown is off) and for non-builder query types. Passing
the prop as-is wasn't enough: enableDrillDown is undefined in edit mode, and
canDrilldown={undefined} falls back to the true default.

Pass canDrilldown={!!enableDrillDown} (coerced) and add enableDrillDown to
the useCallback deps (also fixes a stale-closure in the bar renderer). The
hint now shows only when a click will actually open the drilldown menu.

* fix(dashboard-v2): make pie panel drilldown fire

preparePieData built slices with only label/value/color, never the
queryName and labels that enrichPieClick needs. Every slice therefore had
queryName === undefined, so enrichPieClick hit isValidQueryName('') and
returned null — the slice click was a silent no-op and pie drilldown never
worked.

Carry the value column's queryName and the row's group-by key→value labels
(keyed by field name) onto each slice, mirroring how enrichTableClick reads
them off the shared PanelTable shape. Adds regression tests for both.

* fix(dashboard-v2): one-click panel create when the dashboard has one section

The New Panel modal always used a select-then-confirm flow with a footer
section picker. When the dashboard has a single section there is nothing to
pick, so the footer degraded to a lone confirm button and the extra click
was pointless.

Hide the footer entirely for the single-section case and create the panel
directly on tile click; keep select-then-confirm when multiple sections
exist. The section-picker guard moves up to the modal so the footer renders
only when a picker is actually needed.
2026-07-08 07:19:32 +00:00
dependabot[bot]
98178795ec chore(deps): bump golang.org/x/crypto from 0.49.0 to 0.52.0 (#12012)
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.49.0 to 0.52.0.
- [Commits](https://github.com/golang/crypto/compare/v0.49.0...v0.52.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.52.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 06:42:13 +00:00
Ashwin Bhatkal
0797b26cb2 feat(dashboard-v2): variable editor form, add-variable UX & styling (#11942)
* fix(dashboard-v2): cap the variable preview-values box height

The 'Preview of Values' box only had a min-height, so a field with many values
grew the box tall. Add a max-height so it scrolls instead.

* feat(dashboard-v2): restore the V1 combined field/source row for dynamic variables

Replace the separate Source and Attribute rows with the single V1-style row:
the telemetry field on the left, then "from" and the source select on the right.

* feat(dashboard-v2): add-variable button in the variables bar

Add a dashed outlined 'Add variable' button on the left of the variables bar
(shown for editors even with no variables). It deep-links into the settings
drawer at the Variables tab with the add-variable form open, via a transient
settingsRequest store slice; the drawer destroys on close so it re-initializes
cleanly each open.

* feat(dashboard-v2): collapse the add-variable button once variables exist

Full labelled button when there are no variables; once some exist it shrinks to
a + icon (label on hover) placed after the collapsed +N. Dashed l3 border.

* style(dashboard-v2): use the l3 border on toolbar buttons and the empty state

Give Actions/Configure/Edit-as-JSON and the dashboard empty-state dashed border
the more visible --l3-border.

* fix(dashboard-v2): keep add-variable button out of collapsed bar + flat toolbar borders

- Move the add-variable + icon inside the strip and only show it when the bar
  isn't collapsed (no overflow) or is expanded, so it never breaks the layout
  mid-wrap; expand to reveal it.
- Make the Actions/Configure/Edit-as-JSON border a flat l3 outline with no
  box-shadow/depth.

* feat(dashboard-v2): raise dynamic-variable attribute search debounce to 500ms

* feat(dashboard-v2): add a Configure step to the dashboard empty state

* fix(dashboard-v2): flow the variables bar under the time selector + reposition add button

Revert the bar wrapper to block so the strip wraps around the floated time
selector (one line beside it collapsed; full-width below it when expanded) — a
flex wrapper had made it a BFC that trapped the rows on the left. The add-variable
"+" now sits after the +N/Less trigger, kept inline and always mounted so the
overflow measurement no longer toggles it (which caused a layout shift), with the
collapse math reserving space for it.

* feat(dashboard-v2): hide dashboard chrome in full screen

Show only the sections and panels in full screen — the header and toolbar
(actions, variables bar, time selector) are hidden for a clean presentation
view; exit with Esc. Also drops a stray blank line that failed the format check.

* refactor(dashboard-v2): extract add-variable buttons into components
2026-07-08 06:37:40 +00:00
Vinicius Lourenço
f8846026fb fix(authz-devtools): drop global listener for modal keyboard (#12018)
Co-authored-by: Yunus M <myounis.ar@live.com>
2026-07-08 06:31:25 +00:00
dependabot[bot]
5ec6560613 chore(deps): bump starlette from 1.0.0 to 1.3.1 in /tests (#11737)
Bumps [starlette](https://github.com/Kludex/starlette) from 1.0.0 to 1.3.1.
- [Release notes](https://github.com/Kludex/starlette/releases)
- [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md)
- [Commits](https://github.com/Kludex/starlette/compare/1.0.0...1.3.1)

---
updated-dependencies:
- dependency-name: starlette
  dependency-version: 1.3.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 05:30:13 +00:00
dependabot[bot]
46e092b2c9 chore(deps): bump cryptography from 46.0.7 to 48.0.1 in /tests (#11736)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Bumps [cryptography](https://github.com/pyca/cryptography) from 46.0.7 to 48.0.1.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/46.0.7...48.0.1)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-version: 48.0.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-08 05:24:02 +00:00
Ashwin Bhatkal
fe660e27a2 feat(dashboard-v2): gate list-page edit actions on edit permission (#12021) 2026-07-08 05:13:03 +00:00
Ashwin Bhatkal
465620fbbb feat(dashboard-v2): enforce read-only behavior when a dashboard is locked (#12017)
* feat(dashboard-v2): lock-aware edit context, mutation guard, tooltip primitives & locked indicator, skip chart refetch on lock toggle

* feat(dashboard-v2): hide toolbar edit actions (incl. clone) in view mode, disable with a hover reason when locked

* feat(dashboard-v2): hide panel & section edit actions in view mode, disable when locked

* feat(dashboard-v2): open the JSON editor read-only when not editable

* feat(dashboard-v2): disable panel editor save when not editable
2026-07-08 05:12:31 +00:00
Aditya Singh
db2e29dde9 feat(trace-details): Pretty View interaction polish (hover, search, actions, z-index) (#11940)
* feat(trace-details): restyle Pretty View attributes search bar

* feat(trace-details): full-width row hover in Pretty View

* feat(trace-details): keep Pretty View row active and brighten value on hover/menu-open

* feat(trace-details): move parent-row ellipsis to the right edge

* fix(cmdk): raise command palette above the floating span-details panel

* feat: use toggle group for data viewer instead of dropdown

* fix(trace-details): disable Monaco sticky scroll in JSON view to stop overlap
2026-07-08 04:55:24 +00:00
Ashwin Bhatkal
cec72e25fd feat(dashboard-v2): link variables to panels (#12003)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(dashboard-v2): scope panel refetch to referenced variables

A panel now refetches only when a variable its queries reference changes (the cache key is scoped to referenced variables; the full payload is still substituted), and stays in its loading state on first load until those variables resolve.

* feat(dashboard-v2): surface dashboard variables in query builder suggestions

Publish the dashboard's variables into the shared store the query builder autocomplete reads, so $variable suggestions appear in the dashboards-page builder and the panel editor.
2026-07-07 20:01:15 +00:00
Abhi kumar
82c833044d feat(dashboard-v2): extend time window from empty panel state (#11999)
* feat(dashboard-v2): add extend-time-window logic for empty panels

Add the empty-state "extend the time window" building block: useExtendTimeWindow
widens the dashboard's global time via the shared zoom-out ladder (getNextZoomOutRange
/ useZoomOut), and extendWindow.ts exposes the ExtendTimeWindow type plus a thin
buildExtendWindow adapter over the ladder result.

* feat(dashboard-v2): add view-session store slice for the modal extender

The View modal owns a local time window; add a transient dashboard-store
slice so it can publish its extend-window behaviour for the deeply-nested
NoData empty state to read, instead of threading it through every renderer.

* feat(dashboard-v2): offer an extend-window action in the panel no-data state

A panel with no data in the selected window showed only a Retry, which can't
help when the query succeeded and there's just nothing in range. Add an
"Extend time range" action that widens the window (global time on the
grid/editor; the View modal's local window in place, read from the store),
shown alongside the retained Retry.

Also fix the stale empty state: keepPreviousData retained the empty response so
NoData lingered through a refetch then snapped to the chart — a refetch over
empty data now shows the shared PanelLoader instead.

PanelMessage gains a secondaryAction so the empty state can render both buttons;
refetch stays on the renderer contract to drive Retry (standalone call sites
like the editor preview may still omit it, showing Extend only).

* chore: pr review fixes

* chore: pr review changes

* chore: pr review changes
2026-07-07 19:06:38 +00:00
Ashwin Bhatkal
f98b8bb1fd feat(dashboard-v2): runtime variable fetch engine & selectors (#12002)
* feat(dashboard-v2): add runtime variable fetch-state engine

Port V1's variable fetch orchestration natively onto the dashboard store: a fetch-state slice (idle/loading/revalidating/waiting/error + per-variable cycle ids) plus the dependency context derivation (query/dynamic order) needed to schedule fetches. Query variables load in dependency order; dynamics wait for query values. enqueueFetchAll drives first load/time change, enqueueDescendants drives a single value change.

* feat(dashboard-v2): drive variable selectors off the fetch engine

Gate the Query/Dynamic option fetches on the engine's per-variable state and key them by cycle id (so a parent change refetches only its dependents, in order, with no duplicate calls), and report completion/failure back. Wire the selection lifecycle: full fetch cycle on load/time change, descendant cascade on value change.

* fix(dashboard-v2): read a variable's default value as string, not { value }

defaultValue is a string | string[] on the wire, but the editor and runtime read
it as { value }, so a saved default showed blank in the form (and couldn't be
cleared) and never auto-applied. Read it directly in all three sites.

* feat(dashboard-v2): show hidden variable values on the collapsed +N hover

When the variables bar collapses the overflow behind +N, hovering it now lists
the hidden variables and their current selected values.

* feat(dashboard-v2): batch initial variable auto-selections into one fetch

Auto-selection now flows through a dedicated onAutoSelect path, separate from
user changes. The initial load burst of fills (each selector picks a value as
its options resolve, at different times) is coalesced across one animation frame
into a single store write plus one enqueueDescendantsBatch, so dependent
variables re-fetch once with the settled parent values instead of once per fill.

* refactor(dashboard-v2): use enum for VariableFetchState
2026-07-07 19:01:32 +00:00
Ashwin Bhatkal
2114fbddfe feat(dashboard-v2): enforce name-length limits on dashboard inputs (#12015)
* feat(dashboard-v2): cap dashboard, section, panel and variable name inputs at 128 chars

* feat(dashboard-v2): cap saved-view names at 64 chars
2026-07-07 18:51:20 +00:00
Yunus M
b2214cf5a3 feat: implement resizable quick filters across multiple components with persistent width settings (#12014) 2026-07-07 18:10:39 +00:00
Abhi kumar
db4219e0f1 feat(dashboards-v2): download panel as PNG/SVG/CSV (#11803)
* chore(dashboards-v2): add html-to-image for panel image export

Dependency used to capture a panel's rendered DOM node as PNG/SVG.

* feat(dashboards-v2): declare per-kind download capability

Adds the DownloadFormat enum and a per-kind `actions.download` map. Tables allow CSV/PNG/SVG, charts PNG/SVG; CSV is table-only (V1 parity).

* feat(dashboards-v2): capture a panel as a PNG/SVG image

downloadElementAsImage captures the panel's rendered node via html-to-image (dropping the hover chrome); useDownloadPanelImage locates it by its data-panel-root marker and surfaces failures as a toast. toSafeFileName sanitizes the filename.

* feat(dashboards-v2): export table panel data as CSV

getTableCsvRows flattens the prepared scalar table (reusing the on-screen cell formatting) into rows, and downloadCsv serializes them via papaparse.

* feat(dashboards-v2): add the Download action to the panel menu

useDownloadPanelMenuItem composes the submenu, dispatching CSV to the query response (useDownloadPanelCsv) and PNG/SVG to the DOM capture; the response is threaded to the menu via props. buildDownloadMenuItem renders the format options; usePanelActionItems consumes the ready item.

* chore: pr review fixes
2026-07-07 16:23:22 +00:00
Gaurav Tewari
165c945511 feat(frontend): LLM pricing UI update and tests [5/6] (#11910)
* feat(llm-pricing): add model pricing foundation (route, permission, page shell)

* feat(llm-pricing): add listing page and table

* chore(llm-pricing): drop search + source filters from list request

The list API does not honour the q (search) and source params yet, so
the controls did nothing. Remove the search input and source dropdown
along with the params we sent, and trim useModelPricingFilters to the
URL-backed page state that pagination still needs. Currency dropdown,
tabs, table and pagination are unchanged. Filters will return once the
backend supports them.

* refactor(llm-pricing): extract getRelativeTime helper in utils

Pull the relative-time formatting out of getRelativeLastSeen into a
small local getRelativeTime helper. Kept feature-local (not in the
shared utils/timeUtils) so the LLM pricing module owns its own dayjs
config; the local relativeTime extend stays for test self-sufficiency.

* refactor(llm-pricing): drop dead NaN guard in formatPricePerMillion

Pricing fields are typed as required numbers and JSON can't carry NaN,
so Number.isNaN was unreachable. Keep the null/undefined guard as API
defensiveness (toFixed on a missing value would crash the row). Also
trims the now-redundant dayjs.extend comment.

* refactor(llm-pricing): centralize constants and shared types

Extract PAGE_SIZE, PAGE_KEY, COLUMN_COUNT and CURRENCY_OPTIONS into a
new constants.ts, and move the ModelPricingFilters contract into
types.ts. Component prop interfaces stay colocated with their
components, matching the convention in the drawer PR.

* refactor(llm-pricing): use nuqs for list pagination URL state

Replace the hand-rolled useHistory + URLSearchParams plumbing in
useModelPricingFilters with nuqs useQueryState, matching the convention
used by the dashboards, alerts and k8s list pages. Behaviour is
unchanged: parseAsInteger.withDefault(1) keeps ?page=1 out of the URL
and history:'replace' avoids polluting the back-stack.

* refactor(llm-pricing): inline pagination, drop useModelPricingFilters

The hook had shrunk to a one-line nuqs wrapper after search/source were
removed, so inline the useQueryState call into the container and remove
the hook file plus the now-unused ModelPricingFilters type. When the
filters return (once the API honours them) they can move back into a
dedicated hook.

* feat(llm-pricing): disable currency selector (USD-only for now)

Only USD is priced today, so render the currency SelectSimple in a
disabled state pinned to USD. A disabled select can't fire onChange, so
the currency useState is dead — drop it (and the now-unused useState
import).

* refactor(llm-pricing): render model costs inside its tab + tab URL param

The listing was rendered outside the Tabs, so the tab was decorative.
Move all model-cost content (currency control, list query, table,
pagination, footer) into a ModelCostsTab component rendered as the
'Model costs' tab's children, and drive the active tab from a 'tab' URL
query param (nuqs). The container is now just the page shell. Unpriced
models stays a disabled placeholder for a later PR.

* style(llm-pricing): target @signozhq table slots, drop dead antd/leftover rules

The component uses @signozhq/ui Table/Tabs (Radix-based), not antd, so the
.ant-table-* and .ant-tabs-nav selectors never matched — the intended
uppercase/muted header styling wasn't applied. Retarget header/cell rules to
[data-slot='table-head'|'table-cell'] (no !important needed). Also remove dead
rules left over from the removed search/source/add UI (.filters-bar__search,
__source, __add, .page-header__actions) and the unused .source-badge--auto/
--override modifiers.

* fix(llm-pricing): constrain currency dropdown width, drop tab URL param

- Currency SelectSimple stretched to fill the filters bar; give it a fixed
  160px width (min-width couldn't cap the trigger).
- Model costs is the only enabled tab for now, so use Tabs defaultValue
  instead of a URL-backed param. Removes the nuqs tab state plus the now-unused
  TAB_KEYS/TAB_QUERY_KEY constants and TabKey type.

* chore: self review changes

* fix: add skeleton loading

* refactor: self review changes

* refactor: initial prop

* fix: update styling

* fix: add comments in utils

* feat(llm-pricing): add model cost drawer and wire into listing page

* fix(llm-pricing): restrict pricing management to admins

Align the frontend write gate with the backend, which protects the
LLM pricing create/update/delete endpoints with AdminAccess (admin
only). Previously manage_llm_pricing allowed EDITOR/AUTHOR, so those
roles saw the Add/Save affordances but their writes were rejected with
a 403. Also removes the AUTHOR entry, which could never reach the page
(the route gate excludes it).

* fix(llm-pricing): read-only drawer shows View title, hides source picker

Non-managers open the drawer in view mode (write APIs are Admin-only), so:
- the heading reads "View model cost" instead of "Edit model cost"
- the Source (auto vs. override) picker is hidden, since switching source is
  a manager-only action with nothing actionable for a viewer.

* refactor: form in edit / add modal

* chore: update color tokens

* fix: add error handling

* chore: update more self review changes

* chore: self review changes

* chore: self review changes

* fix: minor grammer thing

* fix: route thing

* refactor: migrate to css moduel

* refactor: migrate to css module

* refactor: migrate to css module

* refactor: migrate to tanstack table

* docs: clarify price precision comment

* chore: remove comment

* chore: remove comment

* fix: disable isDirty in case of llm pricing

* refactor: number

* feat: add search , dropdown and flag

* feat: feature flag on entire route and add mode costs tabs

* fix: add isFetchingFeatureFlags

* chore: update flag

* refactor: shell

* fix: add key to route

* feat: add flags

* chore: additional refactor

* chore: add commet in utis

* chore: self review changes

* refactor: types and other things

* refactor: types and other things

* chore: add disable on source id

* empty commit

* chore: empty commit

* fix: add demo side nav on sidenav

* chore: remove demo side nav

* refactor: update routes

* chore: remove usd selector for now

* fix: layout shift

* refactor: styles

* refactor: typography component

* refactor: more changes

* refactor: typograhy

* refactor(llm-pricing): break model-cost drawer into per-component files + tokens

Apply the CSS-module/component conventions to the drawer that came from
drawer-3:
- Move the drawer under ModelCostTabPanel/components/ModelCostDrawer/ to mirror
  the ModelCostsTable structure
- Split the single 395-LOC ModelCostDrawer.module.scss into per-component
  co-located modules; cross-component selectors live in shared.module.scss and
  are pulled in via CSS-modules `composes`
- shared.module.scss is a composes target (parsed as plain CSS), so it is kept
  flat with block comments — no SCSS nesting or // comments
- Use --text-vanilla-* (not --bg-vanilla-*) for text colors, matching the
  listing code

* refactor: more changes

* refactor: styling and components

* refactor: styling and components

* chore: add a tooltip on hover

* feat: add delete confirm modal

* fix: update title

* refactor: css variables

* refactor: use signoz button and minor css update

* chore: sync table

* chore: remove extra comment

* chore: use typograpgy test in table config

* fix: minior issues

* fix: llm pricing listing

* refactor: remove extra classes

* refactor: side nav changes

* fix: update missing styles

* chore: update edit and delete options

* chore: remove extra comment

* chore: revert env changes

* chore: add enable check

* chore: remove divider

* refactor: use delete confirm dialog

* chore: remove scss file

* feat: move ui to easily accessable tabs

* feat: update test cases

* chore: update text

* chore: self review changes

* chore: self review refactor

* chore: self review changes

* chore: remove worktree

* chore: revert env.ts

* chore: update tests

* chore: self review changes

* chore: update test cases

* chore: remove extra comments

* chore: use constants

---------

Co-authored-by: Gaurav Tewari <tewarig@users.noreply.github.com>
2026-07-07 15:05:23 +00:00
Aditya Singh
ff19aedaa8 feat(trace-details): UI polish + reusable CopyButton (#11958)
* refactor(trace-details): use ArrowRightFromLine for filter collapse icon

* refactor(trace-details): square header back button with l1 border, tabular-nums trace ID

* refactor(trace-details): show events count as an l3 badge

* feat(periscope): add reusable CopyButton with copy-to-check animation

* refactor(trace-details): use CopyButton in DataViewer and filter query popover

* fix(traces): address PR review on CopyButton and events badge

- Remove unused onCopy prop from CopyButton; it was wired to fire
  unconditionally (even on failed clipboard writes), contradicting its
  documented "on successful copy" contract, and no caller used it. Will
  be re-added gated on success when actually needed.
- Only render the Events tab count badge when eventsCount > 0 so spans
  with no events don't show a "0" badge.

* style(traces): tokenize events badge margin per review

Use var(--spacing-3) for the events badge margin-left instead of a raw
6px. Leave the 18px badge box and 5px padding off-grid (no matching
token; nearest values would change the single-digit circle).
2026-07-07 15:01:58 +00:00
Abhi kumar
ef8319585b feat(dashboard-v2): View-modal drill-down + editor "Switch to View Mode" (#12004)
* fix(dashboard-v2): only mark a new panel savable once it has a query

A new panel was always treated as dirty, so Save was enabled even with no
query to run. Track dirtiness off spec/query edits and require a seeded query
(List auto-seeds one; other kinds open query-less) before a new panel is
savable.

* feat(dashboard-v2): drill down from the panel View modal

Wire the shared drill-down orchestration into the View modal so filter-by-value
and breakout refine the expanded view in place (URL-persisted, re-runs the
preview) instead of opening a nested View modal. Adds an OpenDrilldownView
handoff type, an optional openDrilldownView override on useDrilldown, and the
PreviewPane onClick/enableDrillDown pass-through the modal uses. Cells and log
rows get a pointer/hover affordance for the click.

* fix(dashboard-v2): keep the dashboard spec cache patch-driven

The spec cache is kept fresh by optimistic patches, so auto-refetching flashed
the grid back to server state as observers mounted across the panel tree. Set
staleTime: Infinity + refetchOnMount: false; explicit refetch() still works.

* feat(dashboard-v2): add "Switch to View Mode" to the panel editor

Add the V1 "Switch to View Mode" button to the panel editor header. It leaves
the full-page editor for the dashboard with this panel expanded in the View
modal, seeded with the live (un-saved) query via the same expandedWidgetId +
graphType + compositeQuery URL contract the modal hydrates from. Shown for
existing panels only — a new panel isn't saved to the dashboard spec yet.
2026-07-07 14:20:00 +00:00
Abhi kumar
14ba332935 fix: ui fixes for panel selection modal (#11944)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix: ui fixes for panel selection modal

* feat(dashboards-v2): choose target section when adding a panel

Add a section picker to the New Panel modal so a panel can be placed in
any section (or the untitled root), not just the one the "Add panel"
action was triggered from. Sections are read from the cached dashboard
query via useDashboardSections (no refetch, no prop-drilling).

Picking a panel type now selects it (highlighted card) and reveals a
footer holding the section dropdown and an "Add Panel" button split
50/50; confirming shows a brief loader before navigating to the editor.
The chosen section's layoutIndex is threaded through
useCreatePanel.createPanel.

* fix(dashboards-v2): refine New Panel modal footer + section labels

- Keep the footer visible at all times; the "Add Panel" confirm is disabled
  until a panel type is selected (instead of hiding the whole footer).
- Footer layout: the section selector fills the available width and the
  confirm button takes its natural width (no more 50/50 split).
- Add a "Select panel type" label above the panel-type grid, matching the
  existing "Add panel to" label.

* chore: pr review fixes
2026-07-07 12:28:15 +00:00
Vinicius Lourenço
fda7b66d49 feat(authz): add devtools for authz (#11933)
* feat(authz): add devtools for authz

* fix(authz): add missing allowed/deniedPermissions to test mocks

* fix(pnpm-lock): keep updated

* fix(pr): address comments

* fix(pr): use our button component

* fix(pr): split modal in smaller components
2026-07-07 12:11:05 +00:00
Srikanth Chekuri
de2212e8b9 chore(querier): address impl gap in max_concurrent_queries (#11985) 2026-07-07 08:18:20 +00:00
Yunus M
ff4f18985c Feat/quick filters resizable (#11998)
* feat: add resizable quick filters panel with persistent width settings

* feat: add tooltip to checkbox value display for better user experience

* feat: add grip handle to resizable box for improved user interaction
2026-07-07 08:13:55 +00:00
Ashwin Bhatkal
7d555b643a feat(dashboard-v2): linkify URLs in dashboard description tooltip (#11996)
* feat(dashboard-v2): linkify URLs in dashboard description tooltip

Parse http(s) and www. links in the dashboard description and render
them as clickable anchors opening in a new tab. Add a reusable
linkifyText util under src/utils. Preserve author line breaks and show
the tooltip below the info icon.

* feat(dashboard): linkify URLs in V1 dashboard description

Apply the linkifyText util to the V1 dashboard description section so
pasted URLs become clickable, matching the V2 behaviour. Preserve line
breaks and wrap long URLs.
2026-07-07 06:11:34 +00:00
Ashwin Bhatkal
7839e806fd fix(dashboard-v2): warn about orphaned panels & surface JSON save errors (#11989)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(dashboard-v2): surface the real API error when a JSON save fails

updateDashboardV2 throws the raw generated error; it was passed to the error
modal cast as APIError, so a rejected save (e.g. a locked dashboard) rendered no
message. Run it through toAPIError so the actual error is shown.

* feat(dashboard-v2): warn when JSON edits desync panels and layouts

Editing the dashboard JSON can leave a panel in spec.panels that no layout
places (orphaned — renders nowhere), or a layout item referencing a panel that
no longer exists. Detect both from the draft (findPanelLayoutIssues, typed off
the spec DTO) and show a footer warning with a triangle icon; hovering lists the
exact panel ids. The tooltip sits above the drawer.

* fix(dashboard-v2): keep editor keystrokes from triggering global shortcuts

Stop keydown propagation out of the JSON drawer so Shift-selection and typing in
the editor don't fire app-level keyboard shortcuts.
2026-07-07 05:35:35 +00:00
Ashwin Bhatkal
2dcd51391d feat(dashboard-v2): rename saved views, org-wide creator filter & visible Locked-view query (#11982)
* feat(dashboard-v2): rename saved views via a shared 128-char name popover

Add a per-row rename action wired to renameView() (existing PUT endpoint), and
extract the save/rename name input into a shared ViewNamePopover capped at 128
chars (replaces SaveViewPopover). Group the rename/delete row actions so they no
longer overlap, patch the renamed view into the list cache inline instead of
refetching, and make the active-view 'Reset' restore the view's opening filters.

* feat(dashboard-v2): show locked = true in the query for the Locked view

The Locked built-in view applied its filter as an invisible server-only clause;
seed it into the search box instead so the constraint is visible and editable,
and drop the now-unused viewQuery plumbing.

* feat(dashboard-v2): source the created-by filter from the org user list

The creator filter only listed authors present on the loaded page, so a user who
hadn't authored a visible dashboard couldn't be selected. Source options from the
v2 List-users API via useCreatorOptions (page authors kept as a fallback until it
resolves), labelled with the user's display name.

* feat(dashboard-v2): show the unsaved-changes dot on the results header

Mirror the views rail's dirty indicator next to the active view name in the
results header when the current filters diverge from the view.
2026-07-07 04:42:20 +00:00
Ashwin Bhatkal
6251616d9d fix(dashboard-v2): add (not replace) description when it is empty (#11983)
A dashboard with no description has no /spec/display/description path, so a
JSON-Patch replace failed and the description update silently no-op-d. Use add
(create-or-replace) when the current description is empty.
2026-07-07 04:41:35 +00:00
Nikhil Mantri
652a9044f4 feat(infra-monitoring): goroutines wrapping custom queries for concurrency (#11981)
* chore: added types and open api spec changes

* chore: added method to calculate reason

* chore: per group pod status counts with req metric checks method added

* chore: wired up pod status counts

* chore: pod restarts type added

* chore: added restart counts for the group

* chore: bug in query fix

* chore: onboarding API changes

* chore: integration tests added

* chore: added podcountsbyphase in other entities

* chore: added pod status counts for other entities

* chore: added integration tests for other entities

* chore: added checks api changes for other entities

* chore: rearrangement

* chore: removed succeeded status and mark it as completed

* chore: query beautified

* chore: corrected metrics list for metadata lookup

* chore: removed dead constants

* chore: goroutines for ListHosts

* chore: goroutines for ListPods

* chore: goroutines for ListNodes

* chore: goroutines for ListNamespaces

* chore: goroutines for ListClusters

* chore: goroutines for ListDeployments

* chore: goroutines for ListStatefulsets

* chore: added goroutines for ListStatefulsets, ListJobs and ListDaemonsets
2026-07-07 04:39:08 +00:00
Nityananda Gohain
d4646657ca fix: initalize querier in llmpricing (#11993) 2026-07-07 04:04:29 +00:00
Nikhil Mantri
29681572db feat(infra-monitoring): pod status and restart counts. (#11885)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore: added types and open api spec changes

* chore: added method to calculate reason

* chore: per group pod status counts with req metric checks method added

* chore: wired up pod status counts

* chore: pod restarts type added

* chore: added restart counts for the group

* chore: bug in query fix

* chore: onboarding API changes

* chore: integration tests added

* chore: added podcountsbyphase in other entities

* chore: added pod status counts for other entities

* chore: added integration tests for other entities

* chore: added checks api changes for other entities

* chore: rearrangement

* chore: removed succeeded status and mark it as completed

* chore: query beautified

* chore: corrected metrics list for metadata lookup

* chore: removed dead constants
2026-07-06 20:11:40 +00:00
Vikrant Gupta
a3fa475e88 docs: add contributing guidelines for authz (#11986)
* docs: add contributing guidelines for authz

* docs: address review comments on authz contributing guide
2026-07-06 19:08:50 +00:00
Vinicius Lourenço
64d0ada495 feat(infrastructure-monitoring): add disk usage chart for hosts (#11990) 2026-07-06 18:29:51 +00:00
Yunus M
60886fd906 fix: opening /ai-assistant opens 2 new conversations instead of one (#11923) 2026-07-06 16:58:00 +00:00
Yunus M
d8954da307 fix: context not being passed when user click suggestions in empty state (#11925) 2026-07-06 16:57:48 +00:00
Shivam Gupta
7476a2cacb feat(onboarding): add NGINX Ingress, FluxCD, Cassandra, Cloudflare Workers, PlanetScale, and Hermes Agent datasources (#11884)
* feat(onboarding): add NGINX Ingress, FluxCD, Cassandra, Cloudflare Workers, PlanetScale, and Hermes Agent datasources

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore(onboarding): optimize new datasource logo SVGs with svgo

Run svgo over cassandra.svg, fluxcd.svg, and planetscale.svg
(viewBox and <title> preserved). Trims coordinate precision and
metadata; fluxcd.svg shrinks ~24%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 15:18:54 +00:00
Vinicius Lourenço
e1dd7d52eb feat(authz): add new authz components (#11970)
* refactor(authz): drop create guarded route component

* refactor(authz): drop guarded authz component

* refactor(authz): support list of permissions on denied callout

* refactor(authz): support list of permissions on denied page

* feat(authz): add guard authz button

* feat(authz): add guard authz with page/content variants

* feat(authz): add withAuthZ HOC component to guard pages/components

* feat(authz): add docs for authz + agents update
2026-07-06 14:13:35 +00:00
Vikrant Gupta
1644e35d9c feat(authz): make serviceaccount_role and user_role first class citizens (#11977)
* feat(authz): add serviceaccount and user role handlers

* feat(authz): add support for role and service account extractors

* feat(authz): make the user apis v2

* feat(authz): return the existing service account role id
2026-07-06 13:48:46 +00:00
Abhi kumar
379331ee77 feat(dashboards-v2): panel drilldown — View in Logs/Traces (#11895)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(dashboards-v2): add the panel View-modal state and hooks

URL-driven open state (useViewPanel off expandedWidgetId, V1 parity), a per-view
time window isolated from the dashboard (useViewPanelTimeWindow), and
useViewPanelEditor which layers the drilldown reset + type-selector signal/query
type on top of the shared usePanelEditSession.

* refactor(dashboards-v2): address View-mode PR review feedback

Naming/convention:
- UsePanelEditSessionApi -> UsePanelEditSessionReturn; fullKind -> panelKind
- useViewPanelEditor -> useViewPanelMode (hook, types, file, refs, test)
- useOpenPanelEditor `state` param -> `handoffState` (view -> edit handoff)

Types tightened:
- useViewPanelMode: panelDefinition is required (registry always resolves)
- signal is required: fold the default-signal fallback into the hook so the
  query builder + type selector always get a signal; drop the now-dead
  defaultSignal from the return and the `signal ?? defaultSignal` call site.
  Behavior-preserving: only List restricts signals and it's already gated by
  query type under PromQL/ClickHouse.

Misc:
- PanelEditorPage: drop redundant optional chaining on getPanelDefinition
- ViewPanelModal: Typography.Text title with ellipsis truncation
- ViewPanelModalHeader: clearer queryType JSDoc

* feat(dashboards-v2): add panel drilldown click-enrichment utils

* feat(dashboards-v2): declare drilldown as a per-kind panel capability

* feat(dashboards-v2): open a drilldown context menu with View in Logs/Traces

* feat(dashboards-v2): substitute dashboard variables in drilldown View-in-X

Clicking View in Logs/Traces from a panel drilldown now resolves the
panel query's $var/dashboard-variable references before building the
explorer URL (V1 parity with useBaseAggregateOptions). New
useResolvedDrilldownQuery hook fires a /substitute_vars round-trip
(useReplaceVariables + buildQueryRangeRequest) when the aggregate menu
opens and the dashboard has selections, mirroring the V2-native path in
useCreateAlertFromPanel. While resolving, both actions show a spinner
and are disabled; no-variable dashboards skip the round-trip.

* refactor(dashboards-v2): address drilldown review comments

- stepClickTimeRange takes a single stepInterval (defaulted in props);
  callers do the per-query lookup from exec-stats stepIntervals
- move DrilldownAggregateMenu static inline styles into a CSS module,
  keeping only the dynamic series color inline

* feat(dashboards-v2): drill down filter-by-value into the View modal (#11959)

* feat(dashboards-v2): drill down filter-by-value into the View modal

A table group-cell click opens the filter-by-value menu (Is this / Is
not this); picking an operator adds the filter to the panel query and
opens the refined result in the View modal, persisted in the URL (V1
parity). Reuses V1's read-only getGroupContextMenuConfig; no V1 files
modified.

* refactor(dashboards-v2): type the filter-by-value ClickedData without a double-cast

Address review: build a genuinely-typed ClickedData for the group-cell
filter menu instead of an `as unknown as ClickedData` escape hatch.
getGroupContextMenuConfig reads only column.dataIndex, so column carries
just that field and record gets a minimal valid RowData.

* refactor(dashboards-v2): render the filter-by-value menu from a component

Reshape useDrilldownFilter to return data (isGroupColumnClick + onFilter)
instead of JSX, and move the operator-menu rendering into a new
DrilldownFilterMenu component wired in useDrilldown. Keeps hooks to
logic/state and rendering in components (PR review preference).

* refactor(dashboards-v2): strongly-type the drilldown popover coordinates

Replace the drilldown's use of V1's loosely-typed useCoordinates (clickedData:
any) with a V2-local useDrilldownCoordinates hook generic over the click
payload, so DrilldownContext flows through without a cast. Extract the pure
viewport-clamp math into calculatePopoverPosition with unit tests.

* feat(dashboards-v2): panel drilldown — Breakout by .. (#11896)

* feat(dashboards-v2): gate the panel editor through the capability guard

Route the panel editor's query builder and visualization type switcher through
the capability guard instead of V1's PANEL_TYPE_TO_QUERY_TYPES (now no longer
imported by any V2 file):

- PanelEditorQueryBuilder is keyed on PanelKind; its query-type tabs and
  query-builder field visibility come from the guard.
- Switching the panel kind coerces the active query type via the guard.
- The visualization type switcher disables a kind when the active query type or
  datasource is incompatible with it (e.g. List under ClickHouse/PromQL, or List
  with a metrics query). The live query type is read from the query-builder
  provider so a not-yet-staged new panel still gates correctly, and a tooltip
  explains why a type is disabled. ConfigSelect gains opt-in per-option tooltips.

* feat(dashboards-v2): create alerts from a dashboard panel

Wire the panel actions menu's "Create Alerts" item to seed a new alert
from the panel's query. `buildCreateAlertUrl` translates the panel's V5
queries into the V1 compositeQuery the alert page reads (tagged with the
panel type, v5 version and a dashboards source), and
`useCreateAlertFromPanel` opens /alerts/new in a new tab and logs the
action. Available regardless of edit access (V1 parity: create-alert
works on locked dashboards too).

To reach the query, the full panel is threaded through
Panel -> PanelHeader -> PanelActionsMenu -> usePanelActionItems instead
of just its kind; the header now derives its name/description from the
panel as well.

* refactor(dashboards-v2): ready ChartManager for the standalone view

Prep the shared graph-manager so it renders cleanly inside the View
modal: swap the legacy useNotifications save toast for the sonner toast,
and let ChartLayout grow to its content height (auto) so the manager's
legend table isn't clipped under the chart.

* feat(dashboards-v2): add the panel View modal

The View modal UI — a compact, single-host drilldown editor matching V1's
FullView: a draft preview over the per-view window, a toolbar (Reset
Query, Switch to Edit Mode, panel-type selector, time picker, refresh),
and the query-builder-only drilldown editor (no ClickHouse/PromQL tabs,
per V1). Edits are temporary — they never touch the saved dashboard.

* feat(dashboards-v2): open a drilldown context menu with View in Logs/Traces

* feat(dashboards-v2): add the Breakout by .. drilldown submenu

* chore: pr review fixes

* refactor(dashboards-v2): render the Breakout by .. menu from a component

Reshape useDrilldownBreakout to return data (queryData + onBreakout) instead
of JSX, and move the picker rendering into a new DrilldownBreakoutMenu
component (with a CSS module) wired in useDrilldown. Keeps hooks to
logic/state and rendering in components (PR review preference).

* feat(dashboards-v2): panel drilldown — context links (#11897)

* feat(dashboards-v2): resolve panel context links in the drilldown menu

* feat(dashboards-v2): panel drilldown — dashboard variables + trace link (#11964)

* feat(dashboards-v2): complete drilldown V1 parity — dashboard variables + trace link

Add the last two V1 drilldown features to V2 panels:

- Dashboard Variables submenu: from a grouped click, the aggregate menu now
  offers, per group-by field, Set/Unset a matching dynamic variable to the
  clicked value, or Create a new dynamic variable from it. Set/Unset are
  runtime-only (store + URL, matching V2 selections); Create is the one
  persisted path (appends to spec.variables via the optimistic patch).
  New Panel/hooks/useDrilldownDashboardVariables.tsx mirrors V1's
  useDashboardVarConfig; wired into useDrilldown as a new submenu.

- "View Trace Details" data link: the aggregate menu shows a /trace/{id}
  link when the clicked point carries a trace_id (V1 getDataLinks parity).
  New Panels/utils/drilldown/getDataLinks.ts.

Exports variablesUrlParser from useVariableSelection so the submenu reuses the
runtime-selection URL contract without re-running its seeding effect.

* fix(dashboards-v2): restrict drilldown filters to group-by dimensions

The pure-V5 flattening backfills an ungrouped series' labels with
{queryName: queryName} for its legend; the chart/pie enrichers turned every
label into an equality filter, leaking a bogus `A=A` into the drilldown
context. That broke the "filters are the clicked point's group-by labels,
empty when ungrouped" contract — surfacing a spurious Dashboard Variables
entry and a corrupt View-in-Logs query that V1 never shows.

Add getGroupByFilters to intersect the clicked labels with the query's
groupBy, and use it in enrichChartClick/enrichPieClick.

* refactor(dashboards-v2): dashboard-variables drilldown review fixes

Address PR review on the Dashboard Variables submenu:
- render it from a DrilldownDashboardVariablesMenu component; the hook now
  returns data (hasFieldVariables + actions) instead of JSX, taking a required
  filters array + signal (rendering belongs in the component, not the hook)
- identify dynamic variables by plugin kind on the DTO, not by mapping every
  variable to a form model first
- drop the redundant useGetDashboardV2 enabled guard (the generated hook
  already gates on !!id)
- reference the DrilldownSubMenu enum instead of a raw string
- move inline styles to a CSS module

* refactor(dashboards-v2): read drilldown variables via useDashboardFetchRequired

Use the shared useDashboardFetchRequired in useDrilldownDashboardVariables
instead of calling useGetDashboardV2 directly, so it resolves through the one
dashboard cache entry and drops the `?? []` guards. Filter dynamic variables on
the form model's `type` (via dtoToFormModel) rather than casting the raw spec.

That hook throws on a missing dashboard id, and the id was seeded into the store
in a useEffect — undefined on the first Panel render. Seed it synchronously
during render in DashboardContainer instead, and make setEditContext idempotent
so the render-phase call is a safe no-op once seeded.

* chore: fix failing lint
2026-07-06 13:18:39 +00:00
Ashwin Bhatkal
4d079a8338 refactor(dashboard-v2): unify dashboard tag chips into one TagBadge component (#11984)
* fix(dashboard-v2): render tag chips with the sienna Badge component

The key:value tag editor rendered chips as a hand-rolled div + ghost buttons with
sienna colors mixed in by hand. Use the @signozhq Badge (color=sienna, closable)
so the chips match the design system and the rest of the dashboard tag styling.

* fix(dashboard-v2): keep key:key tags intact in the settings tag editor

tagsToStrings collapsed a tag whose key equals its value down to a bare key, so
the settings tag editor showed `env` for an `env:env` tag. Always render both
sides so key:key tags round-trip through the editor unchanged.

* refactor(dashboard-v2): single TagBadge component for all dashboard tags

The list rows, details header, and tag editors each rendered tag chips their own
way (two hand-rolled sienna variants + an inline Badge), so they drifted. Extract
one TagBadge (sienna Badge, optional closable) and use it everywhere, so tag
styling changes in one place. List-row chips were not even sienna before.

* fix(dashboard-v2): tag label inherits the Badge sienna color

The chip label button used --button-variant-ghost-color: inherit, but for a CSS
custom property inherit takes the parent's value of that same variable (unset),
not the parent color — so the label fell back to the muted ghost default. Use
currentColor so it picks up the Badge's sienna foreground.
2026-07-06 13:05:23 +00:00
Vinicius Lourenço
91938925ec feat(infra-monitoring): rework the category selection (#11957) 2026-07-06 12:04:07 +00:00
Abhi kumar
e2588e6fff feat(dashboards-v2): context-link editor with variable + URL-param support (list + modal) (#11950)
* feat(dashboards-v2): add context-link variable + URL-param building blocks

Reusable primitives for the V2 context-link editor, kept separate from the
UI wiring:

- types: VariableItem / UrlParam / VariableSource
- utils: query-string <-> key/value param parsing, cursor-aware {{variable}}
  insertion, and URL validation (http(s)://, /path, or {{var}}/)
- VariablesPopover: autocomplete that lists {{variables}} grouped by source
  and inserts the picked token at the cursor
- useContextLinkVariables: self-contained hook sourcing the offered variables
  (global timestamps, per-query groupBy fields as _<key>, dashboard variables)
  from the query-builder provider + dashboard store, no prop threading

Covered by utils + hook unit tests.

* feat(dashboards-v2): rework context-link editor into a list + modal

The section is now a list of saved links (label + URL with edit/delete),
with add/edit handled in a modal (@signozhq/ui DialogWrapper) instead of the
cramped inline rows.

The modal carries V1's full authoring UX:
- label + URL with {{variable}} autocomplete and inline validation
- a key/value URL-parameters editor synced to the URL query string
- an "open in new tab" toggle; Save is gated on a non-empty, valid URL

Saved links set renderVariables so consumers interpolate the URL at
click-time. The variables popover renders with withPortal=false so it stays
inside the modal (radix's modal disables pointer events on portalled content).

* chore: pr review fixes

* refactor(dashboards-v2): split dashboard fetch into fetch-only hook + required accessor

- useDashboardFetch (renamed from useDashboardV2) now exposes only the raw
  dashboard plus fetch lifecycle; spec derivation moves out of it.
- Add useDashboardFetchRequired: reads the active dashboardId from the store,
  reuses the shared react-query cache entry, throws when the dashboard is
  missing, and derives spec collections (variables). Also exposes refetch.
- Enforce the split with a new signoz/no-dashboard-fetch-outside-root lint rule,
  allowlisted for the two root pages and the required hook.
- Point the context-link variables hook at useDashboardFetchRequired and expand
  the VariableSource JSDoc.

* chore: fixed fmt
2026-07-06 09:46:24 +00:00
Naman Verma
832a6cc794 feat: v2 versions of public dashboard APIs (#11725)
* feat: add first draft of v2 public dashboard apis

* fix: remove duplicate call to GetDashboardByPublicIDV2 in GetPublicWidgetQueryRangeV2

* fix: fill fields that were in the data blob in v1

* chore: trim comments

* fix: remove fields that v1 also removes when redacting

* chore: rename method name

* test: unit tests for GetPanelQuery

* fix: add fill gaps to query

* fix: generate api specs

* test: add integration tests for new v2 public apis

* fix: add query validation and aggregation validation

* fix: remove unneeded tags db call from public query range api

* fix: redact variable queries as well

* fix: move regex out of method so that it is only compiled once per package load

* chore: remove empty line

* fix: use pointer to specs during redaction

* fix: move single expression validation to dashboard package, use chparser for it

* test: add integration test for variable query redaction

* test: add integration test for expression with many parens

* test: use valid query in integration test

* test: use realistic query in variable
2026-07-06 09:16:42 +00:00
Abhi kumar
5948b5b970 feat(dashboards-v2): view (expand) a dashboard panel (#11882)
* refactor(dashboards-v2): extract usePanelEditSession shared editing pipeline

Pull the panel-editing pipeline (draft + query + staged-query sync + kind
switch) out of the editor container into a shared usePanelEditSession hook so the
full-page editor and the View modal share one source of truth and can't drift. A
characterization test locks the container's forwarding behaviour.

* feat(dashboards-v2): open the panel editor on a handed-off spec

Let useOpenPanelEditor carry an optional spec via router location state so the
View modal can hand its drilldown edits to the full editor; the editor page opens
on the handed-off spec when present, falling back to the saved panel on
refresh/new-tab.

* feat(dashboards-v2): render the graph-manager legend in the standalone view

The time-series and bar renderers show V1's graph-manager legend (Filter Series +
per-series show/hide + Save) below the chart in STANDALONE_VIEW, threaded through
as onCloseStandaloneView. ChartManager moves to the sonner toast, and the shared
ChartLayout only drops its fill height when it has stacked layout children
(--with-layout-children) so the dashboard grid, alert preview, and other charts
keep filling their container.

* refactor(dashboards-v2): make the editor preview and panel-type selector reusable

Prepare the editor's building blocks so the View modal can reuse them instead of
duplicating them:
- PreviewPane takes panelMode/hideHeader/dashboardPreference/onCloseStandaloneView
  so it can render the standalone preview without its own time picker.
- Extract usePanelTypeSelectItems from PanelTypeSwitcher so the modal header and
  the editor build the same capabilities-guarded panel-type options.
- The shared query builder's run button reads "Run Query" (V1 FullView parity).

* feat(dashboards-v2): add the panel View-modal state and hooks

URL-driven open state (useViewPanel off expandedWidgetId, V1 parity), a per-view
time window isolated from the dashboard (useViewPanelTimeWindow), and
useViewPanelEditor which layers the drilldown reset + type-selector signal/query
type on top of the shared usePanelEditSession.

* feat(dashboards-v2): add the panel View modal

A full-screen, temporary drilldown editor mounted once per dashboard (URL host in
the layout). It reuses the editor's PreviewPane, tabbed query builder, and
panel-type selector over the isolated per-view window, with Reset Query and Switch
to Edit Mode. Edits stay in the builder/URL and the local draft, never the saved
dashboard.

* feat(dashboards-v2): wire up the panel View action

The panel actions menu's View item opens the View modal for the panel, replacing
the placeholder.

* fix: fixed failing test

* refactor(dashboards-v2): address View-mode PR review feedback

Naming/convention:
- UsePanelEditSessionApi -> UsePanelEditSessionReturn; fullKind -> panelKind
- useViewPanelEditor -> useViewPanelMode (hook, types, file, refs, test)
- useOpenPanelEditor `state` param -> `handoffState` (view -> edit handoff)

Types tightened:
- useViewPanelMode: panelDefinition is required (registry always resolves)
- signal is required: fold the default-signal fallback into the hook so the
  query builder + type selector always get a signal; drop the now-dead
  defaultSignal from the return and the `signal ?? defaultSignal` call site.
  Behavior-preserving: only List restricts signals and it's already gated by
  query type under PromQL/ClickHouse.

Misc:
- PanelEditorPage: drop redundant optional chaining on getPanelDefinition
- ViewPanelModal: Typography.Text title with ellipsis truncation
- ViewPanelModalHeader: clearer queryType JSDoc

* refactor(dashboards-v2): make panel-type selector queryType required

queryType originates as a required EQueryType in ConfigPane (from the QB
provider) and is always defined in the View modal too, so the optional
prop + silent `?? QUERY_BUILDER` fallback on the leaf selector were just
typing artifacts. Make queryType required on PanelTypeSwitcher and
usePanelTypeSelectItems and drop the fallback. The kind-erased
SectionEditorContext stays all-optional per its invariant, so the default
now lives at the VisualizationSection boundary that consumes it.

* chore: updated dashboard page title

* feat(dashboards-v2): persist the View modal's query edits across refresh (#11945)

* feat(dashboards-v2): persist the View modal's query edits across refresh

The View modal's in-modal query builder is URL-synced (`compositeQuery`, plus
`graphType` when present), but the modal seeded its draft from the saved panel on
mount — so a page refresh discarded any in-modal edits. Seed the draft from the URL
when a query is present (else the saved panel) via a mount-only `buildViewPanelSpec`,
and clear those params on a plain open so a stale query can't bleed into the modal.
URL-backed, shareable, and refresh-safe (V1 parity).

* refactor(dashboards-v2): drop redundant queries fallback in buildViewPanelSpec

DashboardtypesPanelSpecDTO.queries is a required array, so `spec.queries ?? []`
never falls back — pass spec.queries directly. Addresses PR review feedback.
2026-07-06 09:10:48 +00:00
Nityananda Gohain
84834b087b feat: add endpoint for fetching unpriced models (#11763)
* feat: add endpoint for fetching unpriced models

* fix: more updates

* fix: response model
2026-07-06 08:50:15 +00:00
Ashwin Bhatkal
d490126162 fix(dashboard-v2): list-page bug bash fixes (#11939)
* fix(dashboard-v2): refresh the list after deleting a dashboard

Delete invalidated invalidateListDashboardsV2, but the list renders from
useListDashboardsForUserV2 (as does pin/unpin), so the deleted row lingered until
a manual reload. Invalidate the for-user list instead.

* feat(dashboard-v2): show a lock icon on locked dashboards in the list

The list rows already carry `locked`; surface it with a LockKeyhole icon (with a
tooltip) next to the row actions, mirroring the detail-page header.

* fix(dashboard-v2): show pinned icon (not unpin) until the pin is hovered

A pinned row rendered the PinOff ("unpin") icon at rest, so it read as an action
rather than a state. Show the filled Pin by default and reveal PinOff only on
hover of the pin button.

* fix(dashboard-v2): break long unbroken dashboard names in the list

The list title clamps to 3 lines but a long unbroken string could still overflow
the row horizontally; add overflow-wrap so it wraps within the clamp. (The detail
header already single-line truncates with a tooltip.)

* fix(dashboard-v2): use sienna tags in the dashboard header

The create modal and settings tag inputs already render sienna chips (matching the
list rows); the detail-page header still showed amber/warning badges. Switch them
to sienna for consistency across create, configure and display.

* fix(dashboard-v2): use a columns icon for the list columns control

The columns/metadata popover trigger used the HdmiPort icon, which doesn't read as
'columns'. Swap it for the Columns3 icon.

* fix(dashboard-v2): close the new-dashboard modal after creating

Blank/Import/Template create flows navigated to the new dashboard but left the
modal mounted, so it lingered over the detail page. Call onClose() on success
(Import/Template now take the onClose prop the modal already passes to Blank).

* feat(dashboard-v2): open the public dashboard from the header globe

The header globe now reflects the real public state (via usePublicDashboardMeta,
a deduped read) and is clickable — it opens the public dashboard page in a new
tab, with the tooltip updated to say so alongside the existing text.

* fix(dashboard-v2): embed the V1 template gallery in the new-dashboard modal

The V2 templates tab rendered a mock gallery. Until the templates BE API lands,
show the existing V1 gallery instead: extract it into DashboardTemplatesContent
(shared by the V1 modal and the V2 tab, no modal-in-modal) and embed it inline in
the V2 'From a template' tab. The V1 templates are placeholders, so the action
creates a blank dashboard and closes the modal. Drops the now-unused mock
templatesData.

* feat(dashboard-v2): click-to-unlock header lock icon + keep header icons on long names

The header lock icon is now a click-to-unlock control for author/admin (routes to
the existing lock toggle; static for others). Give it flex-shrink:0 (like the
public globe and description icons) so the description/public/lock icons and the
tag overflow stay visible when the title is long and truncates.

* feat(dashboard-v2): add Rename and Lock/Unlock to the list row actions

Rename opens a small dialog that patches /spec/display/name and refreshes the
list (shown for unlocked dashboards). Lock/Unlock toggles via lock/unlockDashboardV2
and refreshes the list, gated to author/admin on non-integration dashboards
(mirroring the detail-page gate).

* fix(dashboard-v2): list row menu — lock casing, disabled Rename tooltip, stop nav on menu click

- Capitalize 'Lock/Unlock Dashboard'.
- Show Rename disabled (not hidden) on locked dashboards with a tooltip explaining
  why (matches Delete).
- Stop clicks inside the actions menu from bubbling to the row's navigate handler
  (disabled items were opening the dashboard).

* fix(dashboard-v2): single-line row title + bottom-anchored tooltip

Truncate the list row title to a single line with an ellipsis (was a 3-line clamp),
and show the full name in a tooltip anchored to the bottom (auto-flips to top, with
an arrow) instead of the left.

* feat(dashboard-v2): session-local lock toggle in the header

The header lock control now reflects a session-local state: it appears once the
dashboard is locked (on load or during the session) and stays as a lock/unlock
toggle for the rest of the page. A dashboard that loads unlocked shows no icon
until it's locked. Clicking flips state optimistically so it no longer depends on
the refetch to update.

* fix(dashboard-v2): add top margin above the public-dashboard variables hint

* feat(dashboard-v2): run search with a Run query button + Cmd/Ctrl+Enter

Show a 'Run query' affordance with the OS-aware ⌘/Ctrl ⏎ hint in the search bar
(matching the query builder) and run the search on Cmd/Ctrl+Enter.

* fix(dashboard-v2): make the filter Clear button prominent

Use the primary (outlined) style for the Clear-filters button so it stands out
once a filter is applied.

* revert(dashboard-v2): restore multi-line clamp for list row title

Single-line truncation broke the row's responsiveness; revert to the 3-line clamp.
Keeps the bottom-anchored tooltip for long names.

* fix(dashboard-v2): show the lock tooltip on disabled Rename/Delete items

antd tooltips don't fire on disabled buttons; wrap them in a span the tooltip can
attach to so the 'dashboard is locked' reason shows on hover.

* fix(dashboard-v2): header tooltips update when moving between icons

Set disableHoverableContent on the title/description/public/lock tooltips so
leaving a trigger closes its tooltip immediately, letting the next icon's tooltip
open in both directions (was sticking when moving public → lock).

* fix(dashboard-v2): tooltip on the pin button showing the click action

Replace the native title with an antd tooltip that reads 'Pin dashboard' /
'Unpin dashboard' based on the current state.

* fix(dashboard-v2): delete dashboards via the v2 endpoint from the list

The list-page delete action was calling the v1 delete endpoint; route it through
deleteDashboardV2 so v2-shape dashboards (incl. pinned) delete correctly.

* refactor(dashboard-v2): use signoz Button/Tooltip in list row & dashboard header

Address review feedback on #11939:
- DashboardRow: swap the antd Tooltip for @signozhq TooltipSimple and the native
  pin <button> for the @signozhq Button. Only wrap long titles in a tooltip so a
  short name no longer renders an empty hanging tooltip. Rename pinBtn -> pinButton.
- DashboardInfo: swap the native public-link and lock <button>s for @signozhq Button.
- Drop the now-orphaned .titleTooltipOverlay antd override.

* fix(dashboard-v2): show a loader and block double-click when deleting a dashboard

The list-row delete confirm fired the mutation on click and closed on settle,
so a quick second click could fire delete twice. Use a promise-based onOk so the
Delete button shows a loading spinner and rejects further clicks until the request
settles, then closes.
2026-07-06 05:42:31 +00:00
Shivam Gupta
526a7d1c46 fix: update stale docs links in frontend (#11319)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix: update 47 stale docs links in frontend to current URLs

Update documentation links across 19 frontend files to match
current signoz.io docs structure after product module restructures.

Key changes:
- Instrumentation links updated to new OpenTelemetry-prefixed paths
- product-features/* links replaced with current locations
- Query builder links point to new querying module pages
- Alert notification channel links point to setup-alerts-notification
- SSO, infra monitoring, and version upgrade links corrected

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update 278 more stale docs links and broken anchors in frontend

- Onboarding md-docs: update instrumentation URLs to canonical paths
  (django/flask/fastapi/falcon → opentelemetry-python, express/nestjs →
  javascript/opentelemetry-nodejs, springboot → java/opentelemetry-java,
  tomcat → java/opentelemetry-tomcat, jboss → java/opentelemetry-jboss,
  golang → opentelemetry-golang, elixir → opentelemetry-elixir,
  reactjs → frontend-monitoring/sending-traces-with-opentelemetry)
- Onboarding md-docs: update tutorial/* → opentelemetry-collection-agents/*,
  userguide/hostmetrics → infrastructure-monitoring/hostmetrics,
  userguide/logs# → userguide/logs_query_builder#
- Query builder UI: fix broken anchors after query-builder-v5 page
  restructure (Having → result-manipulation, Order By → result-manipulation,
  Limit → result-manipulation, Legend → aggregation-grouping, Group By →
  aggregation-grouping, Formula → multi-query-analysis, Trace Matching →
  multi-query-analysis, Reduce → result-manipulation, Aggregation functions
  → aggregation-grouping, Time aggregation → temporal-aggregation)
- Fix Apdex link → alerts-management/apdex-alerts
- Fix missing spans link → traces-management/troubleshooting/faqs
- Fix cost meter, ClickHouse traces, k8s pod logs anchors
- Drop broken anchors where sections were removed from docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: format CreateAlertRule files after anchor removal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert OnboardingContainer changes (deprecated module)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Ubuntu <ubuntu@ip-172-31-24-8.eu-central-1.compute.internal>
2026-07-06 04:47:31 +00:00
Abhi kumar
9f72338c87 fix(dashboards-v2): list panel pagination, spanGaps clamp, discard dialog & create-alert fixes (#11974)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(dashboards-v2): show the list panel pager

A new/edited List panel never showed its server pager. The V1→V5 mapper
folds a list query's internal `pageSize` into the V5 `limit`
(`createBaseSpec`), so a seeded panel (pageSize 100) always looked like it
had a user limit — and `usePanelQuery` suppresses the pager when a limit is
present.

Strip the V1 explorer's `pageSize`/`offset` in `toPerses` before conversion
so `limit` reflects only a real user limit; List panels then page by default
while an explicit user limit still renders as a static, unpaged list.

* fix(dashboards-v2): give logs list requests a deterministic order

Offset paging over a non-total order can duplicate or drop rows sharing a
value (e.g. same-millisecond logs) across page boundaries. Enforce a total
order on every logs-list request (`withListOrderTiebreaker`): default the
primary to `timestamp desc` and always append `id` (logs-explorer parity).
Request-only, so it never lands in the saved panel spec; traces keep theirs.

* fix(dashboards-v2): list pagination runtime behaviour

- Drive `canNext` from the backend's `nextCursor` (set iff the page filled)
  instead of a client-side row-count guess.
- Keep the table + pager mounted on a page change (`keepPreviousData`); show
  the full-panel loader only on the first fetch, not on every refetch.
- Ignore a stale cross-type response kept across a panel-kind switch (match
  the response type to the request) so the list doesn't flash "No data".
- While the next page loads, swap the stale rows for horizontal skeleton rows
  (dashboard grid and editor preview).

* fix(dashboards-v2): seed timestamp order when switching to a list panel

V1's shared `handleQueryChange` clears orderBy when switching to a list, so
the builder's Order By opened empty after e.g. Time series → List. Re-seed
the fresh-list default (timestamp desc) in `usePanelTypeSwitch` so the query
matches a newly created list panel.

* fix(dashboards-v2): clamp time-series spanGaps to the step interval

A numeric spanGaps is a max-gap threshold (seconds). Floor it at the smallest
step interval so a sub-step value doesn't break the line at every normal
point. Boolean "span all" passes through unchanged.

* fix(dashboards-v2): flip discard-dialog buttons

"Keep editing" now sits on the right and is outlined; "Discard" stays left
(destructive). The ConfirmDialog preset can't reorder/restyle its footer, so
swap to DialogWrapper with a custom footer (same chrome, async confirm state
preserved via the button's loading flag).

* fix(dashboards-v2): floor the create-alert time window to integer ms

buildQueryRangeRequest's start/end are int64 ms, so passing a float from the
nanosecond division could break the call. Floor the ns→ms conversion and use
the named NANO_SECOND_MULTIPLIER constant instead of a magic 1e6.

* fix(dashboards-v2): clone patched values so optimistic apply can't corrupt outgoing ops

Creating the first panel on an empty dashboard failed with
"spec.layouts[0].spec.items[0] and items[1] overlap". createPanelOps
emits three ops (add empty section, add panel, add item into that
section), but useOptimisticPatch.onMutate runs applyJsonPatch before the
request is sent, and applyJsonPatch inserted each op.value by reference.
The cache's layouts[0].spec.items then aliased the empty items array held
inside the section-add op, so applying the item op mutated that op's
value too. react-query sent the mutated ops (section already holding the
item, plus the separate item add) → two overlapping items.

Clone the inserted value on add/replace so the applied document never
shares references with the input ops, restoring the purity the docstring
already promises. New-dashboard-only because that is the only batch that
adds a layout and an item into that same layout together.
2026-07-05 06:00:51 +00:00
Abhi kumar
e7ef4c6bdb fix(dashboard-v2): correct formatting carry on panel-kind switch + unify spec seeding (#11956)
* refactor(dashboard-v2): make ThresholdVariant a string enum

Replace the ThresholdVariant string-union with a string enum so panel
section configs reference named members (ThresholdVariant.LABEL/COMPARISON/
TABLE) instead of bare string literals, and update every call site.

* fix(dashboard-v2): correct formatting carry on panel-kind switch

Switching a panel's visualization kind carried formatting fields the target
kind's schema does not accept (e.g. `unit` into a Table, which only supports
`columnUnits` + `decimalPrecision`), so the save API rejected the spec.

Unify new-panel and kind-switch spec seeding into one per-section registry
(`buildPluginSpec`, SECTION_SEEDS): each section derives its plugin-spec slice
from the target kind's declared `controls` and optional context, so a carried
field is emitted only when the target kind actually supports it. Adding a
section now means one registry entry rather than editing two seeders.

Delete the redundant `buildDefaultPluginSpec` wrapper (it only forwarded to
`buildPluginSpec`); `getSwitchedPluginSpec` becomes a thin delegating wrapper.
2026-07-05 05:51:44 +00:00
Vinicius Lourenço
ef9b8eec8a perf(tsconfig): improve type check time (#11927)
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
* chore(tsconfig): explicit path mappings and cleaned includes

* perf(tsconfig): enable incremental & fix large type resolution
2026-07-03 14:29:16 +00:00
Vinicius Lourenço
94a5e568fd refactor(web-settings): move more settings to runtime & disabled by default (#11917)
Some checks failed
build-staging / js-build (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
Co-authored-by: Vikrant Gupta <vikrant@signoz.io>
2026-07-03 11:56:15 +00:00
Vinicius Lourenço
25cd3fc705 chore(authz): move components/hooks to lib (#11932) 2026-07-03 11:52:56 +00:00
Vinicius Lourenço
5c3fdb64ed feat(entity-metrics): use new uplot API for charts (#11954) 2026-07-03 11:37:35 +00:00
Vikrant Gupta
bac68a6707 fix(types): guarantee both letter cases in generated factor passwords (#11961)
password.Generate draws letters from both cases without guaranteeing
either, so roughly 1 in 1000 generated passwords contained no lowercase
letter and failed IsPasswordValid, panicking MustGenerateFactorPassword.
The existing "Z" suffix only covered the uppercase requirement; append
"zZ" to guarantee both cases while keeping the generated part mixed-case
for entropy.
2026-07-03 10:20:41 +00:00
Naman Verma
766a05e24b chore: fix issues found in bug bash (#11949)
* fix: return list of all tags sorted alphabetically

* chore: return reserved keys in list api response for easy filtering

* fix: add length limit to dashboard display name

* test: check error message as well

* chore: increase the length limits

* chore: add copy suffix on cloning dashboards

* fix: increase limit to 64 for dashboard view name

* fix: send user friendly err message on length check fail

* fix: add path to error message

* fix: include path in main error message directly

* fix: move regex out so that it only compiles once per init

* fix: format integration test properly
2026-07-03 08:10:37 +00:00
Ashwin Bhatkal
1a84503f4b feat(dashboards): add auto-refresh to public dashboards (#11938)
* feat(dashboards): add auto-refresh to public dashboards

Add a self-contained auto-refresh interval selector to the public dashboard
header, shown alongside the time picker when the publisher enabled the time
range. On each tick it recomputes the rolling window from the selected
relative range and updates local state, so panels refetch with an advanced
window. Paused/disabled for fixed 'custom' ranges.

Kept independent of Redux global time (which the public viewer doesn't use);
reuses the shared refreshIntervalOptions.

* refactor(dashboards): dedup public auto-refresh tick, use nano constant, userEvent

Route the auto-refresh interval through handleTimeChange instead of

duplicating the GetMinMax/setSelectedTimeRange logic, replace the 1e9

magic number with NANO_SECOND_MULTIPLIER, and switch the AutoRefresh

test to userEvent.
2026-07-03 06:44:35 +00:00
Ashwin Bhatkal
9454427b47 feat(dashboard-v2): JSON drawer redaction, JSON action cleanup & breadcrumb SPA nav (#11952)
* feat(dashboard-v2): redact JSON editor to tags/spec, preserve other fields on save

The dashboard JSON drawer now exposes only the user-editable `tags` and `spec`;
server-owned/derived keys (id, orgId, name, timestamps, locked, schemaVersion,
image, …) are redacted from the view, copy, and export. On save, the edited draft
is overlaid on the current dashboard so those redacted keys are preserved.

* feat(dashboard-v2): drop redundant JSON actions, rename Edit-as-JSON to JSON

Remove the Actions-menu Data group (Export JSON / Copy as JSON) — these are
redundant with the JSON drawer's own Copy/Download. Rename the 'Edit as JSON'
toolbar button to 'JSON' (keeping the Braces icon).

* feat(dashboard-v2): client-side nav on the Dashboard breadcrumb

Intercept a plain click on the 'Dashboard' breadcrumb for instant SPA navigation
to the list page instead of a full-page reload; the href is kept so middle/
modifier-click still opens in a new tab.
2026-07-03 06:33:15 +00:00
Ashwin Bhatkal
124d76068c fix(dashboard-v2): reconcile optimistic patches from the PATCH response (#11947)
Panel delete/move flickered A -> B -> A -> B: onSettled invalidateQueries fired an
immediate GET that read pre-mutation (stale) data before settling. patchDashboardV2
already returns the updated dashboard, so reconcile the cache from that response
(onSuccess) instead of refetching. Sequence is now A -> B -> B; rollback on error
is unchanged.
2026-07-03 06:33:06 +00:00
Vinicius Lourenço
704b8bf917 chore(frontend-readme): clean the readme for frontend (#11955)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-02 21:18:44 +00:00
Vinicius Lourenço
3e6339019e fix(meter-explorer): not persisting query after page refresh (#11948)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
2026-07-02 14:57:44 +00:00
Vinicius Lourenço
372d304a6f feat(meter): migrate to new uplot API & use bar stacked chart (#11902) 2026-07-02 12:23:30 +00:00
Naman Verma
dbb4eb9574 chore: validate layout size and positioning in backend (#11921)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* chore: validate layout size and positioning in backend

* test: add integratino test for layout validation

* test: use assert instead of require for non blocking check

* test: use assert instead of require for non blocking check

* fix: move require to assert for actual test checks
2026-07-02 11:07:58 +00:00
Abhi kumar
c36226050e feat(dashboards-v2): substitute dashboard variables when creating an alert from a panel (#11929)
Wire the `/substitute_vars` round-trip into the panel create-alert flow so
`$var` / dynamic variable references resolve to the values selected in the
variable bar before the alert is seeded — V1 parity with `useCreateAlerts`,
which the previous V2 path skipped (it shipped variable refs verbatim).

When the dashboard has resolved variables, `useCreateAlertFromPanel` builds a
V5 query-range request (panel queries + resolved variables) and POSTs it through
the generated `useReplaceVariables` hook; on success the substituted envelopes
are translated to the V1 `Query` the alert page reads. With no variables to
substitute the round-trip is a no-op, so we keep seeding synchronously and the
new tab stays tied to the click.

- persesQueryAdapters: extract `envelopesToQuery` from `fromPerses` (the
  substitute response hands back envelopes, not panel-query wrappers)
- buildCreateAlertUrl: export `buildAlertUrl` + `readPanelUnit` so the sync and
  substituted paths share URL assembly
2026-07-02 08:43:48 +00:00
Ashwin Bhatkal
a72484f12c feat(dashboard-v2): optimistic updates for dashboard spec mutations (#11936)
* feat(dashboard-v2): add lenient RFC-6902 JSON-Patch applier

Add applyJsonPatch, a pure applier for the add/replace/remove ops our patchOps
builders emit. Deep-clones and returns a new document (never mutates input), and
is deliberately lenient like the backend apply (remove/replace on a missing path
is a no-op, add creates missing object parents). This lets a dashboard edit be
reflected in the react-query cache optimistically, with the mutation's settle
refetch as the reconcile safety net.

* feat(dashboard-v2): add useOptimisticPatch central mutation hook

A single react-query mutation over patchDashboardV2 that applies the ops to the
cached dashboard on onMutate (via applyJsonPatch, patching the envelope's .data),
snapshots for rollback on onError, and invalidates on settle to reconcile. Reads
dashboardId from the edit-context store (with an optional override for the panel
editor, which receives its id as a prop) and exposes error; rethrows so call sites
keep their own error handling.

* feat(dashboard-v2): route section/layout edits through optimistic patch

Migrate the section and layout mutations (rename, add, delete, reorder, resize/
move persist, first-section migration) off the 'await patchDashboardV2(...);
refetch()' pattern onto useOptimisticPatch, so section edits render instantly and
reconcile in the background. The explicit refetch is dropped (onSettled invalidates)
and each hook keeps its own toast/error handling.

* feat(dashboard-v2): route panel add/move/delete through optimistic patch

Migrate the grid-item panel mutations (delete, move-between-sections, clone) onto
useOptimisticPatch so they render instantly and reconcile on settle. useClonePanel
keeps its toast.promise UX over the patch promise. Update the clone test to assert
against the ops passed to patchAsync.

* feat(dashboard-v2): route panel editor save through optimistic patch

Migrate usePanelEditorSave off usePatchDashboardV2 + invalidateQueries onto the
central useOptimisticPatch (passing the editor's explicit dashboardId). The isNew
branch still reads cached layouts to resolve the target section.

* feat(dashboard-v2): route settings/toolbar edits through optimistic patch

Migrate the remaining patchDashboardV2 spec edits — variable-definition save,
Overview metadata (title/description/image/tags), and toolbar rename — onto
useOptimisticPatch. The toolbar keeps its refetch prop for the lock/unlock toggle
(a non-patch API), and the edit-context refetch stays for the JSON editor's
full-document save; both are outside this PR's patch-op scope.

* chore(dashboard-v2): ban direct patchDashboardV2 via oxlint

Add a no-restricted-imports rule forbidding patchDashboardV2 / usePatchDashboardV2
from api/generated/services/dashboard, directing callers to useOptimisticPatch().
patchAsync so every spec edit goes through the optimistic cache path. The hook
itself (the one sanctioned caller) and its test carry a scoped inline exception.
2026-07-02 07:28:50 +00:00
Ashwin Bhatkal
71eabac1e7 fix(dashboards): stop query cache collisions on public dashboards (#11935)
The public payload redacts each widget's query (filters/limit/orderBy
stripped), so panels differing only by their filter arrive with identical
query bodies. The react-query key was built from that query body, so those
panels hashed to the same key and were deduped into one request — its data
filled every colliding panel while other indices were never fetched.

Key each panel on what determines its response — widget id + index + time —
instead of the redacted query body.

Fixes SigNoz/engineering-pod#5503
2026-07-02 06:07:21 +00:00
Abhi kumar
fea3be7c51 feat(dashboards-v2): panel editor — threshold carry, span-gaps fixes, metric unit defaults, live thresholds and pie multi-column fix (#11918)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* feat(dashboards-v2): carry thresholds across a panel visualization-type switch

When switching a panel's visualization kind mid-edit, thresholds now carry
over if the target kind supports them, remapped to the target's variant
(label/comparison/table) — keeping the shared core (color, value, unit) and
seeding any variant-required fields (operator, format, column) with sensible
defaults so the carried threshold stays functional. Kinds without a Thresholds
section drop them. The carry is a first-visit seed; reversible round-trips
still restore from the per-kind session cache.

* fix(dashboards-v2): span-gaps Disconnect Values reactivity + fillOnlyBelow flag

Fixes three issues in the chart-appearance span-gaps control and makes the
fillOnlyBelow flag authoritative end-to-end:

- Threshold default now seeds from the live query step interval (which arrives
  async) instead of being captured once at mount, so it no longer falls back
  to 1m.
- The threshold input no longer re-commits an unchanged value on blur, so
  clicking "Never" reliably switches mode (the blur/toggle race is gone).
- Invalid input is validated live as the user types, surfacing the error
  immediately rather than only on blur.
- Selecting Threshold writes fillOnlyBelow: true (+ duration); Never writes
  fillOnlyBelow: false and drops the duration. The selected mode is derived
  from fillOnlyBelow, and the renderer honors it (explicit false spans every
  gap), with back-compat for panels saved before the flag existed.

* feat(dashboards-v2): auto-seed panel unit from the metric with a mismatch warning

V1 parity for the formatting unit selector: when the selected metric carries a
unit, a new panel auto-initializes its unit from it, and choosing a different
unit shows the "Unit mismatch" warning. Reuses the shared useGetYAxisUnit hook
and YAxisUnitSelector read-only.

The resolution + auto-seed runs at the editor level (not inside the collapsible
FormattingSection) so it applies even while that section is closed; the
resolved metric unit is threaded down via context purely to drive the warning.
Seeding is gated to new panels — editing never overwrites a saved unit.

* feat(dashboards-v2): reactive threshold editing with live preview

Threshold edits now stream to the spec as the user types, so the panel preview
reflects them before Save. The per-row draft is mirrored into the spec via an
onLiveChange effect in useThresholdDraft; because edits reach the spec live,
ThresholdsSection snapshots the saved value on edit entry and restores it on
Discard. Save keeps the value, Discard rolls back, and add-then-discard still
removes the row.

* fix(dashboard): apply pie multi-column scalar fix to v2 panels

Mirror the V1 pie fix in the V2 PieChartPanel. preparePieData already reads
the scalar table (via prepareScalarTables) but used
columns.find(isValueColumn), so only the first value column was plotted — a
ClickHouse `count() AS col1, sum() AS col2` collapsed to a single slice.

It now emits one slice per (row × value column); with multiple value columns
the column name distinguishes the slices (prefixed by the group when
grouped). Single-value and grouped panels are unchanged — a single value
column iterates exactly once.

Per the V1/V2 split, this duplicates the behaviour into V2 land rather than
sharing the V1 helper.

* chore: pr review fixes
2026-07-02 00:45:26 +00:00
Srikanth Chekuri
66f03d5912 fix(metrics): use local table for fingerprint ctes (#11931)
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
* fix(metrics): use local table for fingerprint ctes

* chore: remove queries file

* chore: update reduced_test.go
2026-07-01 16:14:11 +00:00
Pandey
cf69a05f74