+- Graphite
+
+### Unconfirmed
+
+{{< column-list >}}
+
+- Altinity plugin for ClickHouse
+- Amazon Athena
+- Amazon Redshift
+- Amazon Timestream
+- Apache Cassandra
+- AppDynamics
+- Azure Data Explorer Datasource
+- Azure Monitor
+- CSV
+- DB2 Datasource
+- Databricks
+- Datadog
+- Dataset
+- Druid
+- Dynatrace
+- GitHub
+- Google BigQuery
+- Grafana for YNAB
+- Honeycomb
+- Jira
+- Mock
+- Neo4j Datasource
+- New Relic
+- OPC UA (Unified Architecture)
+- Open Distro for Elasticsearch
+- OpenSearch
+- OpenTSDB
+- Orbit
+- SAP HANA®
+- Salesforce
+- Sentry
+- ServiceNow
+- Snowflake
+- Splunk
+- Splunk Infrastructure Monitoring
+- Sqlyze data source
+- TDengine
+- Vertica
+- Wavefront
+- X-Ray
+- kdb+
+- simple grpc data source
+
+{{< /column-list >}}
## Limitations
diff --git a/docs/sources/panels-visualizations/configure-data-links/index.md b/docs/sources/panels-visualizations/configure-data-links/index.md
index 3032bd3e45b..31bf6df9b67 100644
--- a/docs/sources/panels-visualizations/configure-data-links/index.md
+++ b/docs/sources/panels-visualizations/configure-data-links/index.md
@@ -143,14 +143,26 @@ If there's only one data link in the visualization, clicking anywhere on the vis
You can configure data links for the following visualizations:
-| | | |
-| ------------------------------ | ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Heatmap](ref:heatmap) | [Status history](ref:status-history) |
-| [Bar gauge](ref:bar-gauge) | [Histogram](ref:histogram) | [Table](ref:table) |
-| [Candlestick](ref:candlestick) | [Pie chart](ref:pie-chart) | [Time series](ref:time-series) |
-| [Canvas](ref:canvas) | [Stat](ref:stat) | [Trend](ref:trend) |
-| [Gauge](ref:gauge) | [State timeline](ref:state-timeline) | [XY chart](ref:xy-chart) |
-| [Geomap](ref:geomap) | | |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Bar gauge](ref:bar-gauge)
+- [Candlestick](ref:candlestick)
+- [Canvas](ref:canvas)
+- [Gauge](ref:gauge)
+- [Geomap](ref:geomap)
+- [Heatmap](ref:heatmap)
+- [Histogram](ref:histogram)
+- [Pie chart](ref:pie-chart)
+- [Stat](ref:stat)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Table](ref:table)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+- [XY chart](ref:xy-chart)
+
+{{< /column-list >}}
## Data link variables
diff --git a/docs/sources/panels-visualizations/configure-overrides/index.md b/docs/sources/panels-visualizations/configure-overrides/index.md
index 2b7264ee6d4..c01a72bd781 100644
--- a/docs/sources/panels-visualizations/configure-overrides/index.md
+++ b/docs/sources/panels-visualizations/configure-overrides/index.md
@@ -121,14 +121,26 @@ After you've set them, your overrides appear in both the **All** and **Overrides
You can configure field overrides for the following visualizations:
-| | | |
-| ------------------------------ | ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Heatmap](ref:heatmap) | [Status history](ref:status-history) |
-| [Bar gauge](ref:bar-gauge) | [Histogram](ref:histogram) | [Table](ref:table) |
-| [Candlestick](ref:candlestick) | [Pie chart](ref:pie-chart) | [Time series](ref:time-series) |
-| [Canvas](ref:canvas) | [Stat](ref:stat) | [Trend](ref:trend) |
-| [Gauge](ref:gauge) | [State timeline](ref:state-timeline) | [XY chart](ref:xy-chart) |
-| [Geomap](ref:geomap) | | |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Bar gauge](ref:bar-gauge)
+- [Candlestick](ref:candlestick)
+- [Canvas](ref:canvas)
+- [Gauge](ref:gauge)
+- [Geomap](ref:geomap)
+- [Heatmap](ref:heatmap)
+- [Histogram](ref:histogram)
+- [Pie chart](ref:pie-chart)
+- [Stat](ref:stat)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Table](ref:table)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+- [XY chart](ref:xy-chart)
+
+{{< /column-list >}}
## Override rules
diff --git a/docs/sources/panels-visualizations/configure-standard-options/index.md b/docs/sources/panels-visualizations/configure-standard-options/index.md
index e39626fc2f1..cbbdfb570b6 100644
--- a/docs/sources/panels-visualizations/configure-standard-options/index.md
+++ b/docs/sources/panels-visualizations/configure-standard-options/index.md
@@ -126,13 +126,25 @@ For more granular control over the display of fields, refer to [Configure overri
You can configure standard options for the following visualizations:
-| | | |
-| ------------------------------ | ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Geomap](ref:geomap) | [Status history](ref:status-history) |
-| [Bar gauge](ref:bar-gauge) | [Histogram](ref:histogram) | [Table](ref:table) |
-| [Candlestick](ref:candlestick) | [Pie chart](ref:pie-chart) | [Time series](ref:time-series) |
-| [Canvas](ref:canvas) | [Stat](ref:stat) | [Trend](ref:trend) |
-| [Gauge](ref:gauge) | [State timeline](ref:state-timeline) | [XY chart](ref:xy-chart) |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Bar gauge](ref:bar-gauge)
+- [Candlestick](ref:candlestick)
+- [Canvas](ref:canvas)
+- [Gauge](ref:gauge)
+- [Geomap](ref:geomap)
+- [Histogram](ref:histogram)
+- [Pie chart](ref:pie-chart)
+- [Stat](ref:stat)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Table](ref:table)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+- [XY chart](ref:xy-chart)
+
+{{< /column-list >}}
## Standard options
diff --git a/docs/sources/panels-visualizations/configure-thresholds/index.md b/docs/sources/panels-visualizations/configure-thresholds/index.md
index 102b8ea4505..220f8464450 100644
--- a/docs/sources/panels-visualizations/configure-thresholds/index.md
+++ b/docs/sources/panels-visualizations/configure-thresholds/index.md
@@ -110,13 +110,23 @@ You can also use thresholds to:
You can set thresholds in the following visualizations:
-| | | |
-| ------------------------------ | ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Geomap](ref:geomap) | [Status history](ref:status-history) |
-| [Bar gauge](ref:bar-gauge) | [Histogram](ref:histogram) | [Table](ref:table) |
-| [Candlestick](ref:candlestick) | [Stat](ref:stat) | [Time series](ref:time-series) |
-| [Canvas](ref:canvas) | [State timeline](ref:state-timeline) | [Trend](ref:trend) |
-| [Gauge](ref:gauge) |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Bar gauge](ref:bar-gauge)
+- [Candlestick](ref:candlestick)
+- [Canvas](ref:canvas)
+- [Gauge](ref:gauge)
+- [Geomap](ref:geomap)
+- [Histogram](ref:histogram)
+- [Stat](ref:stat)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Table](ref:table)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+
+{{< /column-list >}}
## Default thresholds
diff --git a/docs/sources/panels-visualizations/configure-tooltips/index.md b/docs/sources/panels-visualizations/configure-tooltips/index.md
index 79f7010d6a2..4c7ee9e11e6 100644
--- a/docs/sources/panels-visualizations/configure-tooltips/index.md
+++ b/docs/sources/panels-visualizations/configure-tooltips/index.md
@@ -84,13 +84,19 @@ When you hover your cursor over a visualization, Grafana can display tooltips th
You can configure tooltips for the following visualizations:
-| | |
-| ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Status history](ref:status-history) |
-| [Candlestick](ref:candlestick) | [Time series](ref:time-series) |
-| [Heatmap](ref:heatmap) | [Trend](ref:trend) |
-| [Pie chart](ref:pie-chart) | [XY chart](ref:xy-chart) |
-| [State timeline](ref:state-timeline) | |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Candlestick](ref:candlestick)
+- [Heatmap](ref:heatmap)
+- [Pie chart](ref:pie-chart)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+- [XY chart](ref:xy-chart)
+
+{{< /column-list >}}
Some visualizations, for example [candlestick](ref:candlestick) and [flame graph](ref:flame-graph), have tooltips, but they aren't configurable. These visualizations don't have a **Tooltip** section in the panel editor pane. [Geomaps](ref:geomaps) provide you the option to have tooltips triggered upon click or hover under the **Map controls** options in the panel editor pane.
diff --git a/docs/sources/panels-visualizations/configure-value-mappings/index.md b/docs/sources/panels-visualizations/configure-value-mappings/index.md
index 754eeed29ee..82231549084 100644
--- a/docs/sources/panels-visualizations/configure-value-mappings/index.md
+++ b/docs/sources/panels-visualizations/configure-value-mappings/index.md
@@ -105,13 +105,24 @@ Value mappings bypass unit formatting set in the **Standard options** section of
You can configure value mappings for the following visualizations:
-| | | |
-| ------------------------------ | ------------------------------------ | ------------------------------------ |
-| [Bar chart](ref:bar-chart) | [Geomap](ref:geomap) | [Status history](ref:status-history) |
-| [Bar gauge](ref:bar-gauge) | [Histogram](ref:histogram) | [Table](ref:table) |
-| [Candlestick](ref:candlestick) | [Pie chart](ref:pie-chart) | [Time series](ref:time-series) |
-| [Canvas](ref:canvas) | [Stat](ref:stat) | [Trend](ref:trend) |
-| [Gauge](ref:gauge) | [State timeline](ref:state-timeline) | |
+{{< column-list >}}
+
+- [Bar chart](ref:bar-chart)
+- [Bar gauge](ref:bar-gauge)
+- [Candlestick](ref:candlestick)
+- [Canvas](ref:canvas)
+- [Gauge](ref:gauge)
+- [Geomap](ref:geomap)
+- [Histogram](ref:histogram)
+- [Pie chart](ref:pie-chart)
+- [Stat](ref:stat)
+- [State timeline](ref:state-timeline)
+- [Status history](ref:status-history)
+- [Table](ref:table)
+- [Time series](ref:time-series)
+- [Trend](ref:trend)
+
+{{< /column-list >}}
## Types of value mappings
diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md
index bd96e5514a2..ac5c27f35bc 100644
--- a/docs/sources/setup-grafana/configure-grafana/_index.md
+++ b/docs/sources/setup-grafana/configure-grafana/_index.md
@@ -630,7 +630,11 @@ Define a whitelist of allowed IP addresses or domains, with ports, to be used in
### disable_brute_force_login_protection
-Set to `true` to disable [brute force login protection](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#account-lockout). Default is `false`. An existing user's account will be locked after 5 attempts in 5 minutes.
+Set to `true` to disable [brute force login protection](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#account-lockout). Default is `false`. An existing user's account will be unable to login for 5 minutes if all login attempts are spent within a 5 minute window.
+
+### brute_force_login_protection_max_attempts
+
+Configure how many login attempts a user have within a 5 minute window before the account will be locked. Default is `5`.
### cookie_secure
diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
index 30374f38aa3..3f7c27beb59 100644
--- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
+++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
@@ -81,6 +81,7 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
| `azureMonitorDisableLogLimit` | Disables the log limit restriction for Azure Monitor when true. The limit is enabled by default. | |
| `preinstallAutoUpdate` | Enables automatic updates for pre-installed plugins | Yes |
| `alertingUIOptimizeReducer` | Enables removing the reducer from the alerting UI when creating a new alert rule and using instant query | Yes |
+| `azureMonitorEnableUserAuth` | Enables user auth for Azure Monitor datasource only | Yes |
## Public preview feature toggles
@@ -189,6 +190,7 @@ Experimental features might be changed or removed without prior notice.
| `newFolderPicker` | Enables the nested folder picker without having nested folders enabled |
| `onPremToCloudMigrationsAlerts` | Enables the migration of alerts and its child resources to your Grafana Cloud stack. Requires `onPremToCloudMigrations` to be enabled in conjunction. |
| `onPremToCloudMigrationsAuthApiMig` | Enables the use of auth api instead of gcom for internal token services. Requires `onPremToCloudMigrations` to be enabled in conjunction. |
+| `scopeApi` | In-development feature flag for the scope api using the app platform. |
| `sqlExpressions` | Enables using SQL and DuckDB functions as Expressions. |
| `nodeGraphDotLayout` | Changed the layout algorithm for the node graph |
| `kubernetesAggregator` | Enable grafana's embedded kube-aggregator |
diff --git a/go.mod b/go.mod
index 0f00477032c..4fa8986d9c2 100644
--- a/go.mod
+++ b/go.mod
@@ -121,7 +121,7 @@ require (
github.com/m3db/prometheus_remote_client_golang v0.4.4 // @grafana/grafana-backend-group
github.com/madflojo/testcerts v1.1.1 // @grafana/alerting-backend
github.com/magefile/mage v1.15.0 // @grafana/grafana-developer-enablement-squad
- github.com/matryer/is v1.4.0 // @grafana/grafana-as-code
+ github.com/matryer/is v1.4.1 // @grafana/grafana-as-code
github.com/mattn/go-isatty v0.0.20 // @grafana/grafana-backend-group
github.com/mattn/go-sqlite3 v1.14.22 // @grafana/grafana-backend-group
github.com/matttproud/golang_protobuf_extensions v1.0.4 // @grafana/alerting-backend
@@ -171,15 +171,15 @@ require (
go.uber.org/atomic v1.11.0 // @grafana/alerting-backend
go.uber.org/goleak v1.3.0 // @grafana/grafana-search-and-storage
gocloud.dev v0.40.0 // @grafana/grafana-app-platform-squad
- golang.org/x/crypto v0.28.0 // @grafana/grafana-backend-group
+ golang.org/x/crypto v0.29.0 // @grafana/grafana-backend-group
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // @grafana/alerting-backend
- golang.org/x/mod v0.21.0 // indirect; @grafana/grafana-backend-group
- golang.org/x/net v0.30.0 // @grafana/oss-big-tent @grafana/partner-datasources
+ golang.org/x/mod v0.22.0 // indirect; @grafana/grafana-backend-group
+ golang.org/x/net v0.31.0 // @grafana/oss-big-tent @grafana/partner-datasources
golang.org/x/oauth2 v0.23.0 // @grafana/identity-access-team
golang.org/x/sync v0.9.0 // @grafana/alerting-backend
golang.org/x/text v0.20.0 // @grafana/grafana-backend-group
golang.org/x/time v0.6.0 // @grafana/grafana-backend-group
- golang.org/x/tools v0.26.0 // @grafana/grafana-as-code
+ golang.org/x/tools v0.27.0 // @grafana/grafana-as-code
gonum.org/v1/gonum v0.15.1 // @grafana/observability-metrics
google.golang.org/api v0.193.0 // @grafana/grafana-backend-group
google.golang.org/grpc v1.67.1 // @grafana/plugins-platform-backend
@@ -431,7 +431,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // @grafana/identity-access-team
golang.org/x/sys v0.27.0 // indirect
- golang.org/x/term v0.25.0 // indirect
+ golang.org/x/term v0.26.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
google.golang.org/genproto v0.0.0-20240820151423-278611b39280 // indirect; @grafana/grafana-backend-group
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect
diff --git a/go.sum b/go.sum
index b7f603c27e8..714d9a6cfe3 100644
--- a/go.sum
+++ b/go.sum
@@ -2682,8 +2682,8 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
-github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
+github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ=
+github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU=
github.com/mattermost/xml-roundtrip-validator v0.1.0/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM=
@@ -3518,8 +3518,8 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
-golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
-golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
+golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
+golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -3597,8 +3597,8 @@ golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
-golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -3697,8 +3697,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
-golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
-golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
+golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -3933,8 +3933,8 @@ golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
-golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
-golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
+golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
+golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -4064,8 +4064,8 @@ golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
-golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
-golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
+golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
+golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/go.work.sum b/go.work.sum
index c523ff2e1f7..6925ec372b5 100644
--- a/go.work.sum
+++ b/go.work.sum
@@ -989,6 +989,9 @@ github.com/grafana/alerting v0.0.0-20240917171353-6c25eb6eff10 h1:oDbLKM34O+JUF9
github.com/grafana/alerting v0.0.0-20240917171353-6c25eb6eff10/go.mod h1:GMLi6d09Xqo96fCVUjNk//rcjP5NKEdjOzfWIffD5r4=
github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2 h1:qhugDMdQ4Vp68H0tp/0iN17DM2ehRo1rLEdOFe/gB8I=
github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2/go.mod h1:w/aiO1POVIeXUQyl0VQSZjl5OAGDTL5aX+4v0RA1tcw=
+github.com/grafana/cog v0.0.4/go.mod h1:lzetOuhGUl/JaSACiJoHvBokf9/fS6PEFaWZvnQu2vs=
+github.com/grafana/cog v0.0.5 h1:BCa+10i3KvV+KMSQuxlN1DS9cZEwN+EAFc7ZmXqHxQE=
+github.com/grafana/cog v0.0.5/go.mod h1:lzetOuhGUl/JaSACiJoHvBokf9/fS6PEFaWZvnQu2vs=
github.com/grafana/cuetsy v0.1.10/go.mod h1:Ix97+CPD8ws9oSSxR3/Lf4ahU1I4Np83kjJmDVnLZvc=
github.com/grafana/go-gelf/v2 v2.0.1 h1:BOChP0h/jLeD+7F9mL7tq10xVkDG15he3T1zHuQaWak=
github.com/grafana/go-gelf/v2 v2.0.1/go.mod h1:lexHie0xzYGwCgiRGcvZ723bSNyNI8ZRD4s0CLobh90=
@@ -1783,6 +1786,7 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
@@ -1796,6 +1800,7 @@ golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
diff --git a/kindsv2/gen.go b/kindsv2/gen.go
index ee215e3d491..81ad33a890c 100644
--- a/kindsv2/gen.go
+++ b/kindsv2/gen.go
@@ -6,46 +6,47 @@ import (
"context"
"os"
- "cuelang.org/go/cue/cuecontext"
"github.com/grafana/cog"
)
type codegenTargets struct {
- schemaPath string
- outputPath string
+ modulePath string
+ outputPath string
+ cueImportsMap map[string]string
+ packagesImportMap map[string]string
}
func main() {
- cueCtx := cuecontext.New()
-
targets := []codegenTargets{
{
- schemaPath: "../packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue",
+ modulePath: "../packages/grafana-schema/src/schema/dashboard/v2alpha0/",
outputPath: "../packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen.ts",
+ cueImportsMap: map[string]string{
+ "github.com/grafana/grafana/packages/grafana-schema/src/common": "../packages/grafana-schema/src/common",
+ },
+ packagesImportMap: map[string]string{
+ "common": "@grafana/schema",
+ },
},
}
for _, target := range targets {
- rawSchema, err := os.ReadFile(target.schemaPath)
- if err != nil {
- panic(err)
- }
-
- value := cueCtx.CompileBytes(rawSchema)
- if value.Err() != nil {
- panic(value.Err())
- }
-
codegenPipeline := cog.TypesFromSchema().
- CUEValue("dashboard", value).
- Typescript()
+ CUEModule(
+ target.modulePath,
+ cog.CUEImports(target.cueImportsMap),
+ ).
+ Typescript(cog.TypescriptConfig{
+ ImportsMap: target.packagesImportMap,
+ EnumsAsUnionTypes: true,
+ })
- tsBytes, err := codegenPipeline.Run(context.Background())
+ files, err := codegenPipeline.Run(context.Background())
if err != nil {
panic(err)
}
- if err := os.WriteFile(target.outputPath, tsBytes, 0644); err != nil {
+ if err := os.WriteFile(target.outputPath, files[0].Data, 0644); err != nil {
panic(err)
}
}
diff --git a/kindsv2/go.mod b/kindsv2/go.mod
index ecd83ce978a..820ad5a3065 100644
--- a/kindsv2/go.mod
+++ b/kindsv2/go.mod
@@ -2,13 +2,11 @@ module github.com/grafana/grafana/kindsv2
go 1.23.1
-require (
- cuelang.org/go v0.8.2
- github.com/grafana/cog v0.0.0-20241029201114-f7f7db0c1070
-)
+require github.com/grafana/cog v0.0.5
require (
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect
+ cuelang.org/go v0.8.2 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/proto v1.13.2 // indirect
@@ -36,11 +34,11 @@ require (
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/yalue/merged_fs v1.3.0 // indirect
- golang.org/x/mod v0.21.0 // indirect
- golang.org/x/net v0.30.0 // indirect
+ golang.org/x/mod v0.22.0 // indirect
+ golang.org/x/net v0.31.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/text v0.20.0 // indirect
- golang.org/x/tools v0.26.0 // indirect
+ golang.org/x/tools v0.27.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/kindsv2/go.sum b/kindsv2/go.sum
index c3848f5abe1..79ff5b0bee6 100644
--- a/kindsv2/go.sum
+++ b/kindsv2/go.sum
@@ -26,8 +26,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d h1:hrXbGJ5jgp6yNITzs5o+zXq0V5yT3siNJ+uM8LGwWKk=
github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s=
-github.com/grafana/cog v0.0.0-20241029201114-f7f7db0c1070 h1:ncAkFmIq3UbPiPhQ2CuBzdTuwnDqLsFFNqEIXKaiPGA=
-github.com/grafana/cog v0.0.0-20241029201114-f7f7db0c1070/go.mod h1:FqZi9WZ/Uzvs3tvo7l+OViThCpfvu3KDGDqHCB2LNbg=
+github.com/grafana/cog v0.0.5 h1:BCa+10i3KvV+KMSQuxlN1DS9cZEwN+EAFc7ZmXqHxQE=
+github.com/grafana/cog v0.0.5/go.mod h1:lzetOuhGUl/JaSACiJoHvBokf9/fS6PEFaWZvnQu2vs=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -73,20 +73,20 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
github.com/yalue/merged_fs v1.3.0 h1:qCeh9tMPNy/i8cwDsQTJ5bLr6IRxbs6meakNE5O+wyY=
github.com/yalue/merged_fs v1.3.0/go.mod h1:WqqchfVYQyclV2tnR7wtRhBddzBvLVR83Cjw9BKQw0M=
-golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
-golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
-golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
-golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
+golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
+golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
+golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
-golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
+golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
-golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
-golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
+golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
+golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/package.json b/package.json
index 9f3aed5c838..d4dfc47342b 100644
--- a/package.json
+++ b/package.json
@@ -429,7 +429,6 @@
"react-split-pane@0.1.92": "patch:react-split-pane@npm:0.1.92#.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch",
"history@4.10.1": "patch:history@npm%3A4.10.1#./.yarn/patches/history-npm-4.10.1-ee217563ae.patch",
"redux": "^5.0.0",
- "@storybook/blocks@npm:8.1.6": "patch:@storybook/blocks@npm%3A8.1.6#~/.yarn/patches/@storybook-blocks-npm-8.1.6-892f57a6d7.patch",
"react-grid-layout": "patch:react-grid-layout@npm%3A1.4.4#~/.yarn/patches/react-grid-layout-npm-1.4.4-4024c5395b.patch",
"@grafana/plugin-e2e/@grafana/e2e-selectors": "workspace:*",
"@grafana/scenes/@grafana/e2e-selectors": "workspace:*",
diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts
index 2d78e294e6c..a4add656705 100644
--- a/packages/grafana-data/src/types/featureToggles.gen.ts
+++ b/packages/grafana-data/src/types/featureToggles.gen.ts
@@ -160,6 +160,7 @@ export interface FeatureToggles {
onPremToCloudMigrationsAlerts?: boolean;
onPremToCloudMigrationsAuthApiMig?: boolean;
alertingSaveStatePeriodic?: boolean;
+ scopeApi?: boolean;
promQLScope?: boolean;
logQLScope?: boolean;
sqlExpressions?: boolean;
@@ -240,5 +241,6 @@ export interface FeatureToggles {
jaegerBackendMigration?: boolean;
reportingUseRawTimeRange?: boolean;
alertingUIOptimizeReducer?: boolean;
+ azureMonitorEnableUserAuth?: boolean;
alertingNotificationsStepMode?: boolean;
}
diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen.ts
index 23dfe83a255..dd71e19ba59 100644
--- a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen.ts
+++ b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.gen.ts
@@ -1,5 +1,8 @@
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
+import * as common from '@grafana/schema';
+
+
export interface DashboardV2Spec {
// Unique numeric identifier for the dashboard.
// `id` is internal to a specific Grafana instance. `uid` should be used to identify a dashboard across Grafana instances.
@@ -42,7 +45,7 @@ export interface DashboardV2Spec {
export const defaultDashboardV2Spec = (): DashboardV2Spec => ({
title: "",
- cursorSync: DashboardCursorSync.Off,
+ cursorSync: "Off",
preload: false,
editable: true,
links: [],
@@ -69,13 +72,9 @@ export const defaultAnnotationPanelFilter = (): AnnotationPanelFilter => ({
// "Off" for no shared crosshair or tooltip (default).
// "Crosshair" for shared crosshair.
// "Tooltip" for shared crosshair AND shared tooltip.
-export enum DashboardCursorSync {
- Off = "Off",
- Crosshair = "Crosshair",
- Tooltip = "Tooltip",
-}
+export type DashboardCursorSync = "Off" | "Crosshair" | "Tooltip";
-export const defaultDashboardCursorSync = (): DashboardCursorSync => (DashboardCursorSync.Off);
+export const defaultDashboardCursorSync = (): DashboardCursorSync => ("Off");
// Links with references to other dashboards or external resources
export interface DashboardLink {
@@ -104,7 +103,7 @@ export interface DashboardLink {
export const defaultDashboardLink = (): DashboardLink => ({
title: "",
- type: DashboardLinkType.Link,
+ type: "link",
icon: "",
tooltip: "",
tags: [],
@@ -135,8 +134,7 @@ export interface DataTransformerConfig {
// Optional frame matcher. When missing it will be applied to all results
filter?: MatcherConfig;
// Where to pull DataFrames from as input to transformation
- // replaced with common.DataTopic
- topic?: "series" | "annotations" | "alertStates";
+ topic?: common.DataTopic;
// Options to be passed to the transformer
// Valid options depend on the transformer id
options: any;
@@ -247,7 +245,7 @@ export const defaultMatcherConfig = (): MatcherConfig => ({
});
export interface Threshold {
- value: number | null;
+ value: number;
color: string;
}
@@ -256,12 +254,9 @@ export const defaultThreshold = (): Threshold => ({
color: "",
});
-export enum ThresholdsMode {
- Absolute = "absolute",
- Percentage = "percentage",
-}
+export type ThresholdsMode = "absolute" | "percentage";
-export const defaultThresholdsMode = (): ThresholdsMode => (ThresholdsMode.Absolute);
+export const defaultThresholdsMode = (): ThresholdsMode => ("absolute");
export interface ThresholdsConfig {
mode: ThresholdsMode;
@@ -269,7 +264,7 @@ export interface ThresholdsConfig {
}
export const defaultThresholdsConfig = (): ThresholdsConfig => ({
- mode: ThresholdsMode.Absolute,
+ mode: "absolute",
steps: [],
});
@@ -282,14 +277,9 @@ export const defaultValueMapping = (): ValueMapping => (defaultValueMap());
// `range`: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.
// `regex`: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.
// `special`: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.
-export enum MappingType {
- Value = "value",
- Range = "range",
- Regex = "regex",
- Special = "special",
-}
+export type MappingType = "value" | "range" | "regex" | "special";
-export const defaultMappingType = (): MappingType => (MappingType.Value);
+export const defaultMappingType = (): MappingType => ("value");
// Maps text values to a color or different display text and color.
// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.
@@ -365,22 +355,15 @@ export interface SpecialValueMap {
export const defaultSpecialValueMap = (): SpecialValueMap => ({
type: "special",
options: {
- match: SpecialValueMatch.True,
+ match: "true",
result: defaultValueMappingResult(),
},
});
// Special value types supported by the `SpecialValueMap`
-export enum SpecialValueMatch {
- True = "true",
- False = "false",
- Null = "null",
- NotANumber = "nan",
- NullNan = "null+nan",
- Empty = "empty",
-}
+export type SpecialValueMatch = "true" | "false" | "null" | "nan" | "null+nan" | "empty";
-export const defaultSpecialValueMatch = (): SpecialValueMatch => (SpecialValueMatch.True);
+export const defaultSpecialValueMatch = (): SpecialValueMatch => ("true");
// Result used as replacement with text and color when the value matches
export interface ValueMappingResult {
@@ -415,34 +398,14 @@ export const defaultValueMappingResult = (): ValueMappingResult => ({
// `continuous-purples`: Continuous Purple palette mode
// `shades`: Shades of a single color. Specify a single color, useful in an override rule.
// `fixed`: Fixed color mode. Specify a single color, useful in an override rule.
-export enum FieldColorModeId {
- Thresholds = "thresholds",
- PaletteClassic = "palette-classic",
- PaletteClassicByName = "palette-classic-by-name",
- ContinuousGrYlRd = "continuous-GrYlRd",
- ContinuousRdYlGr = "continuous-RdYlGr",
- ContinuousBlYlRd = "continuous-BlYlRd",
- ContinuousYlRd = "continuous-YlRd",
- ContinuousBlPu = "continuous-BlPu",
- ContinuousYlBl = "continuous-YlBl",
- ContinuousBlues = "continuous-blues",
- ContinuousReds = "continuous-reds",
- ContinuousGreens = "continuous-greens",
- ContinuousPurples = "continuous-purples",
- Fixed = "fixed",
- Shades = "shades",
-}
+export type FieldColorModeId = "thresholds" | "palette-classic" | "palette-classic-by-name" | "continuous-GrYlRd" | "continuous-RdYlGr" | "continuous-BlYlRd" | "continuous-YlRd" | "continuous-BlPu" | "continuous-YlBl" | "continuous-blues" | "continuous-reds" | "continuous-greens" | "continuous-purples" | "fixed" | "shades";
-export const defaultFieldColorModeId = (): FieldColorModeId => (FieldColorModeId.Thresholds);
+export const defaultFieldColorModeId = (): FieldColorModeId => ("thresholds");
// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.
-export enum FieldColorSeriesByMode {
- Min = "min",
- Max = "max",
- Last = "last",
-}
+export type FieldColorSeriesByMode = "min" | "max" | "last";
-export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => (FieldColorSeriesByMode.Min);
+export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min");
// Map a field to a color.
export interface FieldColor {
@@ -455,16 +418,13 @@ export interface FieldColor {
}
export const defaultFieldColor = (): FieldColor => ({
- mode: FieldColorModeId.Thresholds,
+ mode: "thresholds",
});
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
-export enum DashboardLinkType {
- Link = "link",
- Dashboards = "dashboards",
-}
+export type DashboardLinkType = "link" | "dashboards";
-export const defaultDashboardLinkType = (): DashboardLinkType => (DashboardLinkType.Link);
+export const defaultDashboardLinkType = (): DashboardLinkType => ("link");
// --- Common types ---
export interface Kind {
@@ -503,11 +463,9 @@ export const defaultVizConfigKind = (): VizConfigKind => ({
});
export interface AnnotationQuerySpec {
- datasource: DataSourceRef;
+ datasource?: DataSourceRef;
query: DataQueryKind;
- // TODO: Should be figured out based on datasource (Grafana ds)
- // builtIn?: int
- // Below are currently existing options for annotation queries
+ builtIn?: boolean;
enable: boolean;
filter: AnnotationPanelFilter;
hide: boolean;
@@ -516,7 +474,6 @@ export interface AnnotationQuerySpec {
}
export const defaultAnnotationQuerySpec = (): AnnotationQuerySpec => ({
- datasource: defaultDataSourceRef(),
query: defaultDataQueryKind(),
enable: false,
filter: defaultAnnotationPanelFilter(),
@@ -542,6 +499,7 @@ export interface QueryOptionsSpec {
queryCachingTTL?: number;
interval?: string;
cacheTimeout?: string;
+ hideTimeOverride?: boolean;
}
export const defaultQueryOptionsSpec = (): QueryOptionsSpec => ({
@@ -560,14 +518,13 @@ export const defaultDataQueryKind = (): DataQueryKind => ({
export interface PanelQuerySpec {
query: DataQueryKind;
- datasource: DataSourceRef;
+ datasource?: DataSourceRef;
refId: string;
hidden: boolean;
}
export const defaultPanelQuerySpec = (): PanelQuerySpec => ({
query: defaultDataQueryKind(),
- datasource: defaultDataSourceRef(),
refId: "",
hidden: false,
});
@@ -782,7 +739,7 @@ export interface CustomFormatterVariable {
export const defaultCustomFormatterVariable = (): CustomFormatterVariable => ({
name: "",
- type: VariableType.Query,
+ type: "query",
multi: false,
includeAll: false,
});
@@ -813,7 +770,7 @@ export const defaultVariableCustomFormatterFn = (): VariableCustomFormatterFn =>
value: {},
legacyVariableModel: {
name: "",
- type: VariableType.Query,
+ type: "query",
multi: false,
includeAll: false,
},
@@ -828,20 +785,9 @@ export const defaultVariableCustomFormatterFn = (): VariableCustomFormatterFn =>
// `textbox`: Display a free text input field with an optional default value.
// `custom`: Define the variable options manually using a comma-separated list.
// `system`: Variables defined by Grafana. See: https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables
-export enum VariableType {
- Query = "query",
- Adhoc = "adhoc",
- Groupby = "groupby",
- Constant = "constant",
- Datasource = "datasource",
- Interval = "interval",
- Textbox = "textbox",
- Custom = "custom",
- System = "system",
- Snapshot = "snapshot",
-}
+export type VariableType = "query" | "adhoc" | "groupby" | "constant" | "datasource" | "interval" | "textbox" | "custom" | "system" | "snapshot";
-export const defaultVariableType = (): VariableType => (VariableType.Query);
+export const defaultVariableType = (): VariableType => ("query");
// Sort variable options
// Accepted values are:
@@ -855,41 +801,23 @@ export const defaultVariableType = (): VariableType => (VariableType.Query);
// `naturalAsc`: Natural ASC
// `naturalDesc`: Natural DESC
// VariableSort enum with default value
-export enum VariableSort {
- Disabled = "disabled",
- AlphabeticalAsc = "alphabeticalAsc",
- AlphabeticalDesc = "alphabeticalDesc",
- NumericalAsc = "numericalAsc",
- NumericalDesc = "numericalDesc",
- AlphabeticalCaseInsensitiveAsc = "alphabeticalCaseInsensitiveAsc",
- AlphabeticalCaseInsensitiveDesc = "alphabeticalCaseInsensitiveDesc",
- NaturalAsc = "naturalAsc",
- NaturalDesc = "naturalDesc",
-}
+export type VariableSort = "disabled" | "alphabeticalAsc" | "alphabeticalDesc" | "numericalAsc" | "numericalDesc" | "alphabeticalCaseInsensitiveAsc" | "alphabeticalCaseInsensitiveDesc" | "naturalAsc" | "naturalDesc";
-export const defaultVariableSort = (): VariableSort => (VariableSort.Disabled);
+export const defaultVariableSort = (): VariableSort => ("disabled");
// Options to config when to refresh a variable
// `never`: Never refresh the variable
// `onDashboardLoad`: Queries the data source every time the dashboard loads.
// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes.
-export enum VariableRefresh {
- Never = "never",
- OnDashboardLoad = "onDashboardLoad",
- OnTimeRangeChanged = "onTimeRangeChanged",
-}
+export type VariableRefresh = "never" | "onDashboardLoad" | "onTimeRangeChanged";
-export const defaultVariableRefresh = (): VariableRefresh => (VariableRefresh.Never);
+export const defaultVariableRefresh = (): VariableRefresh => ("never");
// Determine if the variable shows on dashboard
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing).
-export enum VariableHide {
- DontHide = "dontHide",
- HideLabel = "hideLabel",
- HideVariable = "hideVariable",
-}
+export type VariableHide = "dontHide" | "hideLabel" | "hideVariable";
-export const defaultVariableHide = (): VariableHide => (VariableHide.DontHide);
+export const defaultVariableHide = (): VariableHide => ("dontHide");
// FIXME: should we introduce this? --- Variable value option
export interface VariableValueOption {
@@ -927,7 +855,7 @@ export interface QueryVariableSpec {
refresh: VariableRefresh;
skipUrlSync: boolean;
description?: string;
- datasource: DataSourceRef;
+ datasource?: DataSourceRef;
query: string | DataQueryKind;
regex: string;
sort: VariableSort;
@@ -942,13 +870,12 @@ export interface QueryVariableSpec {
export const defaultQueryVariableSpec = (): QueryVariableSpec => ({
name: "",
current: { text: "", value: "", },
- hide: VariableHide.DontHide,
- refresh: VariableRefresh.Never,
+ hide: "dontHide",
+ refresh: "never",
skipUrlSync: false,
- datasource: defaultDataSourceRef(),
query: "",
regex: "",
- sort: VariableSort.Disabled,
+ sort: "disabled",
options: [],
multi: false,
includeAll: false,
@@ -980,7 +907,7 @@ export const defaultTextVariableSpec = (): TextVariableSpec => ({
name: "",
current: { text: "", value: "", },
query: "",
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1010,7 +937,7 @@ export const defaultConstantVariableSpec = (): ConstantVariableSpec => ({
name: "",
query: "",
current: { text: "", value: "", },
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1046,14 +973,14 @@ export interface DatasourceVariableSpec {
export const defaultDatasourceVariableSpec = (): DatasourceVariableSpec => ({
name: "",
pluginId: "",
- refresh: VariableRefresh.Never,
+ refresh: "never",
regex: "",
current: { text: "", value: "", },
defaultOptionEnabled: false,
options: [],
multi: false,
includeAll: false,
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1092,8 +1019,8 @@ export const defaultIntervalVariableSpec = (): IntervalVariableSpec => ({
auto: false,
auto_min: "",
auto_count: 0,
- refresh: VariableRefresh.Never,
- hide: VariableHide.DontHide,
+ refresh: "never",
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1130,7 +1057,7 @@ export const defaultCustomVariableSpec = (): CustomVariableSpec => ({
options: [],
multi: false,
includeAll: false,
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1148,7 +1075,7 @@ export const defaultCustomVariableKind = (): CustomVariableKind => ({
// GroupBy variable specification
export interface GroupByVariableSpec {
name: string;
- datasource: DataSourceRef;
+ datasource?: DataSourceRef;
current: VariableOption;
options: VariableOption[];
multi: boolean;
@@ -1162,12 +1089,11 @@ export interface GroupByVariableSpec {
export const defaultGroupByVariableSpec = (): GroupByVariableSpec => ({
name: "",
- datasource: defaultDataSourceRef(),
current: { text: "", value: "", },
options: [],
multi: false,
includeAll: false,
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
@@ -1185,7 +1111,7 @@ export const defaultGroupByVariableKind = (): GroupByVariableKind => ({
// Adhoc variable specification
export interface AdhocVariableSpec {
name: string;
- datasource: DataSourceRef;
+ datasource?: DataSourceRef;
baseFilters: AdHocFilterWithLabels[];
filters: AdHocFilterWithLabels[];
defaultKeys: MetricFindValue[];
@@ -1197,11 +1123,10 @@ export interface AdhocVariableSpec {
export const defaultAdhocVariableSpec = (): AdhocVariableSpec => ({
name: "",
- datasource: defaultDataSourceRef(),
baseFilters: [],
filters: [],
defaultKeys: [],
- hide: VariableHide.DontHide,
+ hide: "dontHide",
skipUrlSync: false,
});
diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue
index e7922f46eae..6be276b73d1 100644
--- a/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue
+++ b/packages/grafana-schema/src/schema/dashboard/v2alpha0/dashboard.schema.cue
@@ -1,4 +1,8 @@
-package dashboard
+package v2alpha0
+
+import (
+ "github.com/grafana/grafana/packages/grafana-schema/src/common"
+)
DashboardV2Spec: {
// Unique numeric identifier for the dashboard.
@@ -113,7 +117,7 @@ DataTransformerConfig: {
// Optional frame matcher. When missing it will be applied to all results
filter?: MatcherConfig
// Where to pull DataFrames from as input to transformation
- topic?: "series" | "annotations" | "alertStates" // replaced with common.DataTopic
+ topic?: common.DataTopic
// Options to be passed to the transformer
// Valid options depend on the transformer id
options: _
@@ -217,7 +221,7 @@ MatcherConfig: {
}
Threshold: {
- value: number | null
+ value: number
color: string
}
@@ -235,7 +239,7 @@ ValueMapping: ValueMap | RangeMap | RegexMap | SpecialValueMap
// `range`: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.
// `regex`: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.
// `special`: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.
-MappingType: "value" | "range" | "regex" | "special"
+MappingType: "value" | "range" | "regex" | "special" @cog(kind="enum",memberNames="ValueToText|RangeToText|RegexToText|SpecialValue")
// Maps text values to a color or different display text and color.
// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.
@@ -287,7 +291,7 @@ SpecialValueMap: {
}
// Special value types supported by the `SpecialValueMap`
-SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty"
+SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty" @cog(kind="enum",memberNames="True|False|Null|NaN|NullAndNaN|Empty")
// Result used as replacement with text and color when the value matches
ValueMappingResult: {
@@ -358,12 +362,9 @@ VizConfigKind: {
}
AnnotationQuerySpec: {
- datasource: DataSourceRef
+ datasource?: DataSourceRef
query: DataQueryKind
-
- // TODO: Should be figured out based on datasource (Grafana ds)
- // builtIn?: int
- // Below are currently existing options for annotation queries
+ builtIn?: bool
enable: bool
filter: AnnotationPanelFilter
hide: bool
@@ -383,6 +384,7 @@ QueryOptionsSpec: {
queryCachingTTL?: int
interval?: string
cacheTimeout?: string
+ hideTimeOverride?: bool
}
DataQueryKind: {
@@ -393,7 +395,7 @@ DataQueryKind: {
PanelQuerySpec: {
query: DataQueryKind
- datasource: DataSourceRef
+ datasource?: DataSourceRef
refId: string
hidden: bool
@@ -593,7 +595,7 @@ QueryVariableSpec: {
refresh: VariableRefresh
skipUrlSync: bool | *false
description?: string
- datasource: DataSourceRef | *{}
+ datasource?: DataSourceRef
query: string | DataQueryKind | *""
regex: string | *""
sort: VariableSort
@@ -727,7 +729,7 @@ CustomVariableKind: {
// GroupBy variable specification
GroupByVariableSpec: {
name: string | *""
- datasource: DataSourceRef | *{}
+ datasource?: DataSourceRef
current: VariableOption | *{
text: ""
value: ""
@@ -751,7 +753,7 @@ GroupByVariableKind: {
// Adhoc variable specification
AdhocVariableSpec: {
name: string | *""
- datasource: DataSourceRef | *{}
+ datasource?: DataSourceRef
baseFilters: [...AdHocFilterWithLabels] | *[]
filters: [...AdHocFilterWithLabels] | *[]
defaultKeys: [...MetricFindValue] | *[]
diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha0/examples.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha0/examples.ts
index 5b98aaf0854..801deb57bc9 100644
--- a/packages/grafana-schema/src/schema/dashboard/v2alpha0/examples.ts
+++ b/packages/grafana-schema/src/schema/dashboard/v2alpha0/examples.ts
@@ -1,36 +1,32 @@
-import { DashboardCursorSync, DashboardV2Spec } from './dashboard.gen';
+import { DashboardV2Spec } from './dashboard.gen';
export const handyTestingSchema: DashboardV2Spec = {
id: 1,
title: 'Default Dashboard',
description: 'This is a default dashboard',
- cursorSync: DashboardCursorSync.Off,
+ cursorSync: 'Off',
liveNow: false,
preload: false,
editable: true,
- links: [],
- tags: [],
- schemaVersion: 39,
+ schemaVersion: 40,
+ tags: ['tag1', 'tag2'],
timeSettings: {
- timezone: 'browser',
- from: 'now-6h',
- to: 'now',
- autoRefresh: '10s',
- autoRefreshIntervals: ['10s', '1m', '5m', '15m', '30m', '1h', '6h', '12h', '1d'],
- quickRanges: ['now/d', 'now/w', 'now/M', 'now/y'],
- hideTimepicker: false,
- weekStart: 'sunday',
+ autoRefresh: '5s',
+ autoRefreshIntervals: ['5s', '10s', '30s'],
fiscalYearStartMonth: 1,
+ from: 'now-1h',
+ hideTimepicker: false,
+ nowDelay: '1m',
+ quickRanges: [],
+ timezone: 'UTC',
+ to: 'now',
+ weekStart: 'monday',
},
-
+ annotations: [],
elements: {
- timeSeriesTest: {
+ 'test-panel-uid': {
kind: 'Panel',
spec: {
- title: 'Time Series Test',
- description: 'This is a test panel',
- uid: 'timeSeriesTest',
- links: [],
data: {
kind: 'QueryGroup',
spec: {
@@ -38,44 +34,63 @@ export const handyTestingSchema: DashboardV2Spec = {
{
kind: 'PanelQuery',
spec: {
+ refId: 'A',
+ datasource: {
+ type: 'prometheus',
+ uid: 'datasource1',
+ },
query: {
kind: 'prometheus',
spec: {
- query: 'up',
+ expr: 'test-query',
},
},
- datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
hidden: false,
- refId: 'A',
},
},
],
+ queryOptions: {
+ timeFrom: '1h',
+ maxDataPoints: 100,
+ timeShift: '1h',
+ queryCachingTTL: 60,
+ interval: '1m',
+ cacheTimeout: '1m',
+ hideTimeOverride: false,
+ },
transformations: [
{
kind: 'limit',
spec: {
- id: 'limit', // id is competing w/ kind
+ id: 'limit',
+ disabled: false,
+ filter: {
+ id: 'byValue',
+ options: {
+ reducer: 'sum',
+ },
+ },
options: {
limit: 10,
},
},
},
],
- queryOptions: {
- maxDataPoints: 100,
- cacheTimeout: '1m',
- },
},
},
+ description: 'Test Description',
+ links: [],
+ title: 'Test Panel',
+ uid: 'test-panel-uid',
vizConfig: {
kind: 'timeseries',
spec: {
- pluginVersion: '11.0.0',
- options: {},
fieldConfig: {
defaults: {},
overrides: [],
},
+ options: {},
+ pluginVersion: '7.0.0',
},
},
},
@@ -88,62 +103,252 @@ export const handyTestingSchema: DashboardV2Spec = {
{
kind: 'GridLayoutItem',
spec: {
- element: { kind: 'ElementReference', name: 'timeSeriesTest' },
+ element: {
+ kind: 'ElementReference',
+ name: 'test-panel-uid',
+ },
+ height: 0,
+ width: 0,
x: 0,
y: 0,
- width: 12,
- height: 6,
},
},
],
},
},
- variables: [],
- annotations: [
+ links: [
{
- kind: 'AnnotationQuery',
+ asDropdown: false,
+ icon: '',
+ includeVars: false,
+ keepTime: false,
+ tags: [],
+ targetBlank: false,
+ title: 'Test Link',
+ tooltip: '',
+ type: 'dashboards',
+ url: 'http://test.com',
+ },
+ ],
+
+ variables: [
+ {
+ kind: 'QueryVariable',
spec: {
- datasource: { type: 'datasource', uid: 'grafana' },
- query: {
- kind: 'grafana',
- spec: {
- queryType: 'timeRegions',
- matchAny: false,
- timeRegion: {
- from: '12:27',
- fromDayOfWeek: 2,
- timezone: 'browser',
- to: '11:30',
- toDayOfWeek: 2,
- },
- },
+ allValue: '*',
+ current: {
+ text: 'text1',
+ value: 'value1',
},
- enable: true,
- filter: {
- ids: [],
+ datasource: {
+ type: 'prometheus',
+ uid: 'datasource1',
},
- hide: false,
- iconColor: 'blue',
- name: 'Grafana annotations',
+ definition: 'definition1',
+ description: 'A query variable',
+ hide: 'dontHide',
+ includeAll: true,
+ label: 'Query Variable',
+ multi: true,
+ name: 'queryVar',
+ options: [],
+ query: 'query1',
+ refresh: 'onDashboardLoad',
+ regex: 'regex1',
+ skipUrlSync: false,
+ sort: 'disabled',
},
},
{
- kind: 'AnnotationQuery',
+ kind: 'CustomVariable',
spec: {
- datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
- query: {
- kind: 'prometheus',
- spec: {
- query: 'up',
+ allValue: 'All',
+ current: {
+ text: 'option1',
+ value: 'option1',
+ },
+ description: 'A custom variable',
+ hide: 'dontHide',
+ includeAll: true,
+ label: 'Custom Variable',
+ multi: true,
+ name: 'customVar',
+ options: [
+ {
+ selected: true,
+ text: 'option1',
+ value: 'option1',
},
+ {
+ selected: false,
+ text: 'option2',
+ value: 'option2',
+ },
+ ],
+ query: 'option1, option2',
+ skipUrlSync: false,
+ },
+ },
+ {
+ kind: 'DatasourceVariable',
+ spec: {
+ allValue: undefined,
+ current: {
+ text: 'text1',
+ value: 'value1',
},
- enable: true,
- filter: {
- ids: [],
+ defaultOptionEnabled: true,
+ description: 'A datasource variable',
+ hide: 'dontHide',
+ includeAll: false,
+ label: 'Datasource Variable',
+ multi: false,
+ name: 'datasourceVar',
+ options: [],
+ pluginId: 'datasource1',
+ refresh: 'onDashboardLoad',
+ regex: 'regex1',
+ skipUrlSync: false,
+ },
+ },
+ {
+ kind: 'ConstantVariable',
+ spec: {
+ current: {
+ text: 'value4',
+ value: 'value4',
},
- hide: false,
- iconColor: 'red',
- name: 'Prometheus annotations',
+ description: 'A constant variable',
+ hide: 'dontHide',
+ label: 'Constant Variable',
+ name: 'constantVar',
+ query: 'value4',
+ skipUrlSync: true,
+ },
+ },
+ {
+ kind: 'IntervalVariable',
+ spec: {
+ auto: false,
+ auto_count: 10,
+ auto_min: '1m',
+ current: {
+ text: '1m',
+ value: '1m',
+ },
+ description: 'An interval variable',
+ hide: 'dontHide',
+ label: 'Interval Variable',
+ name: 'intervalVar',
+ options: [
+ {
+ selected: true,
+ text: '1m',
+ value: '1m',
+ },
+ {
+ selected: false,
+ text: '5m',
+ value: '5m',
+ },
+ {
+ selected: false,
+ text: '10m',
+ value: '10m',
+ },
+ ],
+ query: '1m,5m,10m',
+ refresh: 'onDashboardLoad',
+ skipUrlSync: false,
+ },
+ },
+ {
+ kind: 'TextVariable',
+ spec: {
+ current: {
+ text: 'value6',
+ value: 'value6',
+ },
+ description: 'A text variable',
+ hide: 'dontHide',
+ label: 'Text Variable',
+ name: 'textVar',
+ query: 'value6',
+ skipUrlSync: false,
+ },
+ },
+ {
+ kind: 'GroupByVariable',
+ spec: {
+ current: {
+ text: 'text7',
+ value: 'value7',
+ },
+ datasource: {
+ type: 'prometheus',
+ uid: 'datasource2',
+ },
+ description: 'A group by variable',
+ hide: 'dontHide',
+ includeAll: false,
+ label: 'Group By Variable',
+ multi: false,
+ name: 'groupByVar',
+ options: [
+ {
+ text: 'option1',
+ value: 'option1',
+ },
+ {
+ text: 'option2',
+ value: 'option2',
+ },
+ ],
+ skipUrlSync: false,
+ },
+ },
+ {
+ kind: 'AdhocVariable',
+ spec: {
+ baseFilters: [
+ {
+ condition: 'AND',
+ key: 'key1',
+ operator: '=',
+ value: 'value1',
+ },
+ {
+ condition: 'OR',
+ key: 'key2',
+ operator: '=',
+ value: 'value2',
+ },
+ ],
+ datasource: {
+ type: 'prometheus',
+ uid: 'datasource3',
+ },
+ defaultKeys: [
+ {
+ expandable: true,
+ group: 'defaultGroup1',
+ text: 'defaultKey1',
+ value: 'defaultKey1',
+ },
+ ],
+ description: 'An adhoc variable',
+ filters: [
+ {
+ condition: 'AND',
+ key: 'key3',
+ operator: '=',
+ value: 'value3',
+ },
+ ],
+ hide: 'dontHide',
+ label: 'Adhoc Variable',
+ name: 'adhocVar',
+ skipUrlSync: false,
},
},
],
diff --git a/packages/grafana-ui/.storybook/copyAssets.ts b/packages/grafana-ui/.storybook/copyAssets.ts
new file mode 100644
index 00000000000..ecd7c2663f6
--- /dev/null
+++ b/packages/grafana-ui/.storybook/copyAssets.ts
@@ -0,0 +1,62 @@
+// This script is used to copy assets from the public folder to a temporary static folder within
+// the .storybook directory.
+// We selectively limit assets that are uploaded to the Storybook bucket to prevent rate limiting
+// when publishing new storybook.
+// Note: Storybook has a static copying feature but it copies entire directories which can contain thousands of icons.
+
+import { copySync, emptyDirSync, lstatSync } from 'fs-extra';
+import { resolve } from 'node:path';
+
+// avoid importing from @grafana/data to prevent error: window is not defined
+import { availableIconsIndex, IconName } from '../../grafana-data/src/types/icon';
+import { getIconSubDir } from '../src/components/Icon/utils';
+
+// doesn't require uploading 1000s of unused assets.
+const iconPaths = Object.keys(availableIconsIndex)
+ .filter((iconName) => !iconName.startsWith('fa '))
+ .map((iconName) => {
+ const subDir = getIconSubDir(iconName as IconName, 'default');
+ return {
+ from: `../../../public/img/icons/${subDir}/${iconName}.svg`,
+ to: `./static/public/img/icons/${subDir}/${iconName}.svg`,
+ };
+ });
+
+export function copyAssetsSync() {
+ const assets = [
+ {
+ from: '../../../public/fonts',
+ to: './static/public/fonts',
+ },
+ {
+ from: '../../../public/img/grafana_text_logo-dark.svg',
+ to: './static/public/img/grafana_text_logo-dark.svg',
+ },
+ {
+ from: '../../../public/img/grafana_text_logo-light.svg',
+ to: './static/public/img/grafana_text_logo-light.svg',
+ },
+ {
+ from: '../../../public/img/fav32.png',
+ to: './static/public/img/fav32.png',
+ },
+ {
+ from: '../../../public/lib',
+ to: './static/public/lib',
+ },
+ ...iconPaths,
+ ];
+
+ const staticDir = resolve(__dirname, 'static', 'public');
+
+ emptyDirSync(staticDir);
+
+ for (const asset of assets) {
+ const fromPath = resolve(__dirname, asset.from);
+ const toPath = resolve(__dirname, asset.to);
+
+ copySync(fromPath, toPath, {
+ filter: (src) => !lstatSync(src).isSymbolicLink(),
+ });
+ }
+}
diff --git a/packages/grafana-ui/.storybook/main.ts b/packages/grafana-ui/.storybook/main.ts
index f8bf57783db..6314014c9f9 100644
--- a/packages/grafana-ui/.storybook/main.ts
+++ b/packages/grafana-ui/.storybook/main.ts
@@ -1,8 +1,6 @@
-import path, { dirname, join } from 'path';
+import path, { dirname, join } from 'node:path';
import type { StorybookConfig } from '@storybook/react-webpack5';
-// avoid importing from @grafana/data to prevent node error: ERR_REQUIRE_ESM
-import { availableIconsIndex, IconName } from '../../grafana-data/src/types/icon';
-import { getIconSubDir } from '../src/components/Icon/utils';
+import { copyAssetsSync } from './copyAssets';
// Internal stories should only be visible during development
const storyGlob =
@@ -12,17 +10,8 @@ const storyGlob =
const stories = ['../src/Intro.mdx', storyGlob];
-// We limit icon paths to only the available icons so publishing
-// doesn't require uploading 1000s of unused assets.
-const iconPaths = Object.keys(availableIconsIndex)
- .filter((iconName) => !iconName.startsWith('fa '))
- .map((iconName) => {
- const subDir = getIconSubDir(iconName as IconName, 'default');
- return {
- from: `../../../public/img/icons/${subDir}/${iconName}.svg`,
- to: `/public/img/icons/${subDir}/${iconName}.svg`,
- };
- });
+// Copy the assets required by storybook before starting the storybook server.
+copyAssetsSync();
const mainConfig: StorybookConfig = {
stories,
@@ -45,17 +34,18 @@ const mainConfig: StorybookConfig = {
url: false,
importLoaders: 2,
},
+ sassLoaderOptions: {
+ sassOptions: {
+ // silencing these warnings since we're planning to remove sass when angular is gone
+ silenceDeprecations: ['import', 'global-builtin'],
+ },
+ },
},
},
getAbsolutePath('@storybook/addon-storysource'),
getAbsolutePath('storybook-dark-mode'),
- getAbsolutePath('@storybook/addon-mdx-gfm'),
getAbsolutePath('@storybook/addon-webpack5-compiler-swc'),
],
- core: {},
- docs: {
- autodocs: true,
- },
framework: {
name: getAbsolutePath('@storybook/react-webpack5'),
options: {
@@ -66,29 +56,7 @@ const mainConfig: StorybookConfig = {
},
},
logLevel: 'debug',
- staticDirs: [
- {
- from: '../../../public/fonts',
- to: '/public/fonts',
- },
- {
- from: '../../../public/img/grafana_text_logo-dark.svg',
- to: '/public/img/grafana_text_logo-dark.svg',
- },
- {
- from: '../../../public/img/grafana_text_logo-light.svg',
- to: '/public/img/grafana_text_logo-light.svg',
- },
- {
- from: '../../../public/img/fav32.png',
- to: '/public/img/fav32.png',
- },
- {
- from: '../../../public/lib',
- to: '/public/lib',
- },
- ...iconPaths,
- ],
+ staticDirs: ['static'],
typescript: {
check: true,
reactDocgen: 'react-docgen-typescript',
diff --git a/packages/grafana-ui/.storybook/preview.ts b/packages/grafana-ui/.storybook/preview.ts
index 28110965ade..cc4be9bfbe8 100644
--- a/packages/grafana-ui/.storybook/preview.ts
+++ b/packages/grafana-ui/.storybook/preview.ts
@@ -46,7 +46,6 @@ const preview: Preview = {
knobs: {
disable: true,
},
- layout: 'fullscreen',
options: {
// Sort stories first by Docs Overview, then alphabetically
// We should be able to use the builtin alphabetical sort, but is broken in SB 7.0
@@ -83,6 +82,7 @@ const preview: Preview = {
},
},
},
+ tags: ['autodocs'],
};
export default preview;
diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json
index 9b3f5d41a0e..d9282c115fb 100644
--- a/packages/grafana-ui/package.json
+++ b/packages/grafana-ui/package.json
@@ -118,22 +118,22 @@
"@faker-js/faker": "^9.0.0",
"@grafana/tsconfig": "^2.0.0",
"@rollup/plugin-node-resolve": "15.3.0",
- "@storybook/addon-a11y": "^8.1.6",
- "@storybook/addon-actions": "^8.1.6",
- "@storybook/addon-docs": "^8.1.6",
- "@storybook/addon-essentials": "^8.1.6",
- "@storybook/addon-mdx-gfm": "^8.1.6",
- "@storybook/addon-storysource": "^8.1.6",
- "@storybook/addon-webpack5-compiler-swc": "^1.0.2",
- "@storybook/blocks": "patch:@storybook/blocks@npm%3A8.1.6#~/.yarn/patches/@storybook-blocks-npm-8.1.6-892f57a6d7.patch",
- "@storybook/components": "^8.1.6",
- "@storybook/core-events": "^8.1.6",
+ "@storybook/addon-a11y": "^8.4.2",
+ "@storybook/addon-actions": "^8.4.2",
+ "@storybook/addon-docs": "^8.4.2",
+ "@storybook/addon-essentials": "^8.4.2",
+ "@storybook/addon-storysource": "^8.4.2",
+ "@storybook/addon-webpack5-compiler-swc": "^1.0.5",
+ "@storybook/blocks": "^8.4.2",
+ "@storybook/components": "^8.4.2",
+ "@storybook/core-events": "^8.4.2",
+ "@storybook/manager-api": "^8.4.2",
"@storybook/mdx2-csf": "1.1.0",
"@storybook/preset-scss": "1.0.3",
- "@storybook/preview-api": "^8.1.6",
- "@storybook/react": "^8.1.6",
- "@storybook/react-webpack5": "^8.1.6",
- "@storybook/theming": "^8.1.6",
+ "@storybook/preview-api": "^8.4.2",
+ "@storybook/react": "^8.4.2",
+ "@storybook/react-webpack5": "^8.4.2",
+ "@storybook/theming": "^8.4.2",
"@testing-library/dom": "10.4.0",
"@testing-library/jest-dom": "6.6.3",
"@testing-library/react": "16.0.1",
@@ -166,6 +166,7 @@
"csstype": "3.1.3",
"esbuild": "0.24.0",
"expose-loader": "5.0.0",
+ "fs-extra": "^11.2.0",
"mock-raf": "1.0.1",
"process": "^0.11.10",
"react": "18.2.0",
@@ -180,8 +181,8 @@
"rollup-plugin-node-externals": "^7.1.3",
"rollup-plugin-svg-import": "3.0.0",
"sass-loader": "16.0.3",
- "storybook": "^8.1.6",
- "storybook-dark-mode": "^4.0.1",
+ "storybook": "^8.4.2",
+ "storybook-dark-mode": "4.0.1",
"style-loader": "4.0.0",
"typescript": "5.5.4",
"webpack": "5.95.0"
diff --git a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.mdx b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.mdx
index 56c887844ec..2d6433d00c4 100644
--- a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.mdx
+++ b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.mdx
@@ -1,6 +1,6 @@
-import { Preview, ArgTypes } from '@storybook/blocks';
+import { Canvas, ArgTypes } from '@storybook/blocks';
import { AutoSaveField } from './AutoSaveField';
-import { Basic } from './AutoSaveField.story.tsx';
+import * as AutoSaveFieldStories from './AutoSaveField.story';
# AutoSaveField
@@ -217,9 +217,7 @@ The `AutoSaveField`component is comprised of:
{' '}
-
-
-
+
### Placement
diff --git a/packages/grafana-ui/src/components/Button/Button.mdx b/packages/grafana-ui/src/components/Button/Button.mdx
index cce79cbf3bd..48dfcad9143 100644
--- a/packages/grafana-ui/src/components/Button/Button.mdx
+++ b/packages/grafana-ui/src/components/Button/Button.mdx
@@ -1,15 +1,12 @@
-import { Meta, Preview, ArgTypes } from '@storybook/blocks';
+import { Meta, Canvas, ArgTypes, Unstyled } from '@storybook/blocks';
import { Button, LinkButton } from './Button';
import { Alert } from '../Alert/Alert';
+import { ExampleFrame } from '../../utils/storybook/ExampleFrame';
# Button
-
- After reviewing this component we are asking you to use the IconButton when you require a button with only an icon.
-
-
When using a button please always follow a11y rules (e.g. W3C Recommendation [3.3.2 Labels or instructions](https://www.w3.org/TR/WCAG21/#labels-or-instructions)) and make sure the context in which the button is located is also communicated by screen readers.
## Primary
@@ -18,19 +15,17 @@ Used for "call to action", i.e. triggering the main action. There should never b
If there is no primary action, all `Button` components should be secondary.
-
-
-
-
-
-
-
+
+
+
+
+
## Secondary
@@ -39,70 +34,64 @@ The secondary `Button` is the default button style and can trigger various actio
1. When next to the primary `Button`, the Secondary style can for example be used for "Cancel" or "Abort" actions.
2. When there is no main important action on a given page, all `Button` components should use the secondary style.
-
-
-
-
-
-
-
+
+
+
+
+
## Destructive
Used for triggering a removing or deleting action. Because of its dominant coloring, it should be used sparingly. If you need multiple Destructive `Button` components in one view, we recommend using a secondary `Button` or Link variant instead and only use the Destructive variant to double confirm.
-
-
-
-
-
-
-
+
+
+
+
+
## Text
-
-
-
-
-
-
-
-
-
+
+
+
+
+
## Links
To add an anchor that looks like a button use the `` component and pass a href prop.
-
-