Closes HDX-3311
# Summary
This PR adds E2E tests that verify that dashboards created and edited through the external API can be rendered correctly in the UI.
- The tests create a dashboard with all tile types through the external API, then assert that the tile edit form contains the correct values for all of the tile's properties.
- The tests verify that the dashboard can be saved from the UI, proving that the dashboard data conforms to the _internal_ dashboard API's schema, after being created by the external dashboards API
- The tests also validate that dashboard updates and deletes via the external API are reflected in the UI.
Closes HDX-3236
# Summary
This PR fixes an error that occurs when a metricName/metricType is set for a dashboard tile configuration, despite the queried source not being a metric source.
1. Updates in DBEditTimeChartForm prevent us from saving configurations with metricName/metricType for non metric sources
2. Updates in DBDashboardPage ensure that metricName/metricType is ignored for any saved configurations for non-metric sources.
## Demo
A new tile would be saved with a metricName/Type incorrectly when
1. Create the tile
2. Select a metric source
3. Select a metric name
4. Switch back to a non-metric source
5. Save
And the Dashboard tile would then error:
<img width="1288" height="1012" alt="Screenshot 2026-01-23 at 2 39 38 PM" src="https://github.com/user-attachments/assets/4fa4b0bf-355e-47bb-a504-cd03e0dca2d0" />
Now, the configuration is not saved with metricName/Type, and the dashboard does not error for a saved configuration that has a metricName/Type:
<img width="769" height="423" alt="Screenshot 2026-01-23 at 2 43 04 PM" src="https://github.com/user-attachments/assets/92af36aa-dd46-47b8-ae59-d0e4bfcb28af" />
Closes HDX-3220
Closes HDX-1718
Closes HDX-3205
# Summary
This PR adds an option that allows users to customize the 0-fill behavior on time charts. The default behavior remains to fill all empty intervals with 0. The user can now disable the filling behavior. When fill is disabled, series will appear to be interpolated.
This PR also consolidates various display settings into a drawer, replacing the existing Number Format drawer. In the process, various form-related bugs were fixed in the drawer, and micro/nano second input factors were added.
## New Chart Display Settings Drawer
<img width="1697" height="979" alt="Screenshot 2026-01-20 at 9 10 59 AM" src="https://github.com/user-attachments/assets/1683666a-7c56-4018-8e5b-2c6c814f0cd2" />
## Zero-fill behavior
Enabled (default):
<img width="1458" height="494" alt="Screenshot 2026-01-20 at 9 12 45 AM" src="https://github.com/user-attachments/assets/0306644e-d2ff-46d6-998b-eb458d5c9ccc" />
Disabled:
<img width="1456" height="505" alt="Screenshot 2026-01-20 at 9 12 37 AM" src="https://github.com/user-attachments/assets/f084887e-4099-4365-af4f-73eceaf5dc3d" />
Closes HDX-3067
Closes#1331Closes#1212Closes#1468
# Summary
This PR makes a number of improvements around the way we handle date ranges and granularities, in an effort to minimize discrepancies between aggregate values queried from original data and aggregate values queried from materialized views.
1. Date ranges for Line and Bar chart queries are now (by default) auto-aligned to the chart's granularity. **This is not limited to materialized view queries.** Since the chart granularity is a multiple of the MV granularity, this ensures that the date range is aligned to the MV granularity as well. This also address a number of related issues that point out 0-values or low-values in the first or last data points. This PR also includes an option to disable this behavior for charts in Chart Explorer or Dashboard Tiles.
2. All materialized view queries and all time chart queries are now end-exclusive, to avoid selecting the entirety of the next "time bucket" from the materialized view when the date range is aligned with the materialized view granularity
3. Materialized views are only used for a query with a granularity if the chart query granularity is a multiple of the MV granularity. Previously, we'd use the MV as long as the chart query granularity was at least as large as the MV granularity, but this could cause unequal distributions of data across time buckets. Nearly all available granularities are multiples of all smaller available granularities - so this should only impact queries with granularity 15 minutes with MVs with granularity 10 minutes. 10m granularity support is being removed in #1551
## Demo
<details>
<summary>Show Complete Intervals Option</summary>
https://github.com/user-attachments/assets/4b903adb-4edf-4481-93d6-2a0c42589a37
</details>
Closes HDX-3089
Closes HDX-3083
# Summary
This PR ensures that the Generated SQL and Materialized View Explanations are generated for the same config that is queried.
Previously, this was not the case because child components (eg. DBTableChart, DBTimeChart, DBNumberChart) would transform the config passed down by DBEditTimeChart or Dashboard.Tile. Now, the same transformations are applied at the parent component.
## Demo
<details>
<summary>Table Tile MV Indicator now correctly ignores granularity</summary>
Note that the time chart tiles cannot use MVs because the granularity is too small, but the table tile can use the MV:
<img width="1495" height="884" alt="Screenshot 2025-12-29 at 9 00 16 AM" src="https://github.com/user-attachments/assets/324d3511-6b86-4bd8-87b0-824b4586bb9b" />
</details>
<details>
<summary>Number and Table Chart generated SQL is correct</summary>
Number Chart has no granularity, group, or order by:
<img width="1493" height="830" alt="Screenshot 2025-12-29 at 9 14 08 AM" src="https://github.com/user-attachments/assets/34202de1-1d55-4675-9883-e15418f2bb2f" />
Table Chart has implicit group by, limit, and order by applied:
<img width="1495" height="837" alt="Screenshot 2025-12-29 at 9 14 00 AM" src="https://github.com/user-attachments/assets/2aa17106-527a-4e34-a76a-a6c1767a1e86" />
</details>
Closes HDX-3082
# Summary
This PR back-ports support for materialized views from the EE repo. Note that this feature is in **Beta**, and is subject to significant changes.
This feature is intended to support:
1. Configuring AggregatingMergeTree (or SummingMergeTree) Materialized Views which are associated with a Source
2. Automatically selecting and querying an associated materialized view when a query supports it, in Chart Explorer, Custom Dashboards, the Services Dashboard, and the Search Page Histogram.
3. A UX for understanding what materialized views are available for a source, and whether (and why) it is or is not being used for a particular visualization.
## Note to Reviewer(s)
This is a large PR, but the code has largely already been reviewed.
- For net-new files, types, components, and utility functions, the code does not differ from the EE repo
- Changes to the various services dashboard pages do not differ from the EE repo
- Changes to `useOffsetPaginatedQuery`, `useChartConfig`, and `DBEditTimeChart` differ slightly due to unrelated (to MVs) drift between this repo and the EE repo, and due to the lack of feature toggles in this repo. **This is where slightly closer review would be most valuable.**
## Demo
<details>
<summary>Demo: MV Configuration</summary>
https://github.com/user-attachments/assets/fedf3bcf-892c-4b8d-a788-7e231e23bcc3
</details>
<details>
<summary>Demo: Chart Explorer</summary>
https://github.com/user-attachments/assets/fc8d1efa-7edc-42fc-98f0-75431cc056b8
</details>
<details>
<summary>Demo: Dashboards</summary>
https://github.com/user-attachments/assets/f3cb247e-711f-4d90-95b8-cf977e94f065
</details>
## Known Limitations
This feature is in Beta due to the following known limitations, which will be addressed in subsequent PRs:
1. Visualization start and end time, when not aligned with the granularity of MVs, will result in statistics based on the MV "time buckets" which fall inside the date range. This may not align exactly with the source table data which is in the selected date range.
2. Alerts do not make use of MVs, even if the associated visualization does. Due to (1), this means that alert values may not exactly match the values shown in the associated visualization.
## Differences in OSS vs EE Support
- In OSS, there is a beta label on the MV configurations section
- In EE there are feature toggles to enable MV support, in OSS the feature is enabled for all teams, but will only run for sources with MVs configured.
## Testing
To test, a couple of MVs can be created on the default `otel_traces` table, directly in ClickHouse:
<details>
<summary>Example MVs DDL</summary>
```sql
CREATE TABLE default.metrics_rollup_1m
(
`Timestamp` DateTime,
`ServiceName` LowCardinality(String),
`SpanKind` LowCardinality(String),
`StatusCode` LowCardinality(String),
`count` SimpleAggregateFunction(sum, UInt64),
`sum__Duration` SimpleAggregateFunction(sum, UInt64),
`avg__Duration` AggregateFunction(avg, UInt64),
`quantile__Duration` AggregateFunction(quantileTDigest(0.5), UInt64),
`min__Duration` SimpleAggregateFunction(min, UInt64),
`max__Duration` SimpleAggregateFunction(max, UInt64)
)
ENGINE = AggregatingMergeTree
PARTITION BY toDate(Timestamp)
ORDER BY (Timestamp, StatusCode, SpanKind, ServiceName);
CREATE MATERIALIZED VIEW default.metrics_rollup_1m_mv TO default.metrics_rollup_1m
(
`Timestamp` DateTime,
`ServiceName` LowCardinality(String),
`SpanKind` LowCardinality(String),
`version` LowCardinality(String),
`StatusCode` LowCardinality(String),
`count` UInt64,
`sum__Duration` Int64,
`avg__Duration` AggregateFunction(avg, UInt64),
`quantile__Duration` AggregateFunction(quantileTDigest(0.5), UInt64),
`min__Duration` SimpleAggregateFunction(min, UInt64),
`max__Duration` SimpleAggregateFunction(max, UInt64)
)
AS SELECT
toStartOfMinute(Timestamp) AS Timestamp,
ServiceName,
SpanKind,
StatusCode,
count() AS count,
sum(Duration) AS sum__Duration,
avgState(Duration) AS avg__Duration,
quantileTDigestState(0.5)(Duration) AS quantile__Duration,
minSimpleState(Duration) AS min__Duration,
maxSimpleState(Duration) AS max__Duration
FROM default.otel_traces
GROUP BY
Timestamp,
ServiceName,
SpanKind,
StatusCode;
```
```sql
CREATE TABLE default.span_kind_rollup_1m
(
`Timestamp` DateTime,
`ServiceName` LowCardinality(String),
`SpanKind` LowCardinality(String),
`histogram__Duration` AggregateFunction(histogram(20), UInt64)
)
ENGINE = AggregatingMergeTree
PARTITION BY toDate(Timestamp)
ORDER BY (Timestamp, ServiceName, SpanKind);
CREATE MATERIALIZED VIEW default.span_kind_rollup_1m_mv TO default.span_kind_rollup_1m
(
`Timestamp` DateTime,
`ServiceName` LowCardinality(String),
`SpanKind` LowCardinality(String),
`histogram__Duration` AggregateFunction(histogram(20), UInt64)
)
AS SELECT
toStartOfMinute(Timestamp) AS Timestamp,
ServiceName,
SpanKind,
histogramState(20)(Duration) AS histogram__Duration
FROM default.otel_traces
GROUP BY
Timestamp,
ServiceName,
SpanKind;
```
</details>
Then you'll need to configure the materialized views in your source settings:
<details>
<summary>Source Configuration (should auto-infer when MVs are selected)</summary>
<img width="949" height="1011" alt="Screenshot 2025-12-19 at 10 26 54 AM" src="https://github.com/user-attachments/assets/fc46a1b9-de8b-4b95-a8ef-ba5fee905685" />
</details>
Improves the Chart Explorer page to only run the sample query when the accordion is open and visible. Also changed default to closed since it's below the fold.
@pulpdrew assigned to you as you originally observed this issue
Demo:
https://github.com/user-attachments/assets/6108323a-767f-4e9f-88cf-4b9e2de9def1
Fixes HDX-2895
This PR removes bootstrap-icons entirely from the app. It also adds an eslint plugin to detect uses and throw an error, this will help in the immediate short term with PRs in flight and merging downstream.
Fixes HDX-3050
Closes HDX-2845
# Summary
This PR adds support for specifying a persistent Order By in table charts. Previously, the user could sort by clicking a column, but this was not persisted to the saved chart config. Now, we show an input that allows the user to specify an ordering other than the default, and this order is persisted in the saved chart config.
## Demo
https://github.com/user-attachments/assets/960642fd-9749-4e54-9b84-ab82eb5af3d8
This PR adds the ability to click on tables or graphs across the app, and be able to deep link into the search page to view the correlated search events.
https://github.com/user-attachments/assets/e5c7c2f2-9b59-42de-bb73-2fa4cb5d09a2
Things to try:
1. **Attributable Functions** (min, max, average, p95, etc) can all reliably give us a y value back to enable filtering directly to the y-values value
2. **Non-attributable Functions** (count, sum, etc) can’t rely on the y value since it depends on the group by logic. As such, these will simply allow you to search by the service without passing the y value for deeper analysis.
3. **Multiple Group Bys** (ex `ServiceName, SpanName`)
4. **Where Clause** (SQL or Lucene)
5. Do a **general test** across the app to ensure everywhere that uses charting behaves the same or better than before.
Some things that don’t work:
1. **Aliases in the group by** - we are hitting limitations with `node-sql-parser` that causes the aliasMap to not generate correctly when using aggregate functions in most cases. We may need to either fix these issues or find an alternative solution.
2. **Expressions in Group By** - If you have expressions in the group by, the filtering will not work based on the current implementation, it does not factor in the result of the expression in the filter value.
3. **Filters are not reflected in the UI on Search** - When you deeplink, the filters in the sidebar do not reflect what is actually being queried. This is because the filter UI logic uses `IN` but the deeplinking uses `=` to achieve the best level of precision (and avoid false positives). As such, this is something that could be improved in the future.
Fixes HDX-2844, HDX-2922
Closes HDX-2777
# Summary
This PR adds a toggle that enables showing "previous period" data on line charts, overlayed with the current period data.
1. The "previous period" is a date range of the same length as the selected "current" date range, immediately prior to the current date range.
2. This feature is only enabled for line charts, bar charts are not enabled when this option is toggled on.
**This PR is organized into a number of commits which may be easier to review one at a time.**
## Followup work
- Improve layout of the DBEditTimeChartForm, pending design review
## Demo
https://github.com/user-attachments/assets/76b220da-810e-4280-8fb3-fa20a9919685
moves them into a core folder, this allows us to easily track when core files are modified via path
no changeset because no version bump required
fixes HDX-2589
Across the app, we are inconsistent with when we can open the sidebar and expand functionality. This is because the sidebar and logic was managed by the parent component.
Additionally, the expand logic was set to assume a certain structure that some places in the application could not support (ex clickhouse dashboard doesn't have a 'source').
As a result, I have created the `DBSqlRowTableWithSideBar` component which will manage a lot of the common use cases for us. This PR introduces that new component, and updates all references (that could be easily upgraded) to use the new component when applciable.
The result: a lot less duplicate code (see # of lines removed) and the ability to more easily maintain the components down the road.
This PR also fixes several bugs I found as I tested these flows, especially around sidebars opening subpanels.
Fixes: HDX-2341
Fixes: HDX-2296
When a user clicks the ">" icon, the row is expanded and live tail is paused.
<img width="1882" height="451" alt="image" src="https://github.com/user-attachments/assets/4b4f12e0-df80-49b0-b917-455b213b4f3a" />
The user is able to interact with with the inline view as well
<img width="1823" height="334" alt="image" src="https://github.com/user-attachments/assets/e0c1acfc-7523-470d-b385-343c6e84ad9f" />
The user can click the expand button in the top right to open the sidebar
<img width="258" height="180" alt="image" src="https://github.com/user-attachments/assets/40b40c59-29a8-44fc-a310-6b55121029b4" />
The tab last chosen by the user persists in local storage
Clicking on an item in the table results in the sidebar opening as it does today.
These changes also:
* Disable the chevron in places where the sidebar is not hooked up today
* Disables interactivity of Event Tags if it doesn't have the proper events passed into it as well.
This PR fixes: HDX-1641
The Linear issue only mentions:
> The Run button on the Markdown form doesn't do anything
However, in **Charts Explorer → Markdown**, the time picker also wasn’t working. I’ve removed it as well.
<img width="2681" height="2048" alt="image" src="https://github.com/user-attachments/assets/6f6b7fc5-544f-43e2-ab9d-05894f83e8d6" />
We now store `createdBy` in the `Alert` document when the alert
is created. This new field references the `User` document of the
currently logged in user. The property is optional to support
existing alerts in the database.
This information is also displayed in various places where alert
details are displayed. Older documents without the new field should
display nothing, resulting in the existing UX.