diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index ff3d6acc005..1075f27a677 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -181,4 +181,5 @@ export interface FeatureToggles { groupToNestedTableTransformation?: boolean; newPDFRendering?: boolean; kubernetesAggregator?: boolean; + groupByVariable?: boolean; } diff --git a/packages/grafana-data/src/types/templateVars.ts b/packages/grafana-data/src/types/templateVars.ts index 49dfe218bc9..b088ed63c85 100644 --- a/packages/grafana-data/src/types/templateVars.ts +++ b/packages/grafana-data/src/types/templateVars.ts @@ -1,5 +1,4 @@ import { LoadingState } from './data'; -import { MetricFindValue } from './datasource'; import { DataSourceRef } from './query'; export type VariableType = TypedVariableModel['type']; @@ -66,11 +65,9 @@ export interface AdHocVariableModel extends BaseVariableModel { baseFilters?: AdHocVariableFilter[]; } -export interface GroupByVariableModel extends BaseVariableModel { +export interface GroupByVariableModel extends VariableWithOptions { type: 'groupby'; datasource: DataSourceRef | null; - groupByKeys: string[]; - defaultOptions?: MetricFindValue[]; multi: true; } diff --git a/packages/grafana-e2e-selectors/src/selectors/pages.ts b/packages/grafana-e2e-selectors/src/selectors/pages.ts index f456dc70576..3fb85a71772 100644 --- a/packages/grafana-e2e-selectors/src/selectors/pages.ts +++ b/packages/grafana-e2e-selectors/src/selectors/pages.ts @@ -182,6 +182,11 @@ export const Pages = { stepCountIntervalSelect: 'data-testid interval variable step count input', minIntervalInput: 'data-testid interval variable mininum interval input', }, + GroupByVariable: { + dataSourceSelect: Components.DataSourcePicker.inputV2, + infoText: 'data-testid group by variable info text', + modeToggle: 'data-testid group by variable mode toggle', + }, AdHocFiltersVariable: { datasourceSelect: Components.DataSourcePicker.inputV2, infoText: 'data-testid ad-hoc filters variable info text', diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 8a0c634fa0b..4ec758cac42 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1212,6 +1212,15 @@ var ( Owner: grafanaAppPlatformSquad, RequiresRestart: true, }, + { + Name: "groupByVariable", + Description: "Enable groupBy variable support in scenes dashboards", + Stage: FeatureStageExperimental, + Owner: grafanaDashboardsSquad, + AllowSelfServe: false, + HideFromDocs: true, + HideFromAdminPage: true, + }, } ) diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index 311805fac1d..1612223d688 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -162,3 +162,4 @@ nodeGraphDotLayout,experimental,@grafana/observability-traces-and-profiling,fals groupToNestedTableTransformation,preview,@grafana/dataviz-squad,false,false,true newPDFRendering,experimental,@grafana/sharing-squad,false,false,false kubernetesAggregator,experimental,@grafana/grafana-app-platform-squad,false,true,false +groupByVariable,experimental,@grafana/dashboards-squad,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 6cf98f2576f..17e6fe18f9a 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -658,4 +658,8 @@ const ( // FlagKubernetesAggregator // Enable grafana aggregator FlagKubernetesAggregator = "kubernetesAggregator" + + // FlagGroupByVariable + // Enable groupBy variable support in scenes dashboards + FlagGroupByVariable = "groupByVariable" ) diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 28f3c3ed3b7..118ceb30609 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -5,35 +5,48 @@ "items": [ { "metadata": { - "name": "disableEnvelopeEncryption", - "resourceVersion": "1653393600000", - "creationTimestamp": "2022-05-24T12:00:00Z" + "name": "kubernetesQueryServiceRewrite", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Disable envelope encryption (emergency only)", - "stage": "GA", - "codeowner": "@grafana/grafana-as-code", - "hideFromAdminPage": true + "description": "Rewrite requests targeting /ds/query to the query service", + "stage": "experimental", + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresDevMode": true, + "requiresRestart": true } }, { "metadata": { - "name": "live-service-web-worker", - "resourceVersion": "1636459200000", - "creationTimestamp": "2021-11-09T12:00:00Z" + "name": "managedPluginsInstall", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "This will use a webworker thread to processes events rather than the main thread", - "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", + "description": "Install managed plugins directly from plugins catalog", + "stage": "preview", + "codeowner": "@grafana/plugins-platform-backend" + } + }, + { + "metadata": { + "name": "canvasPanelPanZoom", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" + }, + "spec": { + "description": "Allow pan and zoom in canvas panel", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { "name": "queryOverLive", - "resourceVersion": "1641384000000", - "creationTimestamp": "2022-01-05T12:00:00Z" + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { "description": "Use Grafana Live WebSocket to execute backend queries", @@ -44,140 +57,159 @@ }, { "metadata": { - "name": "panelTitleSearch", - "resourceVersion": "1644926400000", - "creationTimestamp": "2022-02-15T12:00:00Z" + "name": "correlations", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Search for dashboards using panel title", + "description": "Correlations page", + "stage": "GA", + "codeowner": "@grafana/explore-squad", + "allowSelfServe": true + } + }, + { + "metadata": { + "name": "renderAuthJWT", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" + }, + "spec": { + "description": "Uses JWT-based auth for rendering instead of relying on remote cache", "stage": "preview", - "codeowner": "@grafana/grafana-app-platform-squad", + "codeowner": "@grafana/grafana-as-code", "hideFromAdminPage": true } }, { "metadata": { - "name": "publicDashboards", - "resourceVersion": "1649332800000", - "creationTimestamp": "2022-04-07T12:00:00Z" + "name": "sqlDatasourceDatabaseSelection", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "[Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version.", - "stage": "GA", - "codeowner": "@grafana/sharing-squad", - "allowSelfServe": true + "description": "Enables previous SQL data source dataset dropdown behavior", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "publicDashboardsEmailSharing", - "resourceVersion": "1671624000000", - "creationTimestamp": "2022-12-21T12:00:00Z" + "name": "alertingInsights", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables public dashboard sharing to be restricted to only allowed emails", - "stage": "preview", - "codeowner": "@grafana/sharing-squad", - "hideFromAdminPage": true, - "hideFromDocs": true + "description": "Show the new alerting insights landing page", + "stage": "GA", + "codeowner": "@grafana/alerting-squad", + "frontend": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "lokiExperimentalStreaming", - "resourceVersion": "1687176000000", - "creationTimestamp": "2023-06-19T12:00:00Z" + "name": "logsInfiniteScrolling", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Support new streaming approach for loki (prototype, needs special loki build)", + "description": "Enables infinite scrolling for the Logs panel in Explore and Dashboards", "stage": "experimental", - "codeowner": "@grafana/observability-logs" + "codeowner": "@grafana/observability-logs", + "frontend": true } }, { "metadata": { - "name": "featureHighlights", - "resourceVersion": "1643889600000", - "creationTimestamp": "2022-02-03T12:00:00Z" + "name": "kubernetesFeatureToggles", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Highlight Grafana Enterprise features", - "stage": "GA", - "codeowner": "@grafana/grafana-as-code", - "allowSelfServe": true + "description": "Use the kubernetes API for feature toggle management in the frontend", + "stage": "experimental", + "codeowner": "@grafana/grafana-operator-experience-squad", + "frontend": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "migrationLocking", - "resourceVersion": "1644926400000", - "creationTimestamp": "2022-02-15T12:00:00Z" + "name": "dashboardSceneSolo", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Lock database during migrations", - "stage": "preview", - "codeowner": "@grafana/backend-platform" + "description": "Enables rendering dashboards using scenes for solo panels", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", + "frontend": true } }, { "metadata": { - "name": "storage", - "resourceVersion": "1647518400000", - "creationTimestamp": "2022-03-17T12:00:00Z" + "name": "panelTitleSearch", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Configurable storage for dashboards, datasources, and resources", - "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad" + "description": "Search for dashboards using panel title", + "stage": "preview", + "codeowner": "@grafana/grafana-app-platform-squad", + "hideFromAdminPage": true } }, { "metadata": { - "name": "correlations", - "resourceVersion": "1663329600000", - "creationTimestamp": "2022-09-16T12:00:00Z" + "name": "autoMigrateGraphPanel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Correlations page", - "stage": "GA", - "codeowner": "@grafana/explore-squad", - "allowSelfServe": true + "description": "Migrate old graph panel to supported time series panel - broken out from autoMigrateOldPanels to enable granular tracking", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "exploreContentOutline", - "resourceVersion": "1699012800000", - "creationTimestamp": "2023-11-03T12:00:00Z" + "name": "prometheusDataplane", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Content outline sidebar", + "description": "Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label.", "stage": "GA", - "codeowner": "@grafana/explore-squad", - "frontend": true, + "codeowner": "@grafana/observability-metrics", "allowSelfServe": true } }, { "metadata": { - "name": "datasourceQueryMultiStatus", - "resourceVersion": "1651579200000", - "creationTimestamp": "2022-05-03T12:00:00Z" + "name": "cloudWatchLogsMonacoEditor", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Introduce HTTP 207 Multi Status for api/ds/query", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend" + "description": "Enables the Monaco editor for CloudWatch Logs queries", + "stage": "GA", + "codeowner": "@grafana/aws-datasources", + "frontend": true, + "allowSelfServe": true } }, { "metadata": { - "name": "traceToMetrics", - "resourceVersion": "1646654400000", - "creationTimestamp": "2022-03-07T12:00:00Z" + "name": "metricsSummary", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable trace to metrics links", + "description": "Enables metrics summary queries in the Tempo data source", "stage": "experimental", "codeowner": "@grafana/observability-traces-and-profiling", "frontend": true @@ -185,53 +217,49 @@ }, { "metadata": { - "name": "autoMigrateOldPanels", - "resourceVersion": "1654948800000", - "creationTimestamp": "2022-06-11T12:00:00Z" + "name": "showDashboardValidationWarnings", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old angular panels to supported versions (graph, table-old, worldmap, etc)", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Show warnings when dashboards do not validate against the schema", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad" } }, { "metadata": { - "name": "disableAngular", - "resourceVersion": "1679572800000", - "creationTimestamp": "2023-03-23T12:00:00Z" + "name": "recordedQueriesMulti", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime.", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true, - "hideFromAdminPage": true + "description": "Enables writing multiple items from a single query within Recorded Queries", + "stage": "GA", + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "canvasPanelNesting", - "resourceVersion": "1653998400000", - "creationTimestamp": "2022-05-31T12:00:00Z" + "name": "reportingRetries", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow elements nesting", - "stage": "experimental", - "codeowner": "@grafana/dataviz-squad", - "frontend": true, - "hideFromAdminPage": true + "description": "Enables rendering retries for the reporting feature", + "stage": "preview", + "codeowner": "@grafana/sharing-squad", + "requiresRestart": true } }, { "metadata": { - "name": "newVizTooltips", - "resourceVersion": "1699012800000", - "creationTimestamp": "2023-11-03T12:00:00Z" + "name": "regressionTransformation", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "New visualizations tooltips UX", + "description": "Enables regression analysis transformation", "stage": "preview", "codeowner": "@grafana/dataviz-squad", "frontend": true @@ -239,413 +267,401 @@ }, { "metadata": { - "name": "scenes", - "resourceVersion": "1657195200000", - "creationTimestamp": "2022-07-07T12:00:00Z" + "name": "newFolderPicker", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Experimental framework to build interactive dashboards", + "description": "Enables the nested folder picker without having nested folders enabled", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", + "codeowner": "@grafana/grafana-frontend-platform", "frontend": true } }, { "metadata": { - "name": "disableSecretsCompatibility", - "resourceVersion": "1657713600000", - "creationTimestamp": "2022-07-13T12:00:00Z" + "name": "grafanaAPIServerEnsureKubectlAccess", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Disable duplicated secret storage in legacy tables", + "description": "Start an additional https handler and write kubectl options", "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team", + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresDevMode": true, "requiresRestart": true } }, { "metadata": { - "name": "logRequestsInstrumentedAsUnknown", - "resourceVersion": "1654862400000", - "creationTimestamp": "2022-06-10T12:00:00Z" + "name": "datatrails", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Logs the path for requests that are instrumented as unknown", + "description": "Enables the new core app datatrails", "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team" + "codeowner": "@grafana/dashboards-squad", + "frontend": true, + "hideFromDocs": true } }, { "metadata": { - "name": "dataConnectionsConsole", - "resourceVersion": "1654084800000", - "creationTimestamp": "2022-06-01T12:00:00Z" + "name": "alertingQueryOptimization", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables a new top-level page called Connections. This page is an experiment that provides a better experience when you install and configure data sources and other plugins.", + "description": "Optimizes eligible queries in order to reduce load on datasources", "stage": "GA", - "codeowner": "@grafana/plugins-platform-backend", - "allowSelfServe": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "topnav", - "resourceVersion": "1655726400000", - "creationTimestamp": "2022-06-20T12:00:00Z" + "name": "disableEnvelopeEncryption", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables topnav support in external plugins. The new Grafana navigation cannot be disabled.", - "stage": "deprecated", - "codeowner": "@grafana/grafana-frontend-platform" + "description": "Disable envelope encryption (emergency only)", + "stage": "GA", + "codeowner": "@grafana/grafana-as-code", + "hideFromAdminPage": true } }, { "metadata": { - "name": "returnToPrevious", - "resourceVersion": "1704798000000", - "creationTimestamp": "2024-01-09T11:00:00Z" + "name": "autoMigrateOldPanels", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the return to previous context functionality", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform", + "description": "Migrate old angular panels to supported versions (graph, table-old, worldmap, etc)", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "grpcServer", - "resourceVersion": "1664280000000", - "creationTimestamp": "2022-09-27T12:00:00Z" + "name": "dataConnectionsConsole", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Run the GRPC server", - "stage": "preview", - "codeowner": "@grafana/grafana-app-platform-squad", - "hideFromAdminPage": true + "description": "Enables a new top-level page called Connections. This page is an experiment that provides a better experience when you install and configure data sources and other plugins.", + "stage": "GA", + "codeowner": "@grafana/plugins-platform-backend", + "allowSelfServe": true } }, { "metadata": { - "name": "unifiedStorage", - "resourceVersion": "1669896000000", - "creationTimestamp": "2022-12-01T12:00:00Z" + "name": "externalServiceAuth", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "SQL-based k8s storage", + "description": "Starts an OAuth2 authentication provider for external services", "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresDevMode": true, - "requiresRestart": true - } - }, - { - "metadata": { - "name": "cloudWatchCrossAccountQuerying", - "resourceVersion": "1669636800000", - "creationTimestamp": "2022-11-28T12:00:00Z" - }, - "spec": { - "description": "Enables cross-account querying in CloudWatch datasources", - "stage": "GA", - "codeowner": "@grafana/aws-datasources", - "allowSelfServe": true + "codeowner": "@grafana/identity-access-team", + "requiresDevMode": true } }, { "metadata": { - "name": "redshiftAsyncQueryDataSupport", - "resourceVersion": "1661601600000", - "creationTimestamp": "2022-08-27T12:00:00Z" + "name": "grafanaAPIServerWithExperimentalAPIs", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable async query data support for Redshift", - "stage": "GA", - "codeowner": "@grafana/aws-datasources" + "description": "Register experimental APIs with the k8s API server", + "stage": "experimental", + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresDevMode": true, + "requiresRestart": true } }, { "metadata": { - "name": "athenaAsyncQueryDataSupport", - "resourceVersion": "1661601600000", - "creationTimestamp": "2022-08-27T12:00:00Z" + "name": "groupToNestedTableTransformation", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable async query data support for Athena", - "stage": "GA", - "codeowner": "@grafana/aws-datasources", + "description": "Enables the group to nested table transformation", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "showDashboardValidationWarnings", - "resourceVersion": "1665748800000", - "creationTimestamp": "2022-10-14T12:00:00Z" + "name": "lokiQuerySplittingConfig", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Show warnings when dashboards do not validate against the schema", + "description": "Give users the option to configure split durations for Loki queries", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad" + "codeowner": "@grafana/observability-logs", + "frontend": true } }, { "metadata": { - "name": "mysqlAnsiQuotes", - "resourceVersion": "1665576000000", - "creationTimestamp": "2022-10-12T12:00:00Z" + "name": "logsExploreTableVisualisation", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Use double quotes to escape keyword in a MySQL query", - "stage": "experimental", - "codeowner": "@grafana/backend-platform" + "description": "A table visualisation for logs in Explore", + "stage": "GA", + "codeowner": "@grafana/observability-logs", + "frontend": true } }, { "metadata": { - "name": "accessControlOnCall", - "resourceVersion": "1666180800000", - "creationTimestamp": "2022-10-19T12:00:00Z" + "name": "awsAsyncQueryCaching", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Access control primitives for OnCall", - "stage": "preview", - "codeowner": "@grafana/identity-access-team", - "hideFromAdminPage": true + "description": "Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled", + "stage": "GA", + "codeowner": "@grafana/aws-datasources" } }, { "metadata": { - "name": "nestedFolders", - "resourceVersion": "1666440000000", - "creationTimestamp": "2022-10-22T12:00:00Z" + "name": "prometheusConfigOverhaulAuth", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable folder nesting", - "stage": "preview", - "codeowner": "@grafana/backend-platform" + "description": "Update the Prometheus configuration page with the new auth component", + "stage": "GA", + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "nestedFolderPicker", - "resourceVersion": "1690200000000", - "creationTimestamp": "2023-07-24T12:00:00Z" + "name": "alertingPreviewUpgrade", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle", + "description": "Show Unified Alerting preview and upgrade page in legacy alerting", "stage": "GA", - "codeowner": "@grafana/grafana-frontend-platform", - "frontend": true, - "allowSelfServe": true + "codeowner": "@grafana/alerting-squad", + "requiresRestart": true } }, { "metadata": { - "name": "alertingBacktesting", - "resourceVersion": "1666267200000", - "creationTimestamp": "2022-10-20T12:00:00Z" + "name": "alertStateHistoryLokiOnly", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Rule backtesting API for alerting", + "description": "Disable Grafana alerts from emitting annotations when a remote Loki instance is available.", "stage": "experimental", "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "editPanelCSVDragAndDrop", - "resourceVersion": "1707523537136", - "creationTimestamp": "2022-12-20T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "permissionsFilterRemoveSubquery", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables drag and drop for CSV and Excel files", + "description": "Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder", "stage": "experimental", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "alertingNoNormalState", - "resourceVersion": "1673697600000", - "creationTimestamp": "2023-01-14T12:00:00Z" + "name": "externalCorePlugins", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Stop maintaining state of alerts that are not firing", - "stage": "preview", - "codeowner": "@grafana/alerting-squad", - "hideFromAdminPage": true + "description": "Allow core plugins to be loaded as external", + "stage": "experimental", + "codeowner": "@grafana/plugins-platform-backend" } }, { "metadata": { - "name": "logsContextDatasourceUi", - "resourceVersion": "1674820800000", - "creationTimestamp": "2023-01-27T12:00:00Z" + "name": "unifiedStorage", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow datasource to provide custom UI for context view", - "stage": "GA", - "codeowner": "@grafana/observability-logs", - "frontend": true, - "allowSelfServe": true + "description": "SQL-based k8s storage", + "stage": "experimental", + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresDevMode": true, + "requiresRestart": true } }, { "metadata": { - "name": "lokiQuerySplitting", - "resourceVersion": "1675944000000", - "creationTimestamp": "2023-02-09T12:00:00Z" + "name": "influxdbSqlSupport", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Split large interval queries into subqueries with smaller time intervals", + "description": "Enable InfluxDB SQL query language support with new querying UI", "stage": "GA", - "codeowner": "@grafana/observability-logs", - "frontend": true, + "codeowner": "@grafana/observability-metrics", + "requiresRestart": true, "allowSelfServe": true } }, { "metadata": { - "name": "lokiQuerySplittingConfig", - "resourceVersion": "1679313600000", - "creationTimestamp": "2023-03-20T12:00:00Z" + "name": "angularDeprecationUI", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Give users the option to configure split durations for Loki queries", + "description": "Display new Angular deprecation-related UI features", "stage": "experimental", - "codeowner": "@grafana/observability-logs", + "codeowner": "@grafana/plugins-platform-backend", "frontend": true } }, { "metadata": { - "name": "individualCookiePreferences", - "resourceVersion": "1677153600000", - "creationTimestamp": "2023-02-23T12:00:00Z" + "name": "libraryPanelRBAC", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Support overriding cookie preferences per user", + "description": "Enables RBAC support for library panels", "stage": "experimental", - "codeowner": "@grafana/backend-platform" + "codeowner": "@grafana/dashboards-squad", + "requiresRestart": true } }, { "metadata": { - "name": "prometheusMetricEncyclopedia", - "resourceVersion": "1678190400000", - "creationTimestamp": "2023-03-07T12:00:00Z" + "name": "promQLScope", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Adds the metrics explorer component to the Prometheus query builder as an option in metric select", - "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "frontend": true, - "allowSelfServe": true + "description": "In-development feature that will allow injection of labels into prometheus queries.", + "stage": "experimental", + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "influxdbBackendMigration", - "resourceVersion": "1678881600000", - "creationTimestamp": "2023-03-15T12:00:00Z" + "name": "publicDashboards", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Query InfluxDB InfluxQL without the proxy", + "description": "[Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version.", "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "frontend": true + "codeowner": "@grafana/sharing-squad", + "allowSelfServe": true } }, { "metadata": { - "name": "influxqlStreamingParser", - "resourceVersion": "1701259200000", - "creationTimestamp": "2023-11-29T12:00:00Z" + "name": "unifiedRequestLog", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable streaming JSON parser for InfluxDB datasource InfluxQL query language", + "description": "Writes error logs to the request logger", "stage": "experimental", - "codeowner": "@grafana/observability-metrics" + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "influxdbRunQueriesInParallel", - "resourceVersion": "1706529600000", - "creationTimestamp": "2024-01-29T12:00:00Z" + "name": "teamHttpHeaders", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables running InfluxDB Influxql queries in parallel", - "stage": "privatePreview", - "codeowner": "@grafana/observability-metrics" + "description": "Enables datasources to apply team headers to the client requests", + "stage": "experimental", + "codeowner": "@grafana/identity-access-team" } }, { "metadata": { - "name": "clientTokenRotation", - "resourceVersion": "1679572800000", - "creationTimestamp": "2023-03-23T12:00:00Z" + "name": "groupByVariable", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Replaces the current in-request token rotation so that the client initiates the rotation", - "stage": "GA", - "codeowner": "@grafana/identity-access-team" + "description": "Enable groupBy variable support in scenes dashboards", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", + "hideFromAdminPage": true, + "hideFromDocs": true } }, { "metadata": { - "name": "prometheusDataplane", - "resourceVersion": "1680091200000", - "creationTimestamp": "2023-03-29T12:00:00Z" + "name": "dashboardScene", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label.", - "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "allowSelfServe": true + "description": "Enables dashboard rendering using scenes for all roles", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", + "frontend": true } }, { "metadata": { - "name": "lokiMetricDataplane", - "resourceVersion": "1681387200000", - "creationTimestamp": "2023-04-13T12:00:00Z" + "name": "lokiQueryHints", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Changes metric responses from Loki to be compliant with the dataplane specification.", + "description": "Enables query hints for Loki", "stage": "GA", "codeowner": "@grafana/observability-logs", - "allowSelfServe": true + "frontend": true } }, { "metadata": { - "name": "lokiLogsDataplane", - "resourceVersion": "1689249600000", - "creationTimestamp": "2023-07-13T12:00:00Z" + "name": "autoMigrateTablePanel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Changes logs responses from Loki to be compliant with the dataplane specification.", - "stage": "experimental", - "codeowner": "@grafana/observability-logs" + "description": "Migrate old table panel to supported table panel - broken out from autoMigrateOldPanels to enable granular tracking", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "dataplaneFrontendFallback", - "resourceVersion": "1682337600000", - "creationTimestamp": "2023-04-24T12:00:00Z" + "name": "logsContextDatasourceUi", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Support dataplane contract field name change for transformations and field name matchers where the name is different", + "description": "Allow datasource to provide custom UI for context view", "stage": "GA", - "codeowner": "@grafana/observability-metrics", + "codeowner": "@grafana/observability-logs", "frontend": true, "allowSelfServe": true } @@ -653,8 +669,8 @@ { "metadata": { "name": "disableSSEDataplane", - "resourceVersion": "1682337600000", - "creationTimestamp": "2023-04-24T12:00:00Z" + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { "description": "Disables dataplane specific processing in server side expressions.", @@ -664,223 +680,238 @@ }, { "metadata": { - "name": "alertStateHistoryLokiSecondary", - "resourceVersion": "1680177600000", - "creationTimestamp": "2023-03-30T12:00:00Z" + "name": "refactorVariablesTimeRange", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable Grafana to write alert state history to an external Loki instance in addition to Grafana annotations.", - "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "description": "Refactor time range variables flow to reduce number of API calls made when query variables are chained", + "stage": "preview", + "codeowner": "@grafana/dashboards-squad", + "hideFromAdminPage": true } }, { "metadata": { - "name": "alertStateHistoryLokiPrimary", - "resourceVersion": "1680177600000", - "creationTimestamp": "2023-03-30T12:00:00Z" + "name": "awsDatasourcesTempCredentials", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable a remote Loki instance as the primary source for state history reads.", + "description": "Support temporary security credentials in AWS plugins for Grafana Cloud customers", "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "codeowner": "@grafana/aws-datasources" } }, { "metadata": { - "name": "alertStateHistoryLokiOnly", - "resourceVersion": "1680177600000", - "creationTimestamp": "2023-03-30T12:00:00Z" + "name": "prometheusMetricEncyclopedia", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Disable Grafana alerts from emitting annotations when a remote Loki instance is available.", + "description": "Adds the metrics explorer component to the Prometheus query builder as an option in metric select", + "stage": "GA", + "codeowner": "@grafana/observability-metrics", + "frontend": true, + "allowSelfServe": true + } + }, + { + "metadata": { + "name": "wargamesTesting", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" + }, + "spec": { + "description": "Placeholder feature flag for internal testing", "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "codeowner": "@grafana/hosted-grafana-team" } }, { "metadata": { - "name": "unifiedRequestLog", - "resourceVersion": "1680264000000", - "creationTimestamp": "2023-03-31T12:00:00Z" + "name": "idForwarding", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Writes error logs to the request logger", + "description": "Generate signed id token for identity that can be forwarded to plugins and external services", "stage": "experimental", - "codeowner": "@grafana/backend-platform" + "codeowner": "@grafana/identity-access-team" } }, { "metadata": { - "name": "renderAuthJWT", - "resourceVersion": "1680523200000", - "creationTimestamp": "2023-04-03T12:00:00Z" + "name": "kubernetesSnapshots", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Uses JWT-based auth for rendering instead of relying on remote cache", - "stage": "preview", - "codeowner": "@grafana/grafana-as-code", - "hideFromAdminPage": true + "description": "Routes snapshot requests from /api to the /apis endpoint", + "stage": "experimental", + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresRestart": true } }, { "metadata": { - "name": "externalServiceAuth", - "resourceVersion": "1681214400000", - "creationTimestamp": "2023-04-11T12:00:00Z" + "name": "alertmanagerRemoteSecondary", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Starts an OAuth2 authentication provider for external services", + "description": "Enable Grafana to sync configuration and state with a remote Alertmanager.", "stage": "experimental", - "codeowner": "@grafana/identity-access-team", - "requiresDevMode": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "refactorVariablesTimeRange", - "resourceVersion": "1686052800000", - "creationTimestamp": "2023-06-06T12:00:00Z" + "name": "alertingBacktesting", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Refactor time range variables flow to reduce number of API calls made when query variables are chained", - "stage": "preview", - "codeowner": "@grafana/dashboards-squad", - "hideFromAdminPage": true + "description": "Rule backtesting API for alerting", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "enableElasticsearchBackendQuerying", - "resourceVersion": "1681473600000", - "creationTimestamp": "2023-04-14T12:00:00Z" + "name": "influxdbRunQueriesInParallel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable the processing of queries and responses in the Elasticsearch data source through backend", - "stage": "GA", - "codeowner": "@grafana/observability-logs", - "allowSelfServe": true + "description": "Enables running InfluxDB Influxql queries in parallel", + "stage": "privatePreview", + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "faroDatasourceSelector", - "resourceVersion": "1683201600000", - "creationTimestamp": "2023-05-04T12:00:00Z" + "name": "pluginsAPIMetrics", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable the data source selector within the Frontend Apps section of the Frontend Observability", - "stage": "preview", - "codeowner": "@grafana/app-o11y", + "description": "Sends metrics of public grafana packages usage by plugins", + "stage": "experimental", + "codeowner": "@grafana/plugins-platform-backend", "frontend": true } }, { "metadata": { - "name": "enableDatagridEditing", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-04-24T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "cloudWatchBatchQueries", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the edit functionality in the datagrid panel", + "description": "Runs CloudWatch metrics queries as separate batches", "stage": "preview", + "codeowner": "@grafana/aws-datasources" + } + }, + { + "metadata": { + "name": "extractFieldsNameDeduplication", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" + }, + "spec": { + "description": "Make sure extracted field names are unique in the dataframe", + "stage": "experimental", "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "extraThemes", - "resourceVersion": "1683720000000", - "creationTimestamp": "2023-05-10T12:00:00Z" + "name": "exploreScrollableLogsContainer", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables extra themes", + "description": "Improves the scrolling behavior of logs in Explore", "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform", + "codeowner": "@grafana/observability-logs", "frontend": true } }, { "metadata": { - "name": "lokiPredefinedOperations", - "resourceVersion": "1685707200000", - "creationTimestamp": "2023-06-02T12:00:00Z" + "name": "logRowsPopoverMenu", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Adds predefined query operations to Loki query editor", - "stage": "experimental", + "description": "Enable filtering menu displayed when text of a log line is selected", + "stage": "GA", "codeowner": "@grafana/observability-logs", "frontend": true } }, { "metadata": { - "name": "pluginsFrontendSandbox", - "resourceVersion": "1685966400000", - "creationTimestamp": "2023-06-05T12:00:00Z" + "name": "storage", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the plugins frontend sandbox", + "description": "Configurable storage for dashboards, datasources, and resources", "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend", - "frontend": true + "codeowner": "@grafana/grafana-app-platform-squad" } }, { "metadata": { - "name": "dashboardEmbed", - "resourceVersion": "1688644800000", - "creationTimestamp": "2023-07-06T12:00:00Z" + "name": "returnToPrevious", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow embedding dashboard for external use in Code editors", + "description": "Enables the return to previous context functionality", "stage": "experimental", - "codeowner": "@grafana/grafana-as-code", + "codeowner": "@grafana/grafana-frontend-platform", "frontend": true } }, { "metadata": { - "name": "frontendSandboxMonitorOnly", - "resourceVersion": "1688558400000", - "creationTimestamp": "2023-07-05T12:00:00Z" + "name": "influxqlStreamingParser", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables monitor only in the plugin frontend sandbox (if enabled)", + "description": "Enable streaming JSON parser for InfluxDB datasource InfluxQL query language", "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend", - "frontend": true + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "sqlDatasourceDatabaseSelection", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-06-06T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "enableDatagridEditing", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables previous SQL data source dataset dropdown behavior", + "description": "Enables the edit functionality in the datagrid panel", "stage": "preview", "codeowner": "@grafana/dataviz-squad", - "frontend": true, - "hideFromAdminPage": true + "frontend": true } }, { "metadata": { - "name": "lokiFormatQuery", - "resourceVersion": "1687348800000", - "creationTimestamp": "2023-06-21T12:00:00Z" + "name": "lokiPredefinedOperations", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the ability to format Loki queries", + "description": "Adds predefined query operations to Loki query editor", "stage": "experimental", "codeowner": "@grafana/observability-logs", "frontend": true @@ -888,285 +919,278 @@ }, { "metadata": { - "name": "cloudWatchLogsMonacoEditor", - "resourceVersion": "1686571200000", - "creationTimestamp": "2023-06-12T12:00:00Z" + "name": "nestedFolders", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the Monaco editor for CloudWatch Logs queries", - "stage": "GA", - "codeowner": "@grafana/aws-datasources", - "frontend": true, - "allowSelfServe": true + "description": "Enable folder nesting", + "stage": "preview", + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "exploreScrollableLogsContainer", - "resourceVersion": "1686830400000", - "creationTimestamp": "2023-06-15T12:00:00Z" + "name": "panelMonitoring", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Improves the scrolling behavior of logs in Explore", + "description": "Enables panel monitoring through logs and measurements", "stage": "experimental", - "codeowner": "@grafana/observability-logs", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "recordedQueriesMulti", - "resourceVersion": "1686744000000", - "creationTimestamp": "2023-06-14T12:00:00Z" + "name": "mysqlAnsiQuotes", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables writing multiple items from a single query within Recorded Queries", - "stage": "GA", - "codeowner": "@grafana/observability-metrics" + "description": "Use double quotes to escape keyword in a MySQL query", + "stage": "experimental", + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "pluginsDynamicAngularDetectionPatterns", - "resourceVersion": "1687780800000", - "creationTimestamp": "2023-06-26T12:00:00Z" + "name": "pluginsSkipHostEnvVars", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones", + "description": "Disables passing host environment variable to plugin processes", "stage": "experimental", "codeowner": "@grafana/plugins-platform-backend" } }, { "metadata": { - "name": "vizAndWidgetSplit", - "resourceVersion": "1687867200000", - "creationTimestamp": "2023-06-27T12:00:00Z" + "name": "newPDFRendering", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Split panels between visualizations and widgets", + "description": "New implementation for the dashboard to PDF rendering", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", - "frontend": true + "codeowner": "@grafana/sharing-squad" } }, { "metadata": { - "name": "prometheusIncrementalQueryInstrumentation", - "resourceVersion": "1688558400000", - "creationTimestamp": "2023-07-05T12:00:00Z" + "name": "dashboardEmbed", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Adds RudderStack events to incremental queries", + "description": "Allow embedding dashboard for external use in Code editors", "stage": "experimental", - "codeowner": "@grafana/observability-metrics", + "codeowner": "@grafana/grafana-as-code", "frontend": true } }, { "metadata": { - "name": "logsExploreTableVisualisation", - "resourceVersion": "1707747885704", - "creationTimestamp": "2023-07-12T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-12 14:24:45.704022 +0000 UTC" - } + "name": "cloudWatchWildCardDimensionValues", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "A table visualisation for logs in Explore", + "description": "Fetches dimension values from CloudWatch to correctly label wildcard dimensions", "stage": "GA", - "codeowner": "@grafana/observability-logs", - "frontend": true + "codeowner": "@grafana/aws-datasources", + "allowSelfServe": true } }, { "metadata": { - "name": "awsDatasourcesTempCredentials", - "resourceVersion": "1688644800000", - "creationTimestamp": "2023-07-06T12:00:00Z" + "name": "addFieldFromCalculationStatFunctions", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Support temporary security credentials in AWS plugins for Grafana Cloud customers", - "stage": "experimental", - "codeowner": "@grafana/aws-datasources" + "description": "Add cumulative and window functions to the add field from calculation transformation", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "transformationsRedesign", - "resourceVersion": "1689163200000", - "creationTimestamp": "2023-07-12T12:00:00Z" + "name": "panelTitleSearchInV1", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the transformations redesign", - "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "frontend": true, - "allowSelfServe": true + "description": "Enable searching for dashboards using panel title in search v1", + "stage": "experimental", + "codeowner": "@grafana/backend-platform", + "requiresDevMode": true } }, { "metadata": { - "name": "mlExpressions", - "resourceVersion": "1689249600000", - "creationTimestamp": "2023-07-13T12:00:00Z" + "name": "pdfTables", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable support for Machine Learning in server-side expressions", - "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "description": "Enables generating table data as PDF in reporting", + "stage": "preview", + "codeowner": "@grafana/sharing-squad" } }, { "metadata": { - "name": "traceQLStreaming", - "resourceVersion": "1690372800000", - "creationTimestamp": "2023-07-26T12:00:00Z" + "name": "jitterAlertRulesWithinGroups", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables response streaming of TraceQL queries of the Tempo data source", - "stage": "experimental", - "codeowner": "@grafana/observability-traces-and-profiling", - "frontend": true + "description": "Distributes alert rule evaluations more evenly over time, including spreading out rules within the same group", + "stage": "preview", + "codeowner": "@grafana/alerting-squad", + "requiresRestart": true, + "hideFromDocs": true } }, { "metadata": { - "name": "metricsSummary", - "resourceVersion": "1693224000000", - "creationTimestamp": "2023-08-28T12:00:00Z" + "name": "publicDashboardsEmailSharing", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables metrics summary queries in the Tempo data source", - "stage": "experimental", - "codeowner": "@grafana/observability-traces-and-profiling", - "frontend": true + "description": "Enables public dashboard sharing to be restricted to only allowed emails", + "stage": "preview", + "codeowner": "@grafana/sharing-squad", + "hideFromAdminPage": true, + "hideFromDocs": true } }, { "metadata": { - "name": "grafanaAPIServerWithExperimentalAPIs", - "resourceVersion": "1696593600000", - "creationTimestamp": "2023-10-06T12:00:00Z" + "name": "migrationLocking", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Register experimental APIs with the k8s API server", - "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresDevMode": true, - "requiresRestart": true + "description": "Lock database during migrations", + "stage": "preview", + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "grafanaAPIServerEnsureKubectlAccess", - "resourceVersion": "1701864000000", - "creationTimestamp": "2023-12-06T12:00:00Z" + "name": "autoMigrateStatPanel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Start an additional https handler and write kubectl options", - "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresDevMode": true, - "requiresRestart": true + "description": "Migrate old stat panel to supported stat panel - broken out from autoMigrateOldPanels to enable granular tracking", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "featureToggleAdminPage", - "resourceVersion": "1689681600000", - "creationTimestamp": "2023-07-18T12:00:00Z" + "name": "canvasPanelNesting", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable admin page for managing feature toggles from the Grafana front-end", + "description": "Allow elements nesting", "stage": "experimental", - "codeowner": "@grafana/grafana-operator-experience-squad", - "requiresRestart": true + "codeowner": "@grafana/dataviz-squad", + "frontend": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "awsAsyncQueryCaching", - "resourceVersion": "1689940800000", - "creationTimestamp": "2023-07-21T12:00:00Z" + "name": "externalServiceAccounts", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled", - "stage": "GA", - "codeowner": "@grafana/aws-datasources" + "description": "Automatic service account and token setup for plugins", + "stage": "preview", + "codeowner": "@grafana/identity-access-team", + "hideFromAdminPage": true } }, { "metadata": { - "name": "splitScopes", - "resourceVersion": "1689940800000", - "creationTimestamp": "2023-07-21T12:00:00Z" + "name": "alertingSaveStatePeriodic", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Support faster dashboard and folder search by splitting permission scopes into parts", - "stage": "deprecated", - "codeowner": "@grafana/identity-access-team", - "requiresRestart": true, - "hideFromAdminPage": true + "description": "Writes the state periodically to the database, asynchronous to rule evaluation", + "stage": "privatePreview", + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "permissionsFilterRemoveSubquery", - "resourceVersion": "1690977600000", - "creationTimestamp": "2023-08-02T12:00:00Z" + "name": "traceToMetrics", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder", + "description": "Enable trace to metrics links", "stage": "experimental", - "codeowner": "@grafana/backend-platform" + "codeowner": "@grafana/observability-traces-and-profiling", + "frontend": true } }, { "metadata": { - "name": "prometheusConfigOverhaulAuth", - "resourceVersion": "1689940800000", - "creationTimestamp": "2023-07-21T12:00:00Z" + "name": "cloudWatchCrossAccountQuerying", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Update the Prometheus configuration page with the new auth component", + "description": "Enables cross-account querying in CloudWatch datasources", "stage": "GA", - "codeowner": "@grafana/observability-metrics" + "codeowner": "@grafana/aws-datasources", + "allowSelfServe": true } }, { "metadata": { - "name": "configurableSchedulerTick", - "resourceVersion": "1690372800000", - "creationTimestamp": "2023-07-26T12:00:00Z" + "name": "pluginsFrontendSandbox", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable changing the scheduler base interval via configuration option unified_alerting.scheduler_tick_interval", + "description": "Enables the plugins frontend sandbox", "stage": "experimental", - "codeowner": "@grafana/alerting-squad", - "requiresRestart": true, - "hideFromDocs": true + "codeowner": "@grafana/plugins-platform-backend", + "frontend": true } }, { "metadata": { - "name": "influxdbSqlSupport", - "resourceVersion": "1690977600000", - "creationTimestamp": "2023-08-02T12:00:00Z" + "name": "traceQLStreaming", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable InfluxDB SQL query language support with new querying UI", - "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "requiresRestart": true, - "allowSelfServe": true + "description": "Enables response streaming of TraceQL queries of the Tempo data source", + "stage": "experimental", + "codeowner": "@grafana/observability-traces-and-profiling", + "frontend": true } }, { "metadata": { "name": "alertingNoDataErrorExecution", - "resourceVersion": "1692100800000", - "creationTimestamp": "2023-08-15T12:00:00Z" + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { "description": "Changes how Alerting state manager handles execution of NoData/Error", @@ -1177,205 +1201,167 @@ }, { "metadata": { - "name": "angularDeprecationUI", - "resourceVersion": "1693310400000", - "creationTimestamp": "2023-08-29T12:00:00Z" + "name": "logRequestsInstrumentedAsUnknown", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Display new Angular deprecation-related UI features", + "description": "Logs the path for requests that are instrumented as unknown", "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend", - "frontend": true - } - }, - { - "metadata": { - "name": "dashgpt", - "resourceVersion": "1700222400000", - "creationTimestamp": "2023-11-17T12:00:00Z" - }, - "spec": { - "description": "Enable AI powered features in dashboards", - "stage": "preview", - "codeowner": "@grafana/dashboards-squad", - "frontend": true + "codeowner": "@grafana/hosted-grafana-team" } }, { "metadata": { - "name": "reportingRetries", - "resourceVersion": "1693483200000", - "creationTimestamp": "2023-08-31T12:00:00Z" + "name": "transformationsRedesign", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables rendering retries for the reporting feature", - "stage": "preview", - "codeowner": "@grafana/sharing-squad", - "requiresRestart": true + "description": "Enables the transformations redesign", + "stage": "GA", + "codeowner": "@grafana/observability-metrics", + "frontend": true, + "allowSelfServe": true } }, { "metadata": { - "name": "sseGroupByDatasource", - "resourceVersion": "1694088000000", - "creationTimestamp": "2023-09-07T12:00:00Z" + "name": "prometheusPromQAIL", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Send query to the same datasource in a single request when using server side expressions. The `cloudWatchBatchQueries` feature toggle should be enabled if this used with CloudWatch.", + "description": "Prometheus and AI/ML to assist users in creating a query", "stage": "experimental", - "codeowner": "@grafana/observability-metrics" + "codeowner": "@grafana/observability-metrics", + "frontend": true } }, { "metadata": { - "name": "libraryPanelRBAC", - "resourceVersion": "1697025600000", - "creationTimestamp": "2023-10-11T12:00:00Z" + "name": "kubernetesAggregator", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables RBAC support for library panels", + "description": "Enable grafana aggregator", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", + "codeowner": "@grafana/grafana-app-platform-squad", "requiresRestart": true } }, { "metadata": { - "name": "lokiRunQueriesInParallel", - "resourceVersion": "1695124800000", - "creationTimestamp": "2023-09-19T12:00:00Z" - }, - "spec": { - "description": "Enables running Loki queries in parallel", - "stage": "privatePreview", - "codeowner": "@grafana/observability-logs" - } - }, - { - "metadata": { - "name": "wargamesTesting", - "resourceVersion": "1694606400000", - "creationTimestamp": "2023-09-13T12:00:00Z" + "name": "live-service-web-worker", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Placeholder feature flag for internal testing", + "description": "This will use a webworker thread to processes events rather than the main thread", "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team" + "codeowner": "@grafana/grafana-app-platform-squad", + "frontend": true } }, { "metadata": { - "name": "alertingInsights", - "resourceVersion": "1694692800000", - "creationTimestamp": "2023-09-14T12:00:00Z" + "name": "grpcServer", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Show the new alerting insights landing page", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "frontend": true, + "description": "Run the GRPC server", + "stage": "preview", + "codeowner": "@grafana/grafana-app-platform-squad", "hideFromAdminPage": true } }, { "metadata": { - "name": "externalCorePlugins", - "resourceVersion": "1695384000000", - "creationTimestamp": "2023-09-22T12:00:00Z" + "name": "clientTokenRotation", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow core plugins to be loaded as external", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend" + "description": "Replaces the current in-request token rotation so that the client initiates the rotation", + "stage": "GA", + "codeowner": "@grafana/identity-access-team" } }, { "metadata": { - "name": "pluginsAPIMetrics", - "resourceVersion": "1695297600000", - "creationTimestamp": "2023-09-21T12:00:00Z" + "name": "lokiStructuredMetadata", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Sends metrics of public grafana packages usage by plugins", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend", - "frontend": true + "description": "Enables the loki data source to request structured metadata from the Loki server", + "stage": "GA", + "codeowner": "@grafana/observability-logs" } }, { "metadata": { - "name": "idForwarding", - "resourceVersion": "1695643200000", - "creationTimestamp": "2023-09-25T12:00:00Z" + "name": "tableSharedCrosshair", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Generate signed id token for identity that can be forwarded to plugins and external services", + "description": "Enables shared crosshair in table panel", "stage": "experimental", - "codeowner": "@grafana/identity-access-team" + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "cloudWatchWildCardDimensionValues", - "resourceVersion": "1695816000000", - "creationTimestamp": "2023-09-27T12:00:00Z" + "name": "lokiQuerySplitting", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Fetches dimension values from CloudWatch to correctly label wildcard dimensions", + "description": "Split large interval queries into subqueries with smaller time intervals", "stage": "GA", - "codeowner": "@grafana/aws-datasources", + "codeowner": "@grafana/observability-logs", + "frontend": true, "allowSelfServe": true } }, { "metadata": { - "name": "externalServiceAccounts", - "resourceVersion": "1695902400000", - "creationTimestamp": "2023-09-28T12:00:00Z" + "name": "lokiMetricDataplane", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Automatic service account and token setup for plugins", - "stage": "preview", - "codeowner": "@grafana/identity-access-team", - "hideFromAdminPage": true + "description": "Changes metric responses from Loki to be compliant with the dataplane specification.", + "stage": "GA", + "codeowner": "@grafana/observability-logs", + "allowSelfServe": true } }, { "metadata": { - "name": "panelMonitoring", - "resourceVersion": "1696766400000", - "creationTimestamp": "2023-10-08T12:00:00Z" + "name": "transformationsVariableSupport", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables panel monitoring through logs and measurements", - "stage": "experimental", + "description": "Allows using variables in transformations", + "stage": "preview", "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "enableNativeHTTPHistogram", - "resourceVersion": "1696334400000", - "creationTimestamp": "2023-10-03T12:00:00Z" - }, - "spec": { - "description": "Enables native HTTP Histograms", - "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team" - } - }, - { - "metadata": { - "name": "formatString", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-10-13T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "newVizTooltips", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable format string transformer", + "description": "New visualizations tooltips UX", "stage": "preview", "codeowner": "@grafana/dataviz-squad", "frontend": true @@ -1383,291 +1369,281 @@ }, { "metadata": { - "name": "transformationsVariableSupport", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-10-04T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "topnav", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allows using variables in transformations", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Enables topnav support in external plugins. The new Grafana navigation cannot be disabled.", + "stage": "deprecated", + "codeowner": "@grafana/grafana-frontend-platform" } }, { "metadata": { - "name": "kubernetesPlaylists", - "resourceVersion": "1699444800000", - "creationTimestamp": "2023-11-08T12:00:00Z" + "name": "ssoSettingsApi", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s", + "description": "Enables the SSO settings API", "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresRestart": true + "codeowner": "@grafana/identity-access-team" } }, { "metadata": { - "name": "kubernetesSnapshots", - "resourceVersion": "1707374669879", - "creationTimestamp": "2023-12-04T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-08 06:44:29.879787 +0000 UTC" - } + "name": "onPremToCloudMigrations", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Routes snapshot requests from /api to the /apis endpoint", + "description": "In-development feature that will allow users to easily migrate their on-prem Grafana instances to Grafana Cloud.", "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresRestart": true + "codeowner": "@grafana/grafana-operator-experience-squad" } }, { "metadata": { - "name": "kubernetesQueryServiceRewrite", - "resourceVersion": "1706443200000", - "creationTimestamp": "2024-01-28T12:00:00Z" + "name": "disableSecretsCompatibility", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Rewrite requests targeting /ds/query to the query service", + "description": "Disable duplicated secret storage in legacy tables", "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresDevMode": true, + "codeowner": "@grafana/hosted-grafana-team", "requiresRestart": true } }, { "metadata": { - "name": "cloudWatchBatchQueries", - "resourceVersion": "1697803200000", - "creationTimestamp": "2023-10-20T12:00:00Z" + "name": "athenaAsyncQueryDataSupport", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Runs CloudWatch metrics queries as separate batches", - "stage": "preview", - "codeowner": "@grafana/aws-datasources" + "description": "Enable async query data support for Athena", + "stage": "GA", + "codeowner": "@grafana/aws-datasources", + "frontend": true } }, { "metadata": { - "name": "recoveryThreshold", - "resourceVersion": "1696939200000", - "creationTimestamp": "2023-10-10T12:00:00Z" + "name": "lokiLogsDataplane", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables feature recovery threshold (aka hysteresis) for threshold server-side expression", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "requiresRestart": true + "description": "Changes logs responses from Loki to be compliant with the dataplane specification.", + "stage": "experimental", + "codeowner": "@grafana/observability-logs" } }, { "metadata": { - "name": "lokiStructuredMetadata", - "resourceVersion": "1707755676105", - "creationTimestamp": "2023-11-16T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-12 16:34:36.105725 +0000 UTC" - } + "name": "enableNativeHTTPHistogram", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the loki data source to request structured metadata from the Loki server", - "stage": "GA", - "codeowner": "@grafana/observability-logs" + "description": "Enables native HTTP Histograms", + "stage": "experimental", + "codeowner": "@grafana/hosted-grafana-team" } }, { "metadata": { - "name": "teamHttpHeaders", - "resourceVersion": "1697544000000", - "creationTimestamp": "2023-10-17T12:00:00Z" + "name": "panelFilterVariable", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables datasources to apply team headers to the client requests", + "description": "Enables use of the `systemPanelFilterVar` variable to filter panels in a dashboard", "stage": "experimental", - "codeowner": "@grafana/identity-access-team" + "codeowner": "@grafana/dashboards-squad", + "frontend": true, + "hideFromDocs": true } }, { "metadata": { - "name": "awsDatasourcesNewFormStyling", - "resourceVersion": "1697112000000", - "creationTimestamp": "2023-10-12T12:00:00Z" + "name": "featureHighlights", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Applies new form styling for configuration and query editors in AWS plugins", - "stage": "preview", - "codeowner": "@grafana/aws-datasources", - "frontend": true + "description": "Highlight Grafana Enterprise features", + "stage": "GA", + "codeowner": "@grafana/grafana-as-code", + "allowSelfServe": true } }, { "metadata": { - "name": "cachingOptimizeSerializationMemoryUsage", - "resourceVersion": "1697112000000", - "creationTimestamp": "2023-10-12T12:00:00Z" + "name": "alertingNoNormalState", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses.", - "stage": "experimental", - "codeowner": "@grafana/grafana-operator-experience-squad" + "description": "Stop maintaining state of alerts that are not firing", + "stage": "preview", + "codeowner": "@grafana/alerting-squad", + "hideFromAdminPage": true } }, { "metadata": { - "name": "panelTitleSearchInV1", - "resourceVersion": "1697198400000", - "creationTimestamp": "2023-10-13T12:00:00Z" + "name": "enableElasticsearchBackendQuerying", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable searching for dashboards using panel title in search v1", - "stage": "experimental", - "codeowner": "@grafana/backend-platform", - "requiresDevMode": true + "description": "Enable the processing of queries and responses in the Elasticsearch data source through backend", + "stage": "GA", + "codeowner": "@grafana/observability-logs", + "allowSelfServe": true } }, { "metadata": { - "name": "pluginsInstrumentationStatusSource", - "resourceVersion": "1697544000000", - "creationTimestamp": "2023-10-17T12:00:00Z" + "name": "displayAnonymousStats", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Include a status source label for plugin request metrics and logs", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend" + "description": "Enables anonymous stats to be shown in the UI for Grafana", + "stage": "GA", + "codeowner": "@grafana/identity-access-team", + "frontend": true } }, { "metadata": { - "name": "managedPluginsInstall", - "resourceVersion": "1697630400000", - "creationTimestamp": "2023-10-18T12:00:00Z" + "name": "nestedFolderPicker", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Install managed plugins directly from plugins catalog", - "stage": "preview", - "codeowner": "@grafana/plugins-platform-backend" + "description": "Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle", + "stage": "GA", + "codeowner": "@grafana/grafana-frontend-platform", + "frontend": true, + "allowSelfServe": true } }, { "metadata": { - "name": "prometheusPromQAIL", - "resourceVersion": "1697716800000", - "creationTimestamp": "2023-10-19T12:00:00Z" + "name": "dataplaneFrontendFallback", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Prometheus and AI/ML to assist users in creating a query", - "stage": "experimental", + "description": "Support dataplane contract field name change for transformations and field name matchers where the name is different", + "stage": "GA", "codeowner": "@grafana/observability-metrics", - "frontend": true + "frontend": true, + "allowSelfServe": true } }, { "metadata": { - "name": "addFieldFromCalculationStatFunctions", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-11-03T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "vizAndWidgetSplit", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Add cumulative and window functions to the add field from calculation transformation", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", + "description": "Split panels between visualizations and widgets", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", "frontend": true } }, { "metadata": { - "name": "alertmanagerRemoteSecondary", - "resourceVersion": "1698667200000", - "creationTimestamp": "2023-10-30T12:00:00Z" + "name": "featureToggleAdminPage", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable Grafana to sync configuration and state with a remote Alertmanager.", + "description": "Enable admin page for managing feature toggles from the Grafana front-end", "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "codeowner": "@grafana/grafana-operator-experience-squad", + "requiresRestart": true } }, { "metadata": { - "name": "alertmanagerRemotePrimary", - "resourceVersion": "1698667200000", - "creationTimestamp": "2023-10-30T12:00:00Z" + "name": "sseGroupByDatasource", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager.", + "description": "Send query to the same datasource in a single request when using server side expressions. The `cloudWatchBatchQueries` feature toggle should be enabled if this used with CloudWatch.", "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "codeowner": "@grafana/observability-metrics" } }, { "metadata": { - "name": "alertmanagerRemoteOnly", - "resourceVersion": "1698667200000", - "creationTimestamp": "2023-10-30T12:00:00Z" + "name": "lokiRunQueriesInParallel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Disable the internal Alertmanager and only use the external one defined.", - "stage": "experimental", - "codeowner": "@grafana/alerting-squad" + "description": "Enables running Loki queries in parallel", + "stage": "privatePreview", + "codeowner": "@grafana/observability-logs" } }, { "metadata": { - "name": "annotationPermissionUpdate", - "resourceVersion": "1698753600000", - "creationTimestamp": "2023-10-31T12:00:00Z" + "name": "awsDatasourcesNewFormStyling", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Separate annotation permissions from dashboard permissions to allow for more granular control.", - "stage": "experimental", - "codeowner": "@grafana/identity-access-team" + "description": "Applies new form styling for configuration and query editors in AWS plugins", + "stage": "preview", + "codeowner": "@grafana/aws-datasources", + "frontend": true } }, { "metadata": { - "name": "extractFieldsNameDeduplication", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-11-02T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "lokiExperimentalStreaming", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Make sure extracted field names are unique in the dataframe", + "description": "Support new streaming approach for loki (prototype, needs special loki build)", "stage": "experimental", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "codeowner": "@grafana/observability-logs" } }, { "metadata": { - "name": "dashboardSceneForViewers", - "resourceVersion": "1698926400000", - "creationTimestamp": "2023-11-02T12:00:00Z" + "name": "disableAngular", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables dashboard rendering using Scenes for viewer roles", - "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", - "frontend": true + "description": "Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime.", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", + "frontend": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "dashboardScene", - "resourceVersion": "1699876800000", - "creationTimestamp": "2023-11-13T12:00:00Z" + "name": "scenes", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables dashboard rendering using scenes for all roles", + "description": "Experimental framework to build interactive dashboards", "stage": "experimental", "codeowner": "@grafana/dashboards-squad", "frontend": true @@ -1675,63 +1651,64 @@ }, { "metadata": { - "name": "panelFilterVariable", - "resourceVersion": "1699012800000", - "creationTimestamp": "2023-11-03T12:00:00Z" + "name": "editPanelCSVDragAndDrop", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables use of the `systemPanelFilterVar` variable to filter panels in a dashboard", + "description": "Enables drag and drop for CSV and Excel files", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", - "frontend": true, - "hideFromDocs": true + "codeowner": "@grafana/dataviz-squad", + "frontend": true } }, { "metadata": { - "name": "pdfTables", - "resourceVersion": "1699272000000", - "creationTimestamp": "2023-11-06T12:00:00Z" + "name": "extraThemes", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables generating table data as PDF in reporting", - "stage": "preview", - "codeowner": "@grafana/sharing-squad" + "description": "Enables extra themes", + "stage": "experimental", + "codeowner": "@grafana/grafana-frontend-platform", + "frontend": true } }, { "metadata": { - "name": "ssoSettingsApi", - "resourceVersion": "1699444800000", - "creationTimestamp": "2023-11-08T12:00:00Z" + "name": "annotationPermissionUpdate", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the SSO settings API", + "description": "Separate annotation permissions from dashboard permissions to allow for more granular control.", "stage": "experimental", "codeowner": "@grafana/identity-access-team" } }, { "metadata": { - "name": "canvasPanelPanZoom", - "resourceVersion": "1703678400000", - "creationTimestamp": "2023-12-27T12:00:00Z" + "name": "exploreContentOutline", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow pan and zoom in canvas panel", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Content outline sidebar", + "stage": "GA", + "codeowner": "@grafana/explore-squad", + "frontend": true, + "allowSelfServe": true } }, { "metadata": { - "name": "logsInfiniteScrolling", - "resourceVersion": "1699531200000", - "creationTimestamp": "2023-11-09T12:00:00Z" + "name": "lokiFormatQuery", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables infinite scrolling for the Logs panel in Explore and Dashboards", + "description": "Enables the ability to format Loki queries", "stage": "experimental", "codeowner": "@grafana/observability-logs", "frontend": true @@ -1739,384 +1716,369 @@ }, { "metadata": { - "name": "flameGraphItemCollapsing", - "resourceVersion": "1699531200000", - "creationTimestamp": "2023-11-09T12:00:00Z" + "name": "prometheusIncrementalQueryInstrumentation", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Allow collapsing of flame graph items", + "description": "Adds RudderStack events to incremental queries", "stage": "experimental", - "codeowner": "@grafana/observability-traces-and-profiling", + "codeowner": "@grafana/observability-metrics", "frontend": true } }, { "metadata": { - "name": "alertingDetailsViewV2", - "resourceVersion": "1699531200000", - "creationTimestamp": "2023-11-09T12:00:00Z" + "name": "alertmanagerRemotePrimary", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the preview of the new alert details view", + "description": "Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager.", "stage": "experimental", - "codeowner": "@grafana/alerting-squad", - "frontend": true, - "hideFromDocs": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "datatrails", - "resourceVersion": "1700049600000", - "creationTimestamp": "2023-11-15T12:00:00Z" + "name": "cloudRBACRoles", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the new core app datatrails", + "description": "Enabled grafana cloud specific RBAC roles", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", - "frontend": true, + "codeowner": "@grafana/identity-access-team", + "requiresRestart": true, "hideFromDocs": true } }, { "metadata": { - "name": "alertingSimplifiedRouting", - "resourceVersion": "1699617600000", - "creationTimestamp": "2023-11-10T12:00:00Z" + "name": "nodeGraphDotLayout", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the simplified routing for alerting", + "description": "Changed the layout algorithm for the node graph", "stage": "experimental", - "codeowner": "@grafana/alerting-squad", - "hideFromDocs": true + "codeowner": "@grafana/observability-traces-and-profiling", + "frontend": true } }, { "metadata": { - "name": "logRowsPopoverMenu", - "resourceVersion": "1700136000000", - "creationTimestamp": "2023-11-16T12:00:00Z" + "name": "autoMigratePiechartPanel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable filtering menu displayed when text of a log line is selected", - "stage": "GA", - "codeowner": "@grafana/observability-logs", + "description": "Migrate old piechart panel to supported piechart panel - broken out from autoMigrateOldPanels to enable granular tracking", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "pluginsSkipHostEnvVars", - "resourceVersion": "1700049600000", - "creationTimestamp": "2023-11-15T12:00:00Z" + "name": "influxdbBackendMigration", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Disables passing host environment variable to plugin processes", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend" + "description": "Query InfluxDB InfluxQL without the proxy", + "stage": "GA", + "codeowner": "@grafana/observability-metrics", + "frontend": true } }, { "metadata": { - "name": "tableSharedCrosshair", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-12-12T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "alertStateHistoryLokiPrimary", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables shared crosshair in table panel", + "description": "Enable a remote Loki instance as the primary source for state history reads.", "stage": "experimental", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "regressionTransformation", - "resourceVersion": "1707523537136", - "creationTimestamp": "2023-11-24T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-10 00:05:37.1362 +0000 UTC" - } + "name": "configurableSchedulerTick", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables regression analysis transformation", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Enable changing the scheduler base interval via configuration option unified_alerting.scheduler_tick_interval", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad", + "requiresRestart": true, + "hideFromDocs": true } }, { "metadata": { - "name": "displayAnonymousStats", - "resourceVersion": "1701259200000", - "creationTimestamp": "2023-11-29T12:00:00Z" + "name": "dashgpt", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables anonymous stats to be shown in the UI for Grafana", - "stage": "GA", - "codeowner": "@grafana/identity-access-team", + "description": "Enable AI powered features in dashboards", + "stage": "preview", + "codeowner": "@grafana/dashboards-squad", "frontend": true } }, { "metadata": { - "name": "lokiQueryHints", - "resourceVersion": "1702900800000", - "creationTimestamp": "2023-12-18T12:00:00Z" + "name": "alertmanagerRemoteOnly", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables query hints for Loki", - "stage": "GA", - "codeowner": "@grafana/observability-logs", - "frontend": true + "description": "Disable the internal Alertmanager and only use the external one defined.", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "kubernetesFeatureToggles", - "resourceVersion": "1703216580000", - "creationTimestamp": "2023-12-22T03:43:00Z" + "name": "alertStateHistoryLokiSecondary", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Use the kubernetes API for feature toggle management in the frontend", + "description": "Enable Grafana to write alert state history to an external Loki instance in addition to Grafana annotations.", "stage": "experimental", - "codeowner": "@grafana/grafana-operator-experience-squad", - "frontend": true, - "hideFromAdminPage": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "alertingPreviewUpgrade", - "resourceVersion": "1707425412785", - "creationTimestamp": "2024-01-03T12:00:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2024-02-08 20:50:12.785364 +0000 UTC" - } + "name": "frontendSandboxMonitorOnly", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Show Unified Alerting preview and upgrade page in legacy alerting", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "requiresRestart": true + "description": "Enables monitor only in the plugin frontend sandbox (if enabled)", + "stage": "experimental", + "codeowner": "@grafana/plugins-platform-backend", + "frontend": true } }, { "metadata": { - "name": "enablePluginsTracingByDefault", - "resourceVersion": "1704801600000", - "creationTimestamp": "2024-01-09T12:00:00Z" + "name": "pluginsDynamicAngularDetectionPatterns", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable plugin tracing for all external plugins", + "description": "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones", "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend", - "requiresRestart": true + "codeowner": "@grafana/plugins-platform-backend" } }, { "metadata": { - "name": "cloudRBACRoles", - "resourceVersion": "1704888000000", - "creationTimestamp": "2024-01-10T12:00:00Z" + "name": "mlExpressions", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enabled grafana cloud specific RBAC roles", + "description": "Enable support for Machine Learning in server-side expressions", "stage": "experimental", - "codeowner": "@grafana/identity-access-team", - "requiresRestart": true, - "hideFromDocs": true + "codeowner": "@grafana/alerting-squad" } }, { "metadata": { - "name": "alertingQueryOptimization", - "resourceVersion": "1704888000000", - "creationTimestamp": "2024-01-10T12:00:00Z" + "name": "pluginsInstrumentationStatusSource", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Optimizes eligible queries in order to reduce load on datasources", - "stage": "GA", - "codeowner": "@grafana/alerting-squad" + "description": "Include a status source label for plugin request metrics and logs", + "stage": "experimental", + "codeowner": "@grafana/plugins-platform-backend" } }, { "metadata": { - "name": "newFolderPicker", - "resourceVersion": "1705060800000", - "creationTimestamp": "2024-01-12T12:00:00Z" + "name": "autoMigrateWorldmapPanel", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the nested folder picker without having nested folders enabled", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform", + "description": "Migrate old worldmap panel to supported geomap panel - broken out from autoMigrateOldPanels to enable granular tracking", + "stage": "preview", + "codeowner": "@grafana/dataviz-squad", "frontend": true } }, { "metadata": { - "name": "jitterAlertRulesWithinGroups", - "resourceVersion": "1705492800000", - "creationTimestamp": "2024-01-17T12:00:00Z" + "name": "recoveryThreshold", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Distributes alert rule evaluations more evenly over time, including spreading out rules within the same group", - "stage": "preview", + "description": "Enables feature recovery threshold (aka hysteresis) for threshold server-side expression", + "stage": "GA", "codeowner": "@grafana/alerting-squad", - "requiresRestart": true, - "hideFromDocs": true + "requiresRestart": true } }, { "metadata": { - "name": "onPremToCloudMigrations", - "resourceVersion": "1705894200000", - "creationTimestamp": "2024-01-22T03:30:00Z" + "name": "cachingOptimizeSerializationMemoryUsage", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "In-development feature that will allow users to easily migrate their on-prem Grafana instances to Grafana Cloud.", + "description": "If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses.", "stage": "experimental", "codeowner": "@grafana/grafana-operator-experience-squad" } }, { "metadata": { - "name": "alertingSaveStatePeriodic", - "resourceVersion": "1705924800000", - "creationTimestamp": "2024-01-22T12:00:00Z" + "name": "dashboardSceneForViewers", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Writes the state periodically to the database, asynchronous to rule evaluation", - "stage": "privatePreview", - "codeowner": "@grafana/alerting-squad" + "description": "Enables dashboard rendering using Scenes for viewer roles", + "stage": "experimental", + "codeowner": "@grafana/dashboards-squad", + "frontend": true } }, { "metadata": { - "name": "promQLScope", - "resourceVersion": "1706486400000", - "creationTimestamp": "2024-01-29T00:00:00Z" + "name": "flameGraphItemCollapsing", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "In-development feature that will allow injection of labels into prometheus queries.", + "description": "Allow collapsing of flame graph items", "stage": "experimental", - "codeowner": "@grafana/observability-metrics" + "codeowner": "@grafana/observability-traces-and-profiling", + "frontend": true } }, { "metadata": { - "name": "nodeGraphDotLayout", - "resourceVersion": "1704196800000", - "creationTimestamp": "2024-01-02T12:00:00Z" + "name": "datasourceQueryMultiStatus", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Changed the layout algorithm for the node graph", + "description": "Introduce HTTP 207 Multi Status for api/ds/query", "stage": "experimental", - "codeowner": "@grafana/observability-traces-and-profiling", - "frontend": true + "codeowner": "@grafana/plugins-platform-backend" } }, { "metadata": { - "name": "groupToNestedTableTransformation", - "resourceVersion": "1707134400000", - "creationTimestamp": "2024-02-05T12:00:00Z" + "name": "redshiftAsyncQueryDataSupport", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables the group to nested table transformation", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Enable async query data support for Redshift", + "stage": "GA", + "codeowner": "@grafana/aws-datasources" } }, { "metadata": { - "name": "newPDFRendering", - "resourceVersion": "1707425412785", - "creationTimestamp": "2024-02-08T20:50:12Z" + "name": "individualCookiePreferences", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "New implementation for the dashboard to PDF rendering", + "description": "Support overriding cookie preferences per user", "stage": "experimental", - "codeowner": "@grafana/sharing-squad" + "codeowner": "@grafana/backend-platform" } }, { "metadata": { - "name": "autoMigrateGraphPanel", - "resourceVersion": "1707433170195", - "creationTimestamp": "2024-02-08T22:59:30Z" + "name": "faroDatasourceSelector", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old graph panel to supported time series panel - broken out from autoMigrateOldPanels to enable granular tracking", + "description": "Enable the data source selector within the Frontend Apps section of the Frontend Observability", "stage": "preview", - "codeowner": "@grafana/dataviz-squad", + "codeowner": "@grafana/app-o11y", "frontend": true } }, { "metadata": { - "name": "dashboardSceneSolo", - "resourceVersion": "1707577534071", - "creationTimestamp": "2024-02-10T15:05:34Z" + "name": "kubernetesPlaylists", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enables rendering dashboards using scenes for solo panels", + "description": "Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s", "stage": "experimental", - "codeowner": "@grafana/dashboards-squad", - "frontend": true + "codeowner": "@grafana/grafana-app-platform-squad", + "requiresRestart": true } }, { "metadata": { - "name": "kubernetesAggregator", - "resourceVersion": "1707775742552", - "creationTimestamp": "2024-02-12T22:09:02Z" + "name": "alertingDetailsViewV2", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Enable grafana aggregator", + "description": "Enables the preview of the new alert details view", "stage": "experimental", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresRestart": true + "codeowner": "@grafana/alerting-squad", + "frontend": true, + "hideFromDocs": true } }, { "metadata": { - "name": "autoMigrateStatPanel", - "resourceVersion": "1707922335937", - "creationTimestamp": "2024-02-14T14:52:15Z" + "name": "accessControlOnCall", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old stat panel to supported stat panel - broken out from autoMigrateOldPanels to enable granular tracking", + "description": "Access control primitives for OnCall", "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "codeowner": "@grafana/identity-access-team", + "hideFromAdminPage": true } }, { "metadata": { - "name": "autoMigratePiechartPanel", - "resourceVersion": "1707922335937", - "creationTimestamp": "2024-02-14T14:52:15Z" + "name": "splitScopes", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old piechart panel to supported piechart panel - broken out from autoMigrateOldPanels to enable granular tracking", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Support faster dashboard and folder search by splitting permission scopes into parts", + "stage": "deprecated", + "codeowner": "@grafana/identity-access-team", + "requiresRestart": true, + "hideFromAdminPage": true } }, { "metadata": { - "name": "autoMigrateTablePanel", - "resourceVersion": "1707922335937", - "creationTimestamp": "2024-02-14T14:52:15Z" + "name": "formatString", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old table panel to supported table panel - broken out from autoMigrateOldPanels to enable granular tracking", + "description": "Enable format string transformer", "stage": "preview", "codeowner": "@grafana/dataviz-squad", "frontend": true @@ -2124,15 +2086,28 @@ }, { "metadata": { - "name": "autoMigrateWorldmapPanel", - "resourceVersion": "1707922335937", - "creationTimestamp": "2024-02-14T14:52:15Z" + "name": "alertingSimplifiedRouting", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" }, "spec": { - "description": "Migrate old worldmap panel to supported geomap panel - broken out from autoMigrateOldPanels to enable granular tracking", - "stage": "preview", - "codeowner": "@grafana/dataviz-squad", - "frontend": true + "description": "Enables the simplified routing for alerting", + "stage": "experimental", + "codeowner": "@grafana/alerting-squad", + "hideFromDocs": true + } + }, + { + "metadata": { + "name": "enablePluginsTracingByDefault", + "resourceVersion": "1707928895402", + "creationTimestamp": "2024-02-14T16:41:35Z" + }, + "spec": { + "description": "Enable plugin tracing for all external plugins", + "stage": "experimental", + "codeowner": "@grafana/plugins-platform-backend", + "requiresRestart": true } } ] diff --git a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts index 3bb0cc046cc..e6b1c6576e5 100644 --- a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts +++ b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.test.ts @@ -11,12 +11,13 @@ import { toDataFrame, VariableSupportType, } from '@grafana/data'; -import { setRunRequest } from '@grafana/runtime'; +import { config, setRunRequest } from '@grafana/runtime'; import { AdHocFiltersVariable, ConstantVariable, CustomVariable, DataSourceVariable, + GroupByVariable, QueryVariable, SceneVariableSet, TextBoxVariable, @@ -401,4 +402,92 @@ describe('sceneVariablesSetToVariables', () => { } `); }); + + describe('when the groupByVariable feature toggle is enabled', () => { + beforeAll(() => { + config.featureToggles.groupByVariable = true; + }); + + afterAll(() => { + config.featureToggles.groupByVariable = false; + }); + + it('should handle GroupByVariable', () => { + const variable = new GroupByVariable({ + name: 'test', + label: 'test-label', + description: 'test-desc', + datasource: { uid: 'fake-std', type: 'fake-std' }, + defaultOptions: [ + { + text: 'Foo', + value: 'foo', + }, + { + text: 'Bar', + value: 'bar', + }, + ], + }); + const set = new SceneVariableSet({ + variables: [variable], + }); + + const result = sceneVariablesSetToVariables(set); + + expect(result).toHaveLength(1); + expect(result[0]).toMatchInlineSnapshot(` + { + "current": { + "text": [], + "value": [], + }, + "datasource": { + "type": "fake-std", + "uid": "fake-std", + }, + "description": "test-desc", + "label": "test-label", + "name": "test", + "options": [ + { + "text": "Foo", + "value": "foo", + }, + { + "text": "Bar", + "value": "bar", + }, + ], + "type": "groupby", + } + `); + }); + }); + + describe('when the groupByVariable feature toggle is disabled', () => { + it('should not handle GroupByVariable and throw an error', () => { + const variable = new GroupByVariable({ + name: 'test', + label: 'test-label', + description: 'test-desc', + datasource: { uid: 'fake-std', type: 'fake-std' }, + defaultOptions: [ + { + text: 'Foo', + value: 'foo', + }, + { + text: 'Bar', + value: 'bar', + }, + ], + }); + const set = new SceneVariableSet({ + variables: [variable], + }); + + expect(() => sceneVariablesSetToVariables(set)).toThrow('Unsupported variable type'); + }); + }); }); diff --git a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts index 928afaa5e9b..28ff40870b3 100644 --- a/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts +++ b/public/app/features/dashboard-scene/serialization/sceneVariablesSetToVariables.ts @@ -1,3 +1,4 @@ +import { config } from '@grafana/runtime'; import { SceneVariables, sceneUtils } from '@grafana/scenes'; import { VariableHide, VariableModel, VariableRefresh, VariableSort } from '@grafana/schema'; @@ -104,6 +105,22 @@ export function sceneVariablesSetToVariables(set: SceneVariables) { }, query: variable.state.value, }); + } else if (sceneUtils.isGroupByVariable(variable) && config.featureToggles.groupByVariable) { + variables.push({ + ...commonProperties, + datasource: variable.state.datasource, + // Only persist the statically defined options + options: variable.state.defaultOptions?.map((option) => ({ + text: option.text, + value: String(option.value), + })), + current: { + // @ts-expect-error + text: variable.state.text, + // @ts-expect-error + value: variable.state.value, + }, + }); } else if (sceneUtils.isAdHocVariable(variable)) { variables.push({ ...commonProperties, diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts index 1a6f59fa4d7..52f8757b376 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts @@ -7,6 +7,7 @@ import { IntervalVariableModel, TypedVariableModel, TextBoxVariableModel, + GroupByVariableModel, } from '@grafana/data'; import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks'; import { config } from '@grafana/runtime'; @@ -16,6 +17,7 @@ import { ConstantVariable, CustomVariable, DataSourceVariable, + GroupByVariable, QueryVariable, SceneDataLayerControls, SceneDataLayers, @@ -844,6 +846,116 @@ describe('transformSaveModelToScene', () => { }); }); + describe('when groupByVariable feature toggle is enabled', () => { + beforeAll(() => { + config.featureToggles.groupByVariable = true; + }); + + afterAll(() => { + config.featureToggles.groupByVariable = false; + }); + + it('should migrate groupby variable', () => { + const variable: GroupByVariableModel = { + id: 'groupby', + global: false, + index: 0, + state: LoadingState.Done, + error: null, + name: 'groupby', + label: 'GroupBy Label', + description: 'GroupBy Description', + type: 'groupby', + rootStateKey: 'N4XLmH5Vz', + datasource: { + uid: 'gdev-prometheus', + type: 'prometheus', + }, + multi: true, + options: [ + { + selected: false, + text: 'Foo', + value: 'foo', + }, + { + selected: false, + text: 'Bar', + value: 'bar', + }, + ], + current: {}, + query: '', + hide: 0, + skipUrlSync: false, + }; + + const migrated = createSceneVariableFromVariableModel(variable) as GroupByVariable; + const groupbyVarState = migrated.state; + + expect(migrated).toBeInstanceOf(GroupByVariable); + expect(groupbyVarState).toEqual({ + key: expect.any(String), + description: 'GroupBy Description', + hide: 0, + defaultOptions: [ + { + selected: false, + text: 'Foo', + value: 'foo', + }, + { + selected: false, + text: 'Bar', + value: 'bar', + }, + ], + isMulti: true, + layout: 'horizontal', + noValueOnClear: true, + label: 'GroupBy Label', + name: 'groupby', + skipUrlSync: false, + type: 'groupby', + baseFilters: [], + options: [], + text: [], + value: [], + datasource: { uid: 'gdev-prometheus', type: 'prometheus' }, + applyMode: 'auto', + }); + }); + }); + + describe('when groupByVariable feature toggle is disabled', () => { + it('should not migrate groupby variable and throw an error instead', () => { + const variable: GroupByVariableModel = { + id: 'groupby', + global: false, + index: 0, + state: LoadingState.Done, + error: null, + name: 'groupby', + label: 'GroupBy Label', + description: 'GroupBy Description', + type: 'groupby', + rootStateKey: 'N4XLmH5Vz', + datasource: { + uid: 'gdev-prometheus', + type: 'prometheus', + }, + multi: true, + options: [], + current: {}, + query: '', + hide: 0, + skipUrlSync: false, + }; + + expect(() => createSceneVariableFromVariableModel(variable)).toThrow('Scenes: Unsupported variable type'); + }); + }); + it.each(['system'])('should throw for unsupported (yet) variables', (type) => { const variable = { name: 'query0', diff --git a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts index cb3d3795605..b85744efcfe 100644 --- a/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts +++ b/public/app/features/dashboard-scene/serialization/transformSaveModelToScene.ts @@ -26,6 +26,7 @@ import { SceneDataLayerControls, TextBoxVariable, UserActionEvent, + GroupByVariable, AdHocFiltersVariable, } from '@grafana/scenes'; import { DashboardModel, PanelModel } from 'app/features/dashboard/state'; @@ -291,6 +292,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode const commonProperties = { name: variable.name, label: variable.label, + description: variable.description, }; if (variable.type === 'adhoc') { return new AdHocFiltersVariable({ @@ -309,7 +311,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode ...commonProperties, value: variable.current?.value ?? '', text: variable.current?.text ?? '', - description: variable.description, + query: variable.query, isMulti: variable.multi, allValue: variable.allValue || undefined, @@ -323,7 +325,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode ...commonProperties, value: variable.current?.value ?? '', text: variable.current?.text ?? '', - description: variable.description, + query: variable.query, datasource: variable.datasource, sort: variable.sort, @@ -342,7 +344,6 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode ...commonProperties, value: variable.current?.value ?? '', text: variable.current?.text ?? '', - description: variable.description, regex: variable.regex, pluginId: variable.query, allValue: variable.allValue || undefined, @@ -358,7 +359,6 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode return new IntervalVariable({ ...commonProperties, value: currentInterval, - description: variable.description, intervals: intervals, autoEnabled: variable.auto, autoStepCount: variable.auto_count, @@ -370,7 +370,6 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode } else if (variable.type === 'constant') { return new ConstantVariable({ ...commonProperties, - description: variable.description, value: variable.query, skipUrlSync: variable.skipUrlSync, hide: variable.hide, @@ -378,11 +377,21 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode } else if (variable.type === 'textbox') { return new TextBoxVariable({ ...commonProperties, - description: variable.description, value: variable.query, skipUrlSync: variable.skipUrlSync, hide: variable.hide, }); + } else if (config.featureToggles.groupByVariable && variable.type === 'groupby') { + return new GroupByVariable({ + ...commonProperties, + datasource: variable.datasource, + value: variable.current?.value || [], + text: variable.current?.text || [], + skipUrlSync: variable.skipUrlSync, + hide: variable.hide, + // @ts-expect-error + defaultOptions: variable.options, + }); } else { throw new Error(`Scenes: Unsupported variable type ${variable.type}`); } diff --git a/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.test.tsx b/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.test.tsx new file mode 100644 index 00000000000..e59b0e4f3e0 --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.test.tsx @@ -0,0 +1,114 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { byTestId } from 'testing-library-selector'; + +import { VariableSupportType } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { mockDataSource } from 'app/features/alerting/unified/mocks'; +import { LegacyVariableQueryEditor } from 'app/features/variables/editor/LegacyVariableQueryEditor'; + +import { GroupByVariableForm, GroupByVariableFormProps } from './GroupByVariableForm'; + +const defaultDatasource = mockDataSource({ + name: 'Default Test Data Source', + type: 'test', +}); + +const promDatasource = mockDataSource({ + name: 'Prometheus', + type: 'prometheus', +}); + +jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => ({ + ...jest.requireActual('@grafana/runtime/src/services/dataSourceSrv'), + getDataSourceSrv: () => ({ + get: async () => ({ + ...defaultDatasource, + variables: { + getType: () => VariableSupportType.Custom, + query: jest.fn(), + editor: jest.fn().mockImplementation(LegacyVariableQueryEditor), + }, + }), + getList: () => [defaultDatasource, promDatasource], + getInstanceSettings: () => ({ ...defaultDatasource }), + }), +})); + +describe('GroupByVariableForm', () => { + const onDataSourceChangeMock = jest.fn(); + const onDefaultOptionsChangeMock = jest.fn(); + + const defaultProps: GroupByVariableFormProps = { + onDataSourceChange: onDataSourceChangeMock, + onDefaultOptionsChange: onDefaultOptionsChangeMock, + }; + + function setup(props?: Partial) { + return { + renderer: render(), + user: userEvent.setup(), + }; + } + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should call onDataSourceChange when changing the datasource', async () => { + const { + renderer: { getByTestId }, + } = setup(); + const dataSourcePicker = getByTestId(selectors.components.DataSourcePicker.inputV2); + await userEvent.click(dataSourcePicker); + await userEvent.click(screen.getByText(/prometheus/i)); + + expect(onDataSourceChangeMock).toHaveBeenCalledTimes(1); + expect(onDataSourceChangeMock).toHaveBeenCalledWith(promDatasource, undefined); + }); + + it('should not render code editor when no default options provided', async () => { + const { + renderer: { queryByTestId }, + } = setup(); + const codeEditor = queryByTestId(selectors.components.CodeEditor.container); + + expect(codeEditor).not.toBeInTheDocument(); + }); + + it('should render code editor when default options provided', async () => { + const { + renderer: { getByTestId }, + } = setup({ defaultOptions: [{ text: 'test', value: 'test' }] }); + const codeEditor = getByTestId(selectors.components.CodeEditor.container); + + await byTestId(selectors.components.CodeEditor.container).find(); + + expect(codeEditor).toBeInTheDocument(); + }); + + it('should call onDefaultOptionsChange when providing static options', async () => { + const { + renderer: { getByTestId }, + } = setup(); + + const toggle = getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle); + + await userEvent.click(toggle); + expect(onDefaultOptionsChangeMock).toHaveBeenCalledTimes(1); + expect(onDefaultOptionsChangeMock).toHaveBeenCalledWith([]); + }); + + it('should call onDefaultOptionsChange when toggling off static options', async () => { + const { + renderer: { getByTestId }, + } = setup({ defaultOptions: [{ text: 'test', value: 'test' }] }); + + const toggle = getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle); + + await userEvent.click(toggle); + expect(onDefaultOptionsChangeMock).toHaveBeenCalledTimes(1); + expect(onDefaultOptionsChangeMock).toHaveBeenCalledWith(undefined); + }); +}); diff --git a/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.tsx new file mode 100644 index 00000000000..194ff364174 --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.tsx @@ -0,0 +1,84 @@ +import React, { useCallback } from 'react'; + +import { DataSourceInstanceSettings, MetricFindValue, readCSV } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { DataSourceRef } from '@grafana/schema'; +import { Alert, CodeEditor, Field, Switch } from '@grafana/ui'; +import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker'; + +import { VariableLegend } from './VariableLegend'; + +export interface GroupByVariableFormProps { + datasource?: DataSourceRef; + onDataSourceChange: (dsSettings: DataSourceInstanceSettings) => void; + onDefaultOptionsChange: (options?: MetricFindValue[]) => void; + infoText?: string; + defaultOptions?: MetricFindValue[]; +} + +export function GroupByVariableForm({ + datasource, + defaultOptions, + infoText, + onDataSourceChange, + onDefaultOptionsChange, +}: GroupByVariableFormProps) { + const updateDefaultOptions = useCallback( + (csvContent: string) => { + const df = readCSV('key,value\n' + csvContent)[0]; + const options = []; + for (let i = 0; i < df.length; i++) { + options.push({ text: df.fields[0].values[i], value: df.fields[1].values[i] }); + } + + onDefaultOptionsChange(options); + }, + [onDefaultOptionsChange] + ); + + return ( + <> + Group by options + + + + + {infoText ? ( + + ) : null} + + + { + if (defaultOptions === undefined) { + onDefaultOptionsChange([]); + } else { + onDefaultOptionsChange(undefined); + } + }} + /> + + + {defaultOptions !== undefined && ( + `${o.text},${o.value}`).join('\n')} + onBlur={updateDefaultOptions} + onSave={updateDefaultOptions} + showMiniMap={false} + showLineNumbers={true} + /> + )} + + ); +} diff --git a/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.test.tsx b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.test.tsx new file mode 100644 index 00000000000..48b01d8f08f --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.test.tsx @@ -0,0 +1,103 @@ +import { act, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { MetricFindValue, VariableSupportType } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { GroupByVariable } from '@grafana/scenes'; +import { mockDataSource } from 'app/features/alerting/unified/mocks'; +import { LegacyVariableQueryEditor } from 'app/features/variables/editor/LegacyVariableQueryEditor'; + +import { GroupByVariableEditor } from './GroupByVariableEditor'; + +const defaultDatasource = mockDataSource({ + name: 'Default Test Data Source', + uid: 'test-ds', + type: 'test', +}); + +const promDatasource = mockDataSource({ + name: 'Prometheus', + uid: 'prometheus', + type: 'prometheus', +}); + +jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => ({ + ...jest.requireActual('@grafana/runtime/src/services/dataSourceSrv'), + getDataSourceSrv: () => ({ + get: async () => ({ + ...defaultDatasource, + variables: { + getType: () => VariableSupportType.Custom, + query: jest.fn(), + editor: jest.fn().mockImplementation(LegacyVariableQueryEditor), + }, + }), + getList: () => [defaultDatasource, promDatasource], + getInstanceSettings: () => ({ ...defaultDatasource }), + }), +})); + +describe('GroupByVariableEditor', () => { + it('renders AdHocVariableForm with correct props', async () => { + const { renderer } = await setup(); + const dataSourcePicker = renderer.getByTestId( + selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.dataSourceSelect + ); + const infoText = renderer.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.infoText); + + expect(dataSourcePicker).toBeInTheDocument(); + expect(dataSourcePicker.getAttribute('placeholder')).toBe('Default Test Data Source'); + expect(infoText).toBeInTheDocument(); + expect(infoText).toHaveTextContent('This data source does not support group by variable yet.'); + }); + + it('should update the variable data source when data source picker is changed', async () => { + const { renderer, variable, user } = await setup(); + + // Simulate changing the data source + await user.click(renderer.getByTestId(selectors.components.DataSourcePicker.inputV2)); + await user.click(renderer.getByText(/prom/i)); + + expect(variable.state.datasource).toEqual({ uid: 'prometheus', type: 'prometheus' }); + }); + + it('should update the variable default options when static options are enabled', async () => { + const { renderer, variable, user } = await setup(); + + // Simulate toggling static options on + await user.click( + renderer.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle) + ); + + expect(variable.state.defaultOptions).toEqual([]); + }); + + it('should update the variable default options when static options are disabled', async () => { + const { renderer, variable, user } = await setup([{ text: 'A', value: 'A' }]); + + // Simulate toggling static options off + await user.click( + renderer.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle) + ); + + expect(variable.state.defaultOptions).toEqual(undefined); + }); +}); + +async function setup(defaultOptions?: MetricFindValue[]) { + const onRunQuery = jest.fn(); + const variable = new GroupByVariable({ + name: 'groupByVariable', + type: 'groupby', + label: 'Group By', + datasource: { uid: defaultDatasource.uid, type: defaultDatasource.type }, + defaultOptions, + }); + return { + renderer: await act(() => render()), + variable, + user: userEvent.setup(), + mocks: { onRunQuery }, + }; +} diff --git a/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx index 8637fb23e5c..01cffb31c84 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/GroupByVariableEditor.tsx @@ -1,12 +1,51 @@ import React from 'react'; +import { useAsync } from 'react-use'; +import { DataSourceInstanceSettings, DataSourceRef, MetricFindValue } from '@grafana/data'; +import { getDataSourceSrv } from '@grafana/runtime'; import { GroupByVariable } from '@grafana/scenes'; +import { GroupByVariableForm } from '../components/GroupByVariableForm'; + interface GroupByVariableEditorProps { variable: GroupByVariable; - onChange: (variable: GroupByVariable) => void; + onRunQuery: () => void; } export function GroupByVariableEditor(props: GroupByVariableEditorProps) { - return
GroupByVariableEditor
; + const { variable, onRunQuery } = props; + const { datasource: datasourceRef, defaultOptions } = variable.useState(); + + const { value: datasource } = useAsync(async () => { + return await getDataSourceSrv().get(datasourceRef); + }, [variable.state]); + + const message = datasource?.getTagKeys + ? 'Group by dimensions are applied automatically to all queries that target this data source' + : 'This data source does not support group by variable yet.'; + + const onDataSourceChange = async (ds: DataSourceInstanceSettings) => { + const dsRef: DataSourceRef = { + uid: ds.uid, + type: ds.type, + }; + + variable.setState({ datasource: dsRef }); + onRunQuery(); + }; + + const onDefaultOptionsChange = async (defaultOptions?: MetricFindValue[]) => { + variable.setState({ defaultOptions }); + onRunQuery(); + }; + + return ( + + ); } diff --git a/public/app/features/dashboard-scene/settings/variables/utils.test.ts b/public/app/features/dashboard-scene/settings/variables/utils.test.ts index 2b2c42d1ca8..64a14b84fc3 100644 --- a/public/app/features/dashboard-scene/settings/variables/utils.test.ts +++ b/public/app/features/dashboard-scene/settings/variables/utils.test.ts @@ -1,5 +1,5 @@ import { DataSourceApi } from '@grafana/data'; -import { setTemplateSrv, TemplateSrv } from '@grafana/runtime'; +import { config, setTemplateSrv, TemplateSrv } from '@grafana/runtime'; import { CustomVariable, ConstantVariable, @@ -99,26 +99,61 @@ describe('isEditableVariableType', () => { }); describe('getVariableTypeSelectOptions', () => { - it('should contain all editable variable types', () => { - const options = getVariableTypeSelectOptions(); - expect(options).toHaveLength(Object.keys(EDITABLE_VARIABLES).length); + describe('when groupByVariable is enabled', () => { + beforeAll(() => { + config.featureToggles.groupByVariable = true; + }); + + afterAll(() => { + config.featureToggles.groupByVariable = false; + }); - EDITABLE_VARIABLES_SELECT_ORDER.forEach((type) => { - expect(EDITABLE_VARIABLES).toHaveProperty(type); + it('should contain all editable variable types', () => { + const options = getVariableTypeSelectOptions(); + expect(options).toHaveLength(Object.keys(EDITABLE_VARIABLES).length); + + EDITABLE_VARIABLES_SELECT_ORDER.forEach((type) => { + expect(EDITABLE_VARIABLES).toHaveProperty(type); + }); + }); + + it('should return an array of selectable values for editable variable types', () => { + const options = getVariableTypeSelectOptions(); + expect(options).toHaveLength(8); + + options.forEach((option, index) => { + const editableType = EDITABLE_VARIABLES_SELECT_ORDER[index]; + const variableTypeConfig = EDITABLE_VARIABLES[editableType]; + + expect(option.value).toBe(editableType); + expect(option.label).toBe(variableTypeConfig.name); + expect(option.description).toBe(variableTypeConfig.description); + }); }); }); - it('should return an array of selectable values for editable variable types', () => { - const options = getVariableTypeSelectOptions(); - expect(options).toHaveLength(8); + describe('when groupByVariable is disabled', () => { + it('should contain all editable variable types except groupby', () => { + const options = getVariableTypeSelectOptions(); + expect(options).toHaveLength(Object.keys(EDITABLE_VARIABLES).length - 1); + + EDITABLE_VARIABLES_SELECT_ORDER.forEach((type) => { + expect(EDITABLE_VARIABLES).toHaveProperty(type); + }); + }); + + it('should return an array of selectable values for editable variable types', () => { + const options = getVariableTypeSelectOptions(); + expect(options).toHaveLength(7); - options.forEach((option, index) => { - const editableType = EDITABLE_VARIABLES_SELECT_ORDER[index]; - const variableTypeConfig = EDITABLE_VARIABLES[editableType]; + options.forEach((option, index) => { + const editableType = EDITABLE_VARIABLES_SELECT_ORDER[index]; + const variableTypeConfig = EDITABLE_VARIABLES[editableType]; - expect(option.value).toBe(editableType); - expect(option.label).toBe(variableTypeConfig.name); - expect(option.description).toBe(variableTypeConfig.description); + expect(option.value).toBe(editableType); + expect(option.label).toBe(variableTypeConfig.name); + expect(option.description).toBe(variableTypeConfig.description); + }); }); }); }); diff --git a/public/app/features/dashboard-scene/settings/variables/utils.ts b/public/app/features/dashboard-scene/settings/variables/utils.ts index 1d61b445b6b..74207efa750 100644 --- a/public/app/features/dashboard-scene/settings/variables/utils.ts +++ b/public/app/features/dashboard-scene/settings/variables/utils.ts @@ -1,7 +1,7 @@ import { chain } from 'lodash'; import { DataSourceInstanceSettings, SelectableValue } from '@grafana/data'; -import { getDataSourceSrv } from '@grafana/runtime'; +import { config, getDataSourceSrv } from '@grafana/runtime'; import { ConstantVariable, CustomVariable, @@ -95,11 +95,18 @@ export const EDITABLE_VARIABLES_SELECT_ORDER: EditableVariableType[] = [ ]; export function getVariableTypeSelectOptions(): Array> { - return EDITABLE_VARIABLES_SELECT_ORDER.map((variableType) => ({ + const results = EDITABLE_VARIABLES_SELECT_ORDER.map((variableType) => ({ label: EDITABLE_VARIABLES[variableType].name, value: variableType, description: EDITABLE_VARIABLES[variableType].description, })); + + if (!config.featureToggles.groupByVariable) { + // Remove group by variable type if feature toggle is off + return results.filter((option) => option.value !== 'groupby'); + } + + return results; } export function getVariableEditor(type: EditableVariableType) { diff --git a/public/app/features/variables/guard.test.ts b/public/app/features/variables/guard.test.ts index 17e22c9ccce..cd65f21e621 100644 --- a/public/app/features/variables/guard.test.ts +++ b/public/app/features/variables/guard.test.ts @@ -165,7 +165,7 @@ describe('type guards', () => { const variableFactsObj: Record = { query: { variable: createQueryVariable(), isMulti: true, hasOptions: true, hasCurrent: true }, adhoc: { variable: createAdhocVariable(), isMulti: false, hasOptions: false, hasCurrent: false }, - groupby: { variable: createGroupByVariable(), isMulti: true, hasOptions: false, hasCurrent: false }, + groupby: { variable: createGroupByVariable(), isMulti: true, hasOptions: true, hasCurrent: true }, constant: { variable: createConstantVariable(), isMulti: false, hasOptions: true, hasCurrent: true }, datasource: { variable: createDatasourceVariable(), isMulti: true, hasOptions: true, hasCurrent: true }, interval: { variable: createIntervalVariable(), isMulti: false, hasOptions: true, hasCurrent: true }, diff --git a/public/app/features/variables/state/__tests__/fixtures.ts b/public/app/features/variables/state/__tests__/fixtures.ts index 6014a6a33ce..d30052bc886 100644 --- a/public/app/features/variables/state/__tests__/fixtures.ts +++ b/public/app/features/variables/state/__tests__/fixtures.ts @@ -82,12 +82,14 @@ export function createAdhocVariable(input?: Partial): AdHocV export function createGroupByVariable(input?: Partial): GroupByVariableModel { return { ...createBaseVariableModel('groupby'), + query: '', datasource: { uid: 'abc-123', type: 'prometheus', }, - groupByKeys: [], multi: true, + current: createVariableOption('job'), + options: [createVariableOption('job'), createVariableOption('instance')], ...input, }; }