From 3503fc209e97946b22c1e4fe23c766bf341b4ddd Mon Sep 17 00:00:00 2001 From: Adam Yeats <16296989+adamyeats@users.noreply.github.com> Date: Wed, 25 Jun 2025 17:39:54 +0100 Subject: [PATCH] InfluxDB: Config page refresh (#103060) --- .../src/types/featureToggles.gen.ts | 5 + pkg/services/featuremgmt/registry.go | 8 + pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.go | 4 + pkg/services/featuremgmt/toggles_gen.json | 960 +++++------------- .../datasources/components/ButtonRow.tsx | 1 + .../datasources/components/EditDataSource.tsx | 12 +- .../AdvancedDBConnectionSettings.test.tsx | 104 ++ .../AdvancedDBConnectionSettings.tsx | 100 ++ .../config-v2/AdvancedHttpSettings.test.tsx | 71 ++ .../editor/config-v2/AdvancedHttpSettings.tsx | 119 +++ .../editor/config-v2/AuthSettings.test.tsx | 131 +++ .../editor/config-v2/AuthSettings.tsx | 267 +++++ .../editor/config-v2/ConfigEditor.test.tsx | 44 + .../editor/config-v2/ConfigEditor.tsx | 41 + .../DatabaseConnectionSection.test.tsx | 96 ++ .../config-v2/DatabaseConnectionSection.tsx | 65 ++ .../config-v2/InfluxFluxDBConnection.test.tsx | 46 + .../config-v2/InfluxFluxDBConnection.tsx | 58 ++ .../InfluxInfluxQLDBConnection.test.tsx | 41 + .../config-v2/InfluxInfluxQLDBConnection.tsx | 57 ++ .../config-v2/InfluxSQLDBConnection.test.tsx | 39 + .../config-v2/InfluxSQLDBConnection.tsx | 45 + .../editor/config-v2/LeftSideBar.test.tsx | 16 + .../editor/config-v2/LeftSideBar.tsx | 40 + .../UrlAndAuthenticationSection.test.tsx | 90 ++ .../config-v2/UrlAndAuthenticationSection.tsx | 131 +++ .../components/editor/config-v2/constants.ts | 57 ++ .../components/editor/config-v2/helpers.ts | 33 + .../components/editor/config-v2/tracking.ts | 89 ++ .../components/editor/config-v2/types.ts | 22 + .../components/editor/config-v2/versions.ts | 141 +++ .../app/plugins/datasource/influxdb/module.ts | 9 +- .../app/plugins/datasource/influxdb/types.ts | 2 + 34 files changed, 2247 insertions(+), 698 deletions(-) create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/helpers.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/tracking.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/types.ts create mode 100644 public/app/plugins/datasource/influxdb/components/editor/config-v2/versions.ts diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 2f5b4fe42b9..a4967e6a4eb 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -1037,4 +1037,9 @@ export interface FeatureToggles { * @default true */ tabularNumbers?: boolean; + /** + * Enables new design for the InfluxDB data source configuration page + * @default false + */ + newInfluxDSConfigPageDesign?: boolean; } diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 91ab4752a9a..5b0fde051e6 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1780,6 +1780,14 @@ var ( Owner: grafanaFrontendPlatformSquad, Expression: "true", }, + { + Name: "newInfluxDSConfigPageDesign", + Description: "Enables new design for the InfluxDB data source configuration page", + Stage: FeatureStagePrivatePreview, + FrontendOnly: false, + Owner: grafanaPartnerPluginsSquad, + Expression: "false", + }, } ) diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index c103891a09e..797c0f90489 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -232,3 +232,4 @@ alertEnrichment,experimental,@grafana/alerting-squad,false,false,false alertingImportAlertmanagerAPI,experimental,@grafana/alerting-squad,false,false,false preferLibraryPanelTitle,privatePreview,@grafana/dashboards-squad,false,false,false tabularNumbers,GA,@grafana/grafana-frontend-platform,false,false,false +newInfluxDSConfigPageDesign,privatePreview,@grafana/partner-datasources,false,false,false diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 119d8ecf983..e655ea930f8 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -938,4 +938,8 @@ const ( // FlagTabularNumbers // Use fixed-width numbers globally in the UI FlagTabularNumbers = "tabularNumbers" + + // FlagNewInfluxDSConfigPageDesign + // Enables new design for the InfluxDB data source configuration page + FlagNewInfluxDSConfigPageDesign = "newInfluxDSConfigPageDesign" ) diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index 0f1a71b7130..2178f0ff123 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -3,40 +3,10 @@ "apiVersion": "featuretoggle.grafana.app/v0alpha1", "metadata": {}, "items": [ - { - "metadata": { - "name": "ABTestFeatureToggleA", - "resourceVersion": "1745491786560", - "creationTimestamp": "2025-01-13T21:13:13Z", - "deletionTimestamp": "2025-05-27T18:50:27Z" - }, - "spec": { - "description": "Test feature toggle to see how cohorts could be set up AB testing", - "stage": "experimental", - "codeowner": "@grafana/sharing-squad", - "hideFromDocs": true, - "expression": "false" - } - }, - { - "metadata": { - "name": "ABTestFeatureToggleB", - "resourceVersion": "1745491786560", - "creationTimestamp": "2025-01-13T21:13:13Z", - "deletionTimestamp": "2025-05-27T18:50:27Z" - }, - "spec": { - "description": "Test feature toggle to see how cohorts could be set up AB testing", - "stage": "experimental", - "codeowner": "@grafana/sharing-squad", - "hideFromDocs": true, - "expression": "false" - } - }, { "metadata": { "name": "addFieldFromCalculationStatFunctions", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-03T14:39:58Z" }, "spec": { @@ -50,7 +20,7 @@ { "metadata": { "name": "aiGeneratedDashboardChanges", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-03-05T12:01:31Z" }, "spec": { @@ -63,8 +33,8 @@ { "metadata": { "name": "alertEnrichment", - "resourceVersion": "1749210731545", - "creationTimestamp": "2025-06-06T11:52:11Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enable configuration of alert enrichments in Grafana Cloud.", @@ -78,7 +48,7 @@ { "metadata": { "name": "alertRuleRestore", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-05T14:15:26Z" }, "spec": { @@ -91,8 +61,8 @@ { "metadata": { "name": "alertRuleUseFiredAtForStartsAt", - "resourceVersion": "1745491786560", - "creationTimestamp": "2025-04-24T10:49:46Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Use FiredAt for StartsAt when sending alerts to Alertmaanger", @@ -104,7 +74,7 @@ { "metadata": { "name": "alertingBacktesting", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-12-14T14:44:14Z" }, "spec": { @@ -116,11 +86,8 @@ { "metadata": { "name": "alertingBulkActionsInUI", - "resourceVersion": "1745504721038", - "creationTimestamp": "2025-04-24T14:01:56Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-04-24 14:25:21.03825 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables the alerting bulk actions in the UI", @@ -135,7 +102,7 @@ { "metadata": { "name": "alertingCentralAlertHistory", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-29T15:01:38Z" }, "spec": { @@ -148,7 +115,7 @@ { "metadata": { "name": "alertingDisableSendAlertsExternal", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-23T12:29:19Z" }, "spec": { @@ -162,7 +129,7 @@ { "metadata": { "name": "alertingFilterV2", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-11T11:29:26Z" }, "spec": { @@ -175,8 +142,8 @@ { "metadata": { "name": "alertingImportAlertmanagerAPI", - "resourceVersion": "1749365901136", - "creationTimestamp": "2025-06-08T06:58:21Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables the API to import Alertmanager configuration", @@ -190,8 +157,8 @@ { "metadata": { "name": "alertingImportYAMLUI", - "resourceVersion": "1747836716080", - "creationTimestamp": "2025-05-21T14:11:56Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables a UI feature for importing rules from a Prometheus file to Grafana-managed rules", @@ -201,26 +168,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "alertingInsights", - "resourceVersion": "1745491786560", - "creationTimestamp": "2023-09-14T12:58:04Z", - "deletionTimestamp": "2025-05-05T08:01:40Z" - }, - "spec": { - "description": "Show the new alerting insights landing page", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "frontend": true, - "hideFromAdminPage": true, - "expression": "true" - } - }, { "metadata": { "name": "alertingJiraIntegration", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-14T12:22:04Z" }, "spec": { @@ -234,7 +185,7 @@ { "metadata": { "name": "alertingListViewV2", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-24T14:40:49Z" }, "spec": { @@ -247,8 +198,8 @@ { "metadata": { "name": "alertingListViewV2PreviewToggle", - "resourceVersion": "1745491786560", - "creationTimestamp": "2025-04-24T10:49:46Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables the alerting list view v2 preview toggle", @@ -260,11 +211,8 @@ { "metadata": { "name": "alertingMigrationUI", - "resourceVersion": "1747241866044", - "creationTimestamp": "2025-03-14T16:40:05Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-14 16:57:46.044198 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-03-14T16:40:05Z" }, "spec": { "description": "Enables the alerting migration UI, to migrate data source-managed rules to Grafana-managed rules", @@ -277,7 +225,7 @@ { "metadata": { "name": "alertingNotificationsStepMode", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-22T11:07:45Z" }, "spec": { @@ -291,7 +239,7 @@ { "metadata": { "name": "alertingPrometheusRulesPrimary", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-27T12:27:16Z" }, "spec": { @@ -304,7 +252,7 @@ { "metadata": { "name": "alertingQueryAndExpressionsStepMode", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-26T06:33:14Z" }, "spec": { @@ -318,7 +266,7 @@ { "metadata": { "name": "alertingQueryOptimization", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-10T20:52:58Z" }, "spec": { @@ -331,7 +279,7 @@ { "metadata": { "name": "alertingRulePermanentlyDelete", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-03T11:18:25Z" }, "spec": { @@ -347,7 +295,7 @@ { "metadata": { "name": "alertingRuleRecoverDeleted", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-27T14:39:26Z" }, "spec": { @@ -363,7 +311,7 @@ { "metadata": { "name": "alertingRuleVersionHistoryRestore", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-17T12:25:32Z" }, "spec": { @@ -379,7 +327,7 @@ { "metadata": { "name": "alertingSaveStateCompressed", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-27T17:47:33Z" }, "spec": { @@ -392,7 +340,7 @@ { "metadata": { "name": "alertingSaveStatePeriodic", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-23T16:03:30Z" }, "spec": { @@ -401,24 +349,10 @@ "codeowner": "@grafana/alerting-squad" } }, - { - "metadata": { - "name": "alertingSimplifiedRouting", - "resourceVersion": "1745491786560", - "creationTimestamp": "2023-11-10T13:14:39Z", - "deletionTimestamp": "2025-05-06T07:23:50Z" - }, - "spec": { - "description": "Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "expression": "true" - } - }, { "metadata": { "name": "alertingUIOptimizeReducer", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-18T10:59:00Z" }, "spec": { @@ -429,23 +363,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "alertmanagerRemoteOnly", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-10-30T16:27:08Z", - "deletionTimestamp": "2025-05-09T12:58:01Z" - }, - "spec": { - "description": "Disable the internal Alertmanager and only use the external one defined.", - "stage": "experimental", - "codeowner": "@grafana/alerting-squad" - } - }, { "metadata": { "name": "alertmanagerRemotePrimary", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-30T16:27:08Z" }, "spec": { @@ -457,7 +378,7 @@ { "metadata": { "name": "alertmanagerRemoteSecondary", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-30T16:27:08Z" }, "spec": { @@ -469,7 +390,7 @@ { "metadata": { "name": "angularDeprecationUI", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-08-29T14:05:47Z" }, "spec": { @@ -483,7 +404,7 @@ { "metadata": { "name": "annotationPermissionUpdate", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-31T13:30:13Z" }, "spec": { @@ -496,7 +417,7 @@ { "metadata": { "name": "appPlatformGrpcClientAuth", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-14T10:47:18Z" }, "spec": { @@ -507,23 +428,10 @@ "hideFromDocs": true } }, - { - "metadata": { - "name": "appSidecar", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-09-09T12:45:05Z", - "deletionTimestamp": "2025-04-10T20:04:12Z" - }, - "spec": { - "description": "Enable the app sidecar feature that allows rendering 2 apps at the same time", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform" - } - }, { "metadata": { "name": "assetSriChecks", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-04T10:56:35Z" }, "spec": { @@ -536,7 +444,7 @@ { "metadata": { "name": "authZGRPCServer", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-13T09:41:35Z" }, "spec": { @@ -550,7 +458,7 @@ { "metadata": { "name": "awsAsyncQueryCaching", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-21T15:34:07Z" }, "spec": { @@ -563,7 +471,7 @@ { "metadata": { "name": "awsDatasourcesTempCredentials", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-06T15:06:11Z" }, "spec": { @@ -575,7 +483,7 @@ { "metadata": { "name": "azureMonitorDisableLogLimit", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-24T13:32:09Z" }, "spec": { @@ -588,7 +496,7 @@ { "metadata": { "name": "azureMonitorEnableUserAuth", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-27T14:01:54Z" }, "spec": { @@ -601,7 +509,7 @@ { "metadata": { "name": "azureMonitorLogsBuilderEditor", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-02T14:15:25Z" }, "spec": { @@ -614,7 +522,7 @@ { "metadata": { "name": "azureMonitorPrometheusExemplars", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-06T16:53:17Z" }, "spec": { @@ -627,7 +535,7 @@ { "metadata": { "name": "cachingOptimizeSerializationMemoryUsage", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-12T16:56:49Z" }, "spec": { @@ -639,7 +547,7 @@ { "metadata": { "name": "canvasPanelNesting", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-05-31T19:03:34Z" }, "spec": { @@ -653,7 +561,7 @@ { "metadata": { "name": "canvasPanelPanZoom", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-02T19:52:21Z" }, "spec": { @@ -666,7 +574,7 @@ { "metadata": { "name": "cloudRBACRoles", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-10T13:19:01Z" }, "spec": { @@ -682,7 +590,7 @@ { "metadata": { "name": "cloudWatchBatchQueries", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-20T19:09:41Z" }, "spec": { @@ -694,7 +602,7 @@ { "metadata": { "name": "cloudWatchCrossAccountQuerying", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-11-28T11:39:12Z" }, "spec": { @@ -708,7 +616,7 @@ { "metadata": { "name": "cloudWatchNewLabelParsing", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-05T15:57:56Z" }, "spec": { @@ -721,7 +629,7 @@ { "metadata": { "name": "cloudWatchRoundUpEndTime", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-27T15:10:28Z" }, "spec": { @@ -734,7 +642,7 @@ { "metadata": { "name": "configurableSchedulerTick", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-26T16:44:12Z" }, "spec": { @@ -748,7 +656,7 @@ { "metadata": { "name": "correlations", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-09-16T13:14:27Z" }, "spec": { @@ -762,7 +670,7 @@ { "metadata": { "name": "crashDetection", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-12T15:07:27Z" }, "spec": { @@ -775,7 +683,7 @@ { "metadata": { "name": "dashboardDisableSchemaValidationV1", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -787,7 +695,7 @@ { "metadata": { "name": "dashboardDisableSchemaValidationV2", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -799,7 +707,7 @@ { "metadata": { "name": "dashboardNewLayouts", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-23T08:55:45Z" }, "spec": { @@ -809,25 +717,10 @@ "frontend": true } }, - { - "metadata": { - "name": "dashboardRestore", - "resourceVersion": "1747744953711", - "creationTimestamp": "2024-05-16T17:36:26Z", - "deletionTimestamp": "2025-04-03T07:52:54Z" - }, - "spec": { - "description": "Enables deleted dashboard restore feature", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform", - "hideFromAdminPage": true, - "expression": "false" - } - }, { "metadata": { "name": "dashboardScene", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-13T08:51:21Z" }, "spec": { @@ -841,7 +734,7 @@ { "metadata": { "name": "dashboardSceneForViewers", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-02T19:02:25Z" }, "spec": { @@ -855,7 +748,7 @@ { "metadata": { "name": "dashboardSceneSolo", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-11T08:08:47Z" }, "spec": { @@ -869,7 +762,7 @@ { "metadata": { "name": "dashboardSchemaValidationLogging", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-11T16:52:46Z" }, "spec": { @@ -881,7 +774,7 @@ { "metadata": { "name": "dashgpt", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-08-30T20:22:05Z" }, "spec": { @@ -895,7 +788,7 @@ { "metadata": { "name": "dataplaneAggregator", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-09T08:41:07Z" }, "spec": { @@ -908,7 +801,7 @@ { "metadata": { "name": "dataplaneFrontendFallback", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-04-07T21:13:19Z" }, "spec": { @@ -923,7 +816,7 @@ { "metadata": { "name": "datasourceAPIServers", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-19T08:28:27Z" }, "spec": { @@ -936,7 +829,7 @@ { "metadata": { "name": "datasourceConnectionsTab", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-21T17:39:48Z" }, "spec": { @@ -949,7 +842,7 @@ { "metadata": { "name": "datasourceQueryTypes", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-23T16:46:28Z" }, "spec": { @@ -962,7 +855,7 @@ { "metadata": { "name": "disableClassicHTTPHistogram", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-18T19:37:44Z" }, "spec": { @@ -976,11 +869,8 @@ { "metadata": { "name": "disableEnvelopeEncryption", - "resourceVersion": "1746651535573", - "creationTimestamp": "2022-05-24T08:34:47Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-07 20:58:55.573227 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2022-05-24T08:34:47Z" }, "spec": { "description": "Disable envelope encryption (emergency only)", @@ -993,7 +883,7 @@ { "metadata": { "name": "disableNumericMetricsSortingInExpressions", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-16T14:52:47Z" }, "spec": { @@ -1006,7 +896,7 @@ { "metadata": { "name": "disableSSEDataplane", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-04-12T16:24:34Z" }, "spec": { @@ -1015,24 +905,10 @@ "codeowner": "@grafana/observability-metrics" } }, - { - "metadata": { - "name": "disableSecretsCompatibility", - "resourceVersion": "1743693517832", - "creationTimestamp": "2022-07-12T20:27:37Z", - "deletionTimestamp": "2025-05-05T08:21:21Z" - }, - "spec": { - "description": "Disable duplicated secret storage in legacy tables", - "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team", - "requiresRestart": true - } - }, { "metadata": { "name": "editPanelCSVDragAndDrop", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-01-24T09:43:44Z" }, "spec": { @@ -1045,7 +921,7 @@ { "metadata": { "name": "elasticsearchCrossClusterSearch", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-12T22:20:04Z" }, "spec": { @@ -1057,7 +933,7 @@ { "metadata": { "name": "elasticsearchImprovedParsing", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-15T17:05:54Z" }, "spec": { @@ -1069,7 +945,7 @@ { "metadata": { "name": "enableDatagridEditing", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-04-24T14:46:31Z" }, "spec": { @@ -1082,7 +958,7 @@ { "metadata": { "name": "enableExtensionsAdminPage", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-05T15:55:10Z" }, "spec": { @@ -1095,7 +971,7 @@ { "metadata": { "name": "enableNativeHTTPHistogram", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-03T18:23:55Z" }, "spec": { @@ -1109,7 +985,7 @@ { "metadata": { "name": "enableSCIM", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-07T14:38:46Z" }, "spec": { @@ -1121,7 +997,7 @@ { "metadata": { "name": "enableScopesInMetricsExplore", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-06T13:11:33Z" }, "spec": { @@ -1135,7 +1011,7 @@ { "metadata": { "name": "exploreLogsAggregatedMetrics", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1148,7 +1024,7 @@ { "metadata": { "name": "exploreLogsLimitedTimeRange", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1161,7 +1037,7 @@ { "metadata": { "name": "exploreLogsShardSplitting", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-29T13:55:59Z" }, "spec": { @@ -1171,25 +1047,10 @@ "frontend": true } }, - { - "metadata": { - "name": "exploreMetrics", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-04-09T18:15:18Z", - "deletionTimestamp": "2025-04-11T20:45:14Z" - }, - "spec": { - "description": "Enables the new Grafana Metrics Drilldown core app", - "stage": "GA", - "codeowner": "@grafana/observability-metrics", - "frontend": true, - "expression": "true" - } - }, { "metadata": { "name": "exploreMetricsRelatedLogs", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-05T16:28:43Z" }, "spec": { @@ -1199,24 +1060,10 @@ "frontend": true } }, - { - "metadata": { - "name": "exploreMetricsUseExternalAppPlugin", - "resourceVersion": "1743693517832", - "creationTimestamp": "2025-02-03T20:46:54Z", - "deletionTimestamp": "2025-04-11T20:45:14Z" - }, - "spec": { - "description": "Use the externalized Grafana Metrics Drilldown (formerly known as Explore Metrics) app plugin", - "stage": "preview", - "codeowner": "@grafana/observability-metrics", - "requiresRestart": true - } - }, { "metadata": { "name": "expressionParser", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-17T00:59:11Z" }, "spec": { @@ -1229,7 +1076,7 @@ { "metadata": { "name": "extensionSidebar", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-03T10:16:35Z" }, "spec": { @@ -1242,8 +1089,8 @@ { "metadata": { "name": "extensionsReadOnlyProxy", - "resourceVersion": "1744122618262", - "creationTimestamp": "2025-04-08T14:30:18Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Use proxy-based read-only objects for plugin extensions instead of deep cloning", @@ -1257,7 +1104,7 @@ { "metadata": { "name": "externalCorePlugins", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-09-22T08:50:13Z" }, "spec": { @@ -1270,7 +1117,7 @@ { "metadata": { "name": "externalServiceAccounts", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-09-28T07:26:37Z" }, "spec": { @@ -1283,9 +1130,8 @@ { "metadata": { "name": "extraThemes", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-05-10T13:37:04Z", - "deletionTimestamp": "2025-05-19T15:29:06Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2023-05-10T13:37:04Z" }, "spec": { "description": "Enables extra themes", @@ -1297,7 +1143,7 @@ { "metadata": { "name": "extractFieldsNameDeduplication", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-02T15:47:42Z" }, "spec": { @@ -1310,7 +1156,7 @@ { "metadata": { "name": "failWrongDSUID", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-20T10:56:39Z" }, "spec": { @@ -1323,7 +1169,7 @@ { "metadata": { "name": "faroDatasourceSelector", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-05-05T00:35:10Z" }, "spec": { @@ -1336,11 +1182,8 @@ { "metadata": { "name": "featureHighlights", - "resourceVersion": "1746651535573", - "creationTimestamp": "2022-02-03T11:53:23Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-07 20:58:55.573227 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2022-02-03T11:53:23Z" }, "spec": { "description": "Highlight Grafana Enterprise features", @@ -1353,7 +1196,7 @@ { "metadata": { "name": "featureToggleAdminPage", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-18T20:43:32Z" }, "spec": { @@ -1367,7 +1210,7 @@ { "metadata": { "name": "feedbackButton", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-02T17:08:15Z" }, "spec": { @@ -1380,7 +1223,7 @@ { "metadata": { "name": "fetchRulesUsingPost", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-29T12:17:44Z" }, "spec": { @@ -1394,7 +1237,7 @@ { "metadata": { "name": "formatString", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-13T18:17:12Z" }, "spec": { @@ -1405,24 +1248,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "frontendSandboxMonitorOnly", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-07-05T11:48:25Z", - "deletionTimestamp": "2025-05-05T08:21:21Z" - }, - "spec": { - "description": "Enables monitor only in the plugin frontend sandbox (if enabled)", - "stage": "privatePreview", - "codeowner": "@grafana/plugins-platform-backend", - "frontend": true - } - }, { "metadata": { "name": "grafanaAPIServerEnsureKubectlAccess", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-12-06T20:21:21Z" }, "spec": { @@ -1436,7 +1265,7 @@ { "metadata": { "name": "grafanaAPIServerWithExperimentalAPIs", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-06T18:55:22Z" }, "spec": { @@ -1450,11 +1279,8 @@ { "metadata": { "name": "grafanaAdvisor", - "resourceVersion": "1750155856840", - "creationTimestamp": "2025-01-20T10:08:00Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-06-17 10:24:16.840675 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-01-20T10:08:00Z" }, "spec": { "description": "Enables Advisor app", @@ -1465,9 +1291,8 @@ { "metadata": { "name": "grafanaManagedRecordingRules", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-04-22T17:53:16Z", - "deletionTimestamp": "2025-05-16T18:56:20Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2024-04-22T17:53:16Z" }, "spec": { "description": "Enables Grafana-managed recording rules.", @@ -1477,27 +1302,10 @@ "hideFromDocs": true } }, - { - "metadata": { - "name": "grafanaManagedRecordingRulesDatasources", - "resourceVersion": "1746998568254", - "creationTimestamp": "2025-03-07T13:30:40Z", - "deletionTimestamp": "2025-05-19T10:18:04Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-11 21:22:48.254378 +0000 UTC" - } - }, - "spec": { - "description": "Enables writing to data sources for Grafana-managed recording rules.", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "expression": "false" - } - }, { "metadata": { "name": "grafanaconThemes", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-06T11:08:04Z" }, "spec": { @@ -1513,7 +1321,7 @@ { "metadata": { "name": "groupAttributeSync", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-09T15:29:43Z" }, "spec": { @@ -1526,7 +1334,7 @@ { "metadata": { "name": "groupByVariable", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-14T17:18:04Z" }, "spec": { @@ -1540,7 +1348,7 @@ { "metadata": { "name": "groupToNestedTableTransformation", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-07T14:28:26Z" }, "spec": { @@ -1554,7 +1362,7 @@ { "metadata": { "name": "grpcServer", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-09-26T20:25:34Z" }, "spec": { @@ -1564,24 +1372,10 @@ "hideFromAdminPage": true } }, - { - "metadata": { - "name": "homeSetupGuide", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-09-25T17:20:04Z", - "deletionTimestamp": "2025-05-20T16:08:36Z" - }, - "spec": { - "description": "Used in Home for users who want to return to the onboarding flow or quickly find popular config pages", - "stage": "experimental", - "codeowner": "@grafana/growth-and-onboarding", - "frontend": true - } - }, { "metadata": { "name": "improvedExternalSessionHandling", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-17T10:54:39Z" }, "spec": { @@ -1594,7 +1388,7 @@ { "metadata": { "name": "improvedExternalSessionHandlingSAML", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-09T17:02:49Z" }, "spec": { @@ -1607,11 +1401,8 @@ { "metadata": { "name": "individualCookiePreferences", - "resourceVersion": "1746800362427", - "creationTimestamp": "2023-02-21T10:19:07Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-09 14:19:22.427054 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2023-02-21T10:19:07Z" }, "spec": { "description": "Support overriding cookie preferences per user", @@ -1622,7 +1413,7 @@ { "metadata": { "name": "infinityRunQueriesInParallel", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-14T12:54:04Z" }, "spec": { @@ -1634,7 +1425,7 @@ { "metadata": { "name": "influxdbBackendMigration", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-02-09T18:26:16Z", "deletionTimestamp": "2023-01-17T14:11:26Z" }, @@ -1649,7 +1440,7 @@ { "metadata": { "name": "influxdbRunQueriesInParallel", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-01T10:58:24Z" }, "spec": { @@ -1661,7 +1452,7 @@ { "metadata": { "name": "influxqlStreamingParser", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-29T17:29:35Z" }, "spec": { @@ -1673,7 +1464,7 @@ { "metadata": { "name": "investigationsBackend", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-18T08:31:03Z" }, "spec": { @@ -1686,7 +1477,7 @@ { "metadata": { "name": "inviteUserExperimental", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-07T19:09:59Z" }, "spec": { @@ -1701,7 +1492,7 @@ { "metadata": { "name": "jaegerBackendMigration", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-15T14:40:20Z" }, "spec": { @@ -1713,7 +1504,7 @@ { "metadata": { "name": "jitterAlertRulesWithinGroups", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-18T18:48:11Z" }, "spec": { @@ -1727,7 +1518,7 @@ { "metadata": { "name": "k8SFolderCounts", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-27T17:10:44Z" }, "spec": { @@ -1740,7 +1531,7 @@ { "metadata": { "name": "k8SFolderMove", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-27T17:10:44Z" }, "spec": { @@ -1753,7 +1544,7 @@ { "metadata": { "name": "kubernetesAggregator", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-12T20:59:35Z" }, "spec": { @@ -1766,11 +1557,8 @@ { "metadata": { "name": "kubernetesAggregatorCapTokenAuth", - "resourceVersion": "1746996924159", - "creationTimestamp": "2025-05-11T20:48:13Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-11 20:55:24.159856 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enable CAP token based authentication in grafana's embedded kube-aggregator", @@ -1782,8 +1570,8 @@ { "metadata": { "name": "kubernetesAuthzApis", - "resourceVersion": "1747897123910", - "creationTimestamp": "2025-05-22T06:58:43Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Registers AuthZ /apis endpoint", @@ -1796,7 +1584,7 @@ { "metadata": { "name": "kubernetesClientDashboardsFolders", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-18T23:11:26Z" }, "spec": { @@ -1809,7 +1597,7 @@ { "metadata": { "name": "kubernetesDashboards", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-05T14:34:23Z" }, "spec": { @@ -1822,7 +1610,7 @@ { "metadata": { "name": "kubernetesFeatureToggles", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-18T05:32:44Z" }, "spec": { @@ -1833,25 +1621,10 @@ "hideFromAdminPage": true } }, - { - "metadata": { - "name": "kubernetesPlaylists", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-10-05T19:00:36Z", - "deletionTimestamp": "2024-08-13T08:03:28Z" - }, - "spec": { - "description": "Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s", - "stage": "GA", - "codeowner": "@grafana/grafana-app-platform-squad", - "requiresRestart": true, - "expression": "true" - } - }, { "metadata": { "name": "kubernetesSnapshots", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-12-05T22:31:49Z" }, "spec": { @@ -1864,11 +1637,8 @@ { "metadata": { "name": "libraryPanelRBAC", - "resourceVersion": "1750162291839", - "creationTimestamp": "2023-10-11T23:30:50Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-06-17 12:11:31.83962 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2023-10-11T23:30:50Z" }, "spec": { "description": "Enables RBAC support for library panels", @@ -1881,7 +1651,7 @@ { "metadata": { "name": "localeFormatPreference", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-31T13:59:07Z" }, "spec": { @@ -1893,7 +1663,7 @@ { "metadata": { "name": "localizationForPlugins", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-31T04:38:38Z" }, "spec": { @@ -1905,7 +1675,7 @@ { "metadata": { "name": "logQLScope", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-11T11:53:24Z" }, "spec": { @@ -1920,11 +1690,8 @@ { "metadata": { "name": "logRequestsInstrumentedAsUnknown", - "resourceVersion": "1746651640866", - "creationTimestamp": "2022-06-10T08:56:55Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-07 21:00:40.866696 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2022-06-10T08:56:55Z" }, "spec": { "description": "Logs the path for requests that are instrumented as unknown", @@ -1935,7 +1702,7 @@ { "metadata": { "name": "logRowsPopoverMenu", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-16T09:48:10Z" }, "spec": { @@ -1949,7 +1716,7 @@ { "metadata": { "name": "logsContextDatasourceUi", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-01-27T14:12:01Z" }, "spec": { @@ -1964,7 +1731,7 @@ { "metadata": { "name": "logsExploreTableDefaultVisualization", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-02T15:28:15Z" }, "spec": { @@ -1977,7 +1744,7 @@ { "metadata": { "name": "logsExploreTableVisualisation", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-12T13:52:42Z" }, "spec": { @@ -1991,7 +1758,7 @@ { "metadata": { "name": "logsInfiniteScrolling", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-09T10:54:03Z" }, "spec": { @@ -2005,11 +1772,8 @@ { "metadata": { "name": "logsPanelControls", - "resourceVersion": "1743772342343", - "creationTimestamp": "2025-04-07T14:38:55Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-04-04 13:12:22.343052 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-04-07T14:38:55Z" }, "spec": { "description": "Enables a control component for the logs panel in Explore", @@ -2022,7 +1786,7 @@ { "metadata": { "name": "lokiExperimentalStreaming", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-19T10:03:51Z" }, "spec": { @@ -2034,7 +1798,7 @@ { "metadata": { "name": "lokiLabelNamesQueryApi", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-13T14:31:41Z" }, "spec": { @@ -2047,7 +1811,7 @@ { "metadata": { "name": "lokiLogsDataplane", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-13T07:58:00Z" }, "spec": { @@ -2059,7 +1823,7 @@ { "metadata": { "name": "lokiPredefinedOperations", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-02T10:52:36Z" }, "spec": { @@ -2072,7 +1836,7 @@ { "metadata": { "name": "lokiQueryHints", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-12-18T20:43:16Z" }, "spec": { @@ -2086,7 +1850,7 @@ { "metadata": { "name": "lokiQuerySplitting", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-02-09T17:27:02Z" }, "spec": { @@ -2101,7 +1865,7 @@ { "metadata": { "name": "lokiQuerySplittingConfig", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-03-20T15:51:36Z" }, "spec": { @@ -2114,7 +1878,7 @@ { "metadata": { "name": "lokiRunQueriesInParallel", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-09-19T09:34:01Z" }, "spec": { @@ -2123,23 +1887,10 @@ "codeowner": "@grafana/observability-logs" } }, - { - "metadata": { - "name": "lokiSendDashboardPanelNames", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-08-22T19:30:43Z", - "deletionTimestamp": "2025-06-19T13:40:02Z" - }, - "spec": { - "description": "Send dashboard and panel names to Loki when querying", - "stage": "experimental", - "codeowner": "@grafana/observability-logs" - } - }, { "metadata": { "name": "lokiShardSplitting", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-23T11:21:03Z" }, "spec": { @@ -2152,7 +1903,7 @@ { "metadata": { "name": "lokiStructuredMetadata", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-16T16:06:14Z" }, "spec": { @@ -2165,7 +1916,7 @@ { "metadata": { "name": "managedDualWriter", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-19T14:50:39Z" }, "spec": { @@ -2179,7 +1930,7 @@ { "metadata": { "name": "metricsFromProfiles", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-09T10:55:28Z" }, "spec": { @@ -2192,7 +1943,7 @@ { "metadata": { "name": "mlExpressions", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-13T17:37:50Z" }, "spec": { @@ -2204,8 +1955,8 @@ { "metadata": { "name": "multiTenantFrontend", - "resourceVersion": "1745438197175", - "creationTimestamp": "2025-04-23T19:56:37Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Register MT frontend", @@ -2216,7 +1967,7 @@ { "metadata": { "name": "multiTenantTempCredentials", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-02T20:25:50Z" }, "spec": { @@ -2226,23 +1977,10 @@ "hideFromDocs": true } }, - { - "metadata": { - "name": "multitenantFrontend", - "resourceVersion": "1745438122785", - "creationTimestamp": "2025-04-23T19:55:22Z", - "deletionTimestamp": "2025-04-23T19:56:37Z" - }, - "spec": { - "description": "Register MT frontend", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform" - } - }, { "metadata": { "name": "mysqlAnsiQuotes", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-10-12T11:43:35Z" }, "spec": { @@ -2254,8 +1992,8 @@ { "metadata": { "name": "nanoGit", - "resourceVersion": "1750087021356", - "creationTimestamp": "2025-06-16T15:17:01Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Use experimental git library for provisioning", @@ -2267,7 +2005,7 @@ { "metadata": { "name": "nestedFolders", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-10-26T14:15:14Z" }, "spec": { @@ -2280,7 +2018,7 @@ { "metadata": { "name": "newDashboardSharingComponent", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-03T15:02:18Z" }, "spec": { @@ -2294,7 +2032,7 @@ { "metadata": { "name": "newDashboardWithFiltersAndGroupBy", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-04T11:25:21Z" }, "spec": { @@ -2308,7 +2046,7 @@ { "metadata": { "name": "newFiltersUI", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-30T12:48:13Z" }, "spec": { @@ -2320,22 +2058,24 @@ }, { "metadata": { - "name": "newFolderPicker", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-01-15T11:43:19Z", - "deletionTimestamp": "2025-05-14T09:11:28Z" + "name": "newInfluxDSConfigPageDesign", + "resourceVersion": "1750787021637", + "creationTimestamp": "2025-06-20T15:44:57Z", + "annotations": { + "grafana.app/updatedTimestamp": "2025-06-24 17:43:41.637607 +0000 UTC" + } }, "spec": { - "description": "Enables the nested folder picker without having nested folders enabled", - "stage": "experimental", - "codeowner": "@grafana/grafana-frontend-platform", - "frontend": true + "description": "Enables new design for the InfluxDB data source configuration page", + "stage": "privatePreview", + "codeowner": "@grafana/partner-datasources", + "expression": "false" } }, { "metadata": { "name": "newLogsPanel", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-04T17:40:17Z" }, "spec": { @@ -2378,42 +2118,10 @@ "hideFromDocs": true } }, - { - "metadata": { - "name": "noBackdropBlur", - "resourceVersion": "1744057771109", - "creationTimestamp": "2025-03-14T15:21:35Z", - "deletionTimestamp": "2025-04-08T10:58:19Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-04-07 20:29:31.109804663 +0000 UTC" - } - }, - "spec": { - "description": "Disables backdrop blur behind modals and drawers", - "stage": "GA", - "codeowner": "@grafana/grafana-frontend-platform", - "frontend": true, - "expression": "true" - } - }, - { - "metadata": { - "name": "nodeGraphDotLayout", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-01-31T16:26:12Z", - "deletionTimestamp": "2025-04-08T14:37:17Z" - }, - "spec": { - "description": "Changed the layout algorithm for the node graph", - "stage": "experimental", - "codeowner": "@grafana/observability-traces-and-profiling", - "frontend": true - } - }, { "metadata": { "name": "oauthRequireSubClaim", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-03-25T13:22:24Z" }, "spec": { @@ -2427,7 +2135,7 @@ { "metadata": { "name": "onPremToCloudMigrations", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-22T16:09:08Z" }, "spec": { @@ -2440,7 +2148,7 @@ { "metadata": { "name": "panelFilterVariable", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-03T12:15:54Z" }, "spec": { @@ -2454,7 +2162,7 @@ { "metadata": { "name": "panelMonitoring", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-10-09T05:19:08Z" }, "spec": { @@ -2468,7 +2176,7 @@ { "metadata": { "name": "panelTitleSearch", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-02-15T18:26:03Z" }, "spec": { @@ -2481,7 +2189,7 @@ { "metadata": { "name": "passwordlessMagicLinkAuthentication", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-14T13:50:55Z" }, "spec": { @@ -2510,11 +2218,8 @@ { "metadata": { "name": "permissionsFilterRemoveSubquery", - "resourceVersion": "1746651535573", - "creationTimestamp": "2023-08-02T07:39:25Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-07 20:58:55.573227 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2023-08-02T07:39:25Z" }, "spec": { "description": "Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder", @@ -2525,7 +2230,7 @@ { "metadata": { "name": "pinNavItems", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-10T11:40:03Z" }, "spec": { @@ -2538,7 +2243,7 @@ { "metadata": { "name": "playlistsReconciler", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-20T03:09:31Z" }, "spec": { @@ -2551,7 +2256,7 @@ { "metadata": { "name": "pluginProxyPreserveTrailingSlash", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-05T11:36:14Z" }, "spec": { @@ -2561,24 +2266,11 @@ "expression": "false" } }, - { - "metadata": { - "name": "pluginsAPIMetrics", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-09-21T11:36:32Z", - "deletionTimestamp": "2025-05-05T08:21:21Z" - }, - "spec": { - "description": "Enables auto-updating of users installed plugins", - "stage": "experimental", - "codeowner": "@grafana/plugins-platform-backend" - } - }, { "metadata": { "name": "pluginsAutoUpdate", - "resourceVersion": "1746433281774", - "creationTimestamp": "2025-05-05T08:21:21Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables auto-updating of users installed plugins", @@ -2589,7 +2281,7 @@ { "metadata": { "name": "pluginsCDNSyncLoader", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-02-07T10:07:08Z" }, "spec": { @@ -2601,7 +2293,7 @@ { "metadata": { "name": "pluginsDetailsRightPanel", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-08-13T09:55:30Z" }, "spec": { @@ -2615,7 +2307,7 @@ { "metadata": { "name": "pluginsFrontendSandbox", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-05T08:51:36Z" }, "spec": { @@ -2627,7 +2319,7 @@ { "metadata": { "name": "pluginsSkipHostEnvVars", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-15T17:09:14Z" }, "spec": { @@ -2639,7 +2331,7 @@ { "metadata": { "name": "pluginsSriChecks", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-04T12:55:09Z" }, "spec": { @@ -2652,11 +2344,8 @@ { "metadata": { "name": "preferLibraryPanelTitle", - "resourceVersion": "1750152018442", - "creationTimestamp": "2025-06-17T08:53:23Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-06-17 09:20:18.442539 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Prefer library panel title over viz panel title.", @@ -2668,7 +2357,7 @@ { "metadata": { "name": "preinstallAutoUpdate", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-07T12:14:25Z" }, "spec": { @@ -2681,7 +2370,7 @@ { "metadata": { "name": "preserveDashboardStateWhenNavigating", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-27T12:28:06Z" }, "spec": { @@ -2695,7 +2384,7 @@ { "metadata": { "name": "promQLScope", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-01-29T20:22:17Z" }, "spec": { @@ -2710,7 +2399,7 @@ { "metadata": { "name": "prometheusAzureOverrideAudience", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-05-30T15:43:32Z", "deletionTimestamp": "2023-07-16T21:30:14Z" }, @@ -2724,7 +2413,7 @@ { "metadata": { "name": "prometheusCodeModeMetricNamesSearch", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-04T20:38:23Z" }, "spec": { @@ -2734,24 +2423,10 @@ "frontend": true } }, - { - "metadata": { - "name": "prometheusRunQueriesInParallel", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-08-12T12:31:39Z", - "deletionTimestamp": "2025-04-11T22:11:19Z" - }, - "spec": { - "description": "Enables running Prometheus queries in parallel", - "stage": "GA", - "codeowner": "@grafana/oss-big-tent", - "expression": "true" - } - }, { "metadata": { "name": "prometheusSpecialCharsInLabelValues", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-18T21:31:08Z" }, "spec": { @@ -2761,24 +2436,10 @@ "frontend": true } }, - { - "metadata": { - "name": "prometheusUsesCombobox", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-10-23T11:18:33Z", - "deletionTimestamp": "2025-05-05T08:21:21Z" - }, - "spec": { - "description": "Use new **Combobox** component for Prometheus query editor", - "stage": "GA", - "codeowner": "@grafana/oss-big-tent", - "expression": "true" - } - }, { "metadata": { "name": "provisioning", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-22T09:03:50Z" }, "spec": { @@ -2825,7 +2486,7 @@ { "metadata": { "name": "queryLibrary", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-10-07T18:31:45Z", "deletionTimestamp": "2023-03-20T16:00:14Z" }, @@ -2838,7 +2499,7 @@ { "metadata": { "name": "queryService", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2851,7 +2512,7 @@ { "metadata": { "name": "queryServiceFromExplore", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-02T10:00:33Z" }, "spec": { @@ -2864,7 +2525,7 @@ { "metadata": { "name": "queryServiceFromUI", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2877,7 +2538,7 @@ { "metadata": { "name": "queryServiceRewrite", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-04-19T09:26:21Z" }, "spec": { @@ -2890,7 +2551,7 @@ { "metadata": { "name": "recordedQueriesMulti", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-14T12:34:22Z" }, "spec": { @@ -2900,25 +2561,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "recoveryThreshold", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-10-10T14:51:50Z", - "deletionTimestamp": "2025-05-05T08:21:21Z" - }, - "spec": { - "description": "Enables feature recovery threshold (aka hysteresis) for threshold server-side expression", - "stage": "GA", - "codeowner": "@grafana/alerting-squad", - "requiresRestart": true, - "expression": "true" - } - }, { "metadata": { "name": "refactorVariablesTimeRange", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-06T13:12:09Z" }, "spec": { @@ -2931,7 +2577,7 @@ { "metadata": { "name": "regressionTransformation", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-24T14:49:16Z" }, "spec": { @@ -2944,7 +2590,7 @@ { "metadata": { "name": "reloadDashboardsOnParamsChange", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-25T12:56:54Z" }, "spec": { @@ -3005,25 +2651,11 @@ "requiresRestart": true } }, - { - "metadata": { - "name": "reportingUseRawTimeRange", - "resourceVersion": "1743693517832", - "creationTimestamp": "2024-11-14T20:08:03Z", - "deletionTimestamp": "2025-05-28T13:44:54Z" - }, - "spec": { - "description": "Uses the original report or dashboard time range instead of making an absolute transformation", - "stage": "GA", - "codeowner": "@grafana/sharing-squad", - "expression": "true" - } - }, { "metadata": { "name": "restoreDashboards", - "resourceVersion": "1748002635285", - "creationTimestamp": "2025-05-23T12:17:15Z" + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables restore deleted dashboards feature", @@ -3036,7 +2668,7 @@ { "metadata": { "name": "rolePickerDrawer", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-26T12:51:38Z" }, "spec": { @@ -3048,7 +2680,7 @@ { "metadata": { "name": "scopeApi", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-11-27T07:58:25Z" }, "spec": { @@ -3062,7 +2694,7 @@ { "metadata": { "name": "scopeFilters", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-03-05T15:41:19Z" }, "spec": { @@ -3076,7 +2708,7 @@ { "metadata": { "name": "scopeSearchAllLevels", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-14T07:42:16Z" }, "spec": { @@ -3090,7 +2722,7 @@ { "metadata": { "name": "secretsManagementAppPlatform", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-19T09:25:14Z" }, "spec": { @@ -3102,7 +2734,7 @@ { "metadata": { "name": "showDashboardValidationWarnings", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-10-14T13:51:05Z" }, "spec": { @@ -3114,11 +2746,8 @@ { "metadata": { "name": "skipTokenRotationIfRecent", - "resourceVersion": "1748363818965", - "creationTimestamp": "2025-05-27T16:30:53Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-27 16:36:58.965629 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Skip token rotation if it was already rotated less than 5 seconds ago", @@ -3132,7 +2761,7 @@ { "metadata": { "name": "sqlDatasourceDatabaseSelection", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-06-06T16:28:52Z" }, "spec": { @@ -3146,7 +2775,7 @@ { "metadata": { "name": "sqlExpressions", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-02-27T21:16:00Z" }, "spec": { @@ -3158,7 +2787,7 @@ { "metadata": { "name": "sseGroupByDatasource", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-09-07T20:02:07Z" }, "spec": { @@ -3170,7 +2799,7 @@ { "metadata": { "name": "ssoSettingsApi", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-11-08T09:50:01Z" }, "spec": { @@ -3184,11 +2813,8 @@ { "metadata": { "name": "ssoSettingsLDAP", - "resourceVersion": "1749024523226", - "creationTimestamp": "2024-06-18T11:31:27Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-06-04 08:08:43.226801 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2024-06-18T11:31:27Z" }, "spec": { "description": "Use the new SSO Settings API to configure LDAP", @@ -3202,7 +2828,7 @@ { "metadata": { "name": "ssoSettingsSAML", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-03-14T11:04:45Z" }, "spec": { @@ -3216,7 +2842,7 @@ { "metadata": { "name": "storage", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2022-03-17T17:19:23Z" }, "spec": { @@ -3228,11 +2854,8 @@ { "metadata": { "name": "tableNextGen", - "resourceVersion": "1747058265248", - "creationTimestamp": "2025-03-26T03:57:57Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-12 13:57:45.248176 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-03-26T03:57:57Z" }, "spec": { "description": "Allows access to the new react-data-grid based table component.", @@ -3244,7 +2867,7 @@ { "metadata": { "name": "tableSharedCrosshair", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-12-13T09:33:14Z" }, "spec": { @@ -3273,11 +2896,8 @@ { "metadata": { "name": "teamHttpHeadersMimir", - "resourceVersion": "1749732225616", - "creationTimestamp": "2025-01-13T10:42:47Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-06-12 12:43:45.616224 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-01-13T10:42:47Z" }, "spec": { "description": "Enables LBAC for datasources for Mimir to apply LBAC filtering of metrics to the client requests for users in teams", @@ -3290,11 +2910,8 @@ { "metadata": { "name": "teamHttpHeadersTempo", - "resourceVersion": "1747930192816", - "creationTimestamp": "2025-05-20T14:50:32Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-22 16:09:52.816517 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2025-06-20T15:44:57Z" }, "spec": { "description": "Enables LBAC for datasources for Tempo to apply LBAC filtering of traces to the client requests for users in teams", @@ -3305,7 +2922,7 @@ { "metadata": { "name": "templateVariablesUsesCombobox", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-31T09:53:13Z" }, "spec": { @@ -3318,7 +2935,7 @@ { "metadata": { "name": "timeRangeProvider", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-22T10:52:33Z" }, "spec": { @@ -3330,7 +2947,7 @@ { "metadata": { "name": "tlsMemcached", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-05-09T19:12:08Z" }, "spec": { @@ -3340,25 +2957,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "traceQLStreaming", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-07-26T13:33:16Z", - "deletionTimestamp": "2025-04-09T12:57:07Z" - }, - "spec": { - "description": "Enables response streaming of TraceQL queries of the Tempo data source", - "stage": "GA", - "codeowner": "@grafana/observability-traces-and-profiling", - "frontend": true, - "expression": "false" - } - }, { "metadata": { "name": "transformationsRedesign", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2023-07-12T16:35:49Z" }, "spec": { @@ -3373,7 +2975,7 @@ { "metadata": { "name": "unifiedHistory", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-13T10:41:18Z" }, "spec": { @@ -3386,7 +2988,7 @@ { "metadata": { "name": "unifiedNavbars", - "resourceVersion": "1745491786560", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-04-09T12:51:22Z" }, "spec": { @@ -3400,11 +3002,8 @@ { "metadata": { "name": "unifiedRequestLog", - "resourceVersion": "1746651640866", - "creationTimestamp": "2023-03-31T13:38:09Z", - "annotations": { - "grafana.app/updatedTimestamp": "2025-05-07 21:00:40.866696 +0000 UTC" - } + "resourceVersion": "1750434297879", + "creationTimestamp": "2023-03-31T13:38:09Z" }, "spec": { "description": "Writes error logs to the request logger", @@ -3417,7 +3016,7 @@ { "metadata": { "name": "unifiedStorageBigObjectsSupport", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-10-17T10:18:29Z" }, "spec": { @@ -3429,7 +3028,7 @@ { "metadata": { "name": "unifiedStorageGrpcConnectionPool", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-21T13:24:54Z" }, "spec": { @@ -3443,7 +3042,7 @@ { "metadata": { "name": "unifiedStorageHistoryPruner", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-17T10:36:38Z" }, "spec": { @@ -3458,7 +3057,7 @@ { "metadata": { "name": "unifiedStorageSearch", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-30T19:46:14Z" }, "spec": { @@ -3472,7 +3071,7 @@ { "metadata": { "name": "unifiedStorageSearchPermissionFiltering", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-01-22T11:38:37Z" }, "spec": { @@ -3487,7 +3086,7 @@ { "metadata": { "name": "unifiedStorageSearchSprinkles", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-18T17:00:54Z" }, "spec": { @@ -3501,7 +3100,7 @@ { "metadata": { "name": "unifiedStorageSearchUI", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-12-19T18:21:48Z" }, "spec": { @@ -3515,7 +3114,7 @@ { "metadata": { "name": "useScopesNavigationEndpoint", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2025-03-31T15:20:00Z" }, "spec": { @@ -3530,7 +3129,7 @@ { "metadata": { "name": "useSessionStorageForRedirection", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-09-23T09:31:23Z" }, "spec": { @@ -3540,39 +3139,10 @@ "expression": "true" } }, - { - "metadata": { - "name": "wargamesTesting", - "resourceVersion": "1743693517832", - "creationTimestamp": "2023-09-13T18:32:01Z", - "deletionTimestamp": "2025-05-07T20:58:55Z" - }, - "spec": { - "description": "Placeholder feature flag for internal testing", - "stage": "experimental", - "codeowner": "@grafana/hosted-grafana-team" - } - }, - { - "metadata": { - "name": "xrayApplicationSignals", - "resourceVersion": "1743693517832", - "creationTimestamp": "2025-04-01T14:42:02Z", - "deletionTimestamp": "2025-06-11T11:57:58Z" - }, - "spec": { - "description": "Support Application Signals queries in the X-Ray datasource", - "stage": "experimental", - "codeowner": "@grafana/aws-datasources", - "frontend": true, - "hideFromAdminPage": true, - "hideFromDocs": true - } - }, { "metadata": { "name": "zanzana", - "resourceVersion": "1743693517832", + "resourceVersion": "1750434297879", "creationTimestamp": "2024-06-19T13:59:47Z" }, "spec": { diff --git a/public/app/features/datasources/components/ButtonRow.tsx b/public/app/features/datasources/components/ButtonRow.tsx index 7415a62e2f6..0712ee746ce 100644 --- a/public/app/features/datasources/components/ButtonRow.tsx +++ b/public/app/features/datasources/components/ButtonRow.tsx @@ -31,6 +31,7 @@ export function ButtonRow({ canSave, canDelete, onDelete, onSubmit, onTest }: Pr disabled={!canSave} onClick={onSubmit} data-testid={selectors.pages.DataSource.saveAndTest} + id={selectors.pages.DataSource.saveAndTest} > Save & test diff --git a/public/app/features/datasources/components/EditDataSource.tsx b/public/app/features/datasources/components/EditDataSource.tsx index 5b8f8fc8d36..077e66f931f 100644 --- a/public/app/features/datasources/components/EditDataSource.tsx +++ b/public/app/features/datasources/components/EditDataSource.tsx @@ -123,6 +123,16 @@ export function EditDataSourceView({ let currentJsonData = dataSource.jsonData; let currentSecureJsonData = dataSource.secureJsonData; + const isPDCInjected = components.some((component) => component.meta.pluginId === 'grafana-pdc-app'); + + const dataSourceWithIsPDCInjected = { + ...dataSource, + jsonData: { + ...dataSource.jsonData, + pdcInjected: isPDCInjected, + }, + }; + const dsi = getDataSourceSrv()?.getInstanceSettings(dataSource.uid); const onSubmit = async (e: React.MouseEvent | React.FormEvent) => { @@ -190,7 +200,7 @@ export function EditDataSourceView({ diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.test.tsx new file mode 100644 index 00000000000..876da62c1ae --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.test.tsx @@ -0,0 +1,104 @@ +import '@testing-library/jest-dom'; +import { render, screen, fireEvent } from '@testing-library/react'; + +import { InfluxVersion } from '../../../types'; + +import { AdvancedDbConnectionSettings } from './AdvancedDBConnectionSettings'; +import { createTestProps } from './helpers'; + +describe('AdvancedDbConnectionSettings', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: {}, + secureJsonData: {}, + secureJsonFields: {}, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('toggles visibility of advanced settings', () => { + render(); + const toggle = screen.getByTestId('influxdb-v2-config-toggle-switch'); + fireEvent.click(toggle); + }); + + it('renders HTTP Method field for InfluxQL version', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.InfluxQL }, + }, + }; + + render(); + const toggle = screen.getByTestId('influxdb-v2-config-toggle-switch'); + fireEvent.click(toggle); + expect(screen.getByTestId('influxdb-v2-config-http-method-select')).toBeInTheDocument(); + }); + + it('renders insecure connection switch for SQL version and triggers change', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.SQL, insecureGrpc: false }, + }, + }; + + render(); + const toggle = screen.getByTestId('influxdb-v2-config-toggle-switch'); + fireEvent.click(toggle); + + const switchEl = screen.getByTestId('influxdb-v2-config-insecure-switch'); + expect(switchEl).toBeInTheDocument(); + fireEvent.click(switchEl); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); + + it('renders Min time interval input for InfluxQL', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.InfluxQL, timeInterval: '' }, + }, + }; + + render(); + const toggle = screen.getByTestId('influxdb-v2-config-toggle-switch'); + fireEvent.click(toggle); + + const input = screen.getByTestId('influxdb-v2-config-time-interval'); + expect(input).toBeInTheDocument(); + fireEvent.change(input, { target: { value: '15' } }); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); + + it('renders Min time interval input for Flux', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.Flux, timeInterval: '' }, + }, + }; + + render(); + const toggle = screen.getByTestId('influxdb-v2-config-toggle-switch'); + fireEvent.click(toggle); + + const input = screen.getByTestId('influxdb-v2-config-time-interval'); + expect(input).toBeInTheDocument(); + fireEvent.change(input, { target: { value: '15' } }); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.tsx new file mode 100644 index 00000000000..398fa8f3c76 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedDBConnectionSettings.tsx @@ -0,0 +1,100 @@ +import { cx } from '@emotion/css'; +import { useState } from 'react'; + +import { + onUpdateDatasourceJsonDataOption, + onUpdateDatasourceJsonDataOptionChecked, + onUpdateDatasourceJsonDataOptionSelect, +} from '@grafana/data'; +import { InlineFieldRow, InlineField, Combobox, InlineSwitch, Input, Space, useStyles2 } from '@grafana/ui'; + +import { InfluxVersion } from '../../../types'; + +import { getInlineLabelStyles, HTTP_MODES } from './constants'; +import { + trackInfluxDBConfigV2AdvancedDbConnectionSettingsHTTPMethodClicked, + trackInfluxDBConfigV2AdvancedDbConnectionSettingsInsecureConnectClicked, + trackInfluxDBConfigV2AdvancedDbConnectionSettingsMinTimeClicked, + trackInfluxDBConfigV2AdvancedDbConnectionSettingsToggleClicked, +} from './tracking'; +import { Props } from './types'; + +export const AdvancedDbConnectionSettings = (props: Props) => { + const { options } = props; + const styles = useStyles2(getInlineLabelStyles); + + const [advancedDbConnectionSettingsIsOpen, setAdvancedDbConnectionSettingsIsOpen] = useState( + () => !!options.jsonData.timeInterval || !!options.jsonData.insecureGrpc + ); + + return ( + <> + + Advanced Database Settings} labelWidth={40}> + setAdvancedDbConnectionSettingsIsOpen(!advancedDbConnectionSettingsIsOpen)} + onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsToggleClicked} + /> + + + {advancedDbConnectionSettingsIsOpen && ( + <> + {options.jsonData.version === InfluxVersion.InfluxQL && ( + + + httpMode.value === options.jsonData.httpMode)} + options={HTTP_MODES} + onChange={onUpdateDatasourceJsonDataOptionSelect(props, 'httpMode')} + onBlur={trackInfluxDBConfigV2AdvancedDbConnectionSettingsHTTPMethodClicked} + data-testid="influxdb-v2-config-http-method-select" + /> + + + )} + + {options.jsonData.version === InfluxVersion.SQL && ( + + + + + + )} + + {(options.jsonData.version === InfluxVersion.InfluxQL || options.jsonData.version === InfluxVersion.Flux) && ( + + + + + + )} + + )} + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.test.tsx new file mode 100644 index 00000000000..95b401ea063 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.test.tsx @@ -0,0 +1,71 @@ +import { render, screen, fireEvent } from '@testing-library/react'; + +import { AdvancedHttpSettings } from './AdvancedHttpSettings'; +import { createTestProps } from './helpers'; + +describe('AdvancedHttpSettings', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: {}, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders toggle and toggles section visibility', () => { + render(); + + const toggle = screen.getByTestId('influxdb-v2-config-advanced-http-settings-toggle'); + expect(toggle).toBeInTheDocument(); + + fireEvent.click(toggle); + expect(screen.getByLabelText('Timeout in seconds')).toBeInTheDocument(); + }); + + it('calls onOptionsChange when timeout is changed', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { + ...defaultProps.options.jsonData, + timeout: 10, + keepCookies: [], + }, + }, + }; + + render(); + + const input = screen.getByLabelText('Timeout in seconds'); + fireEvent.change(input, { target: { value: '20' } }); + expect(props.onOptionsChange).toHaveBeenCalled(); + }); + + it('calls onOptionsChange when allowed cookies are changed', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { + ...defaultProps.options.jsonData, + timeout: 10, + keepCookies: ['session'], + }, + }, + }; + + render(); + + const cookieInput = screen.getByPlaceholderText('New cookie (hit enter to add)'); + fireEvent.change(cookieInput, { target: { value: 'auth' } }); + fireEvent.keyDown(cookieInput, { key: 'Enter', code: 'Enter' }); + + expect(props.onOptionsChange).toHaveBeenCalled(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.tsx new file mode 100644 index 00000000000..2fe868514d7 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AdvancedHttpSettings.tsx @@ -0,0 +1,119 @@ +import { cx } from '@emotion/css'; +import { useState } from 'react'; + +import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; +import { + Box, + InlineField, + InlineSwitch, + Field, + TagsInput, + Input, + CustomHeadersSettings, + useStyles2, +} from '@grafana/ui'; + +import { InfluxOptions } from '../../../types'; + +import { getInlineLabelStyles } from './constants'; +import { + trackInfluxDBConfigV2AdvancedHTTPSettingsTimeoutField, + trackInfluxDBConfigV2AdvancedHTTPSettingsToggleClicked, +} from './tracking'; + +export type Props = DataSourcePluginOptionsEditorProps; + +export const AdvancedHttpSettings = ({ options, onOptionsChange }: Props) => { + const styles = useStyles2(getInlineLabelStyles); + + const [advancedHttpSettingsIsOpen, setAdvancedHttpSettingsIsOpen] = useState( + () => 'keepCookies' in options.jsonData || 'timeout' in options.jsonData + ); + + return ( + <> + + Advanced HTTP Settings} labelWidth={40}> + setAdvancedHttpSettingsIsOpen(!advancedHttpSettingsIsOpen)} + onBlur={trackInfluxDBConfigV2AdvancedHTTPSettingsToggleClicked} + /> + + + {advancedHttpSettingsIsOpen && options.access === 'proxy' && ( + <> + + + + { + onOptionsChange({ + ...options, + jsonData: { + ...options.jsonData, + ...{ keepCookies: e }, + }, + }); + }} + /> + + + + + + { + const parsed = parseInt(e.currentTarget.value, 10); + onOptionsChange({ + ...options, + jsonData: { + ...options.jsonData, + ...{ timeout: parsed }, + }, + }); + }} + onBlur={trackInfluxDBConfigV2AdvancedHTTPSettingsTimeoutField} + /> + + + + {advancedHttpSettingsIsOpen && ( + + )} + + + )} + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.test.tsx new file mode 100644 index 00000000000..4a51bb94728 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.test.tsx @@ -0,0 +1,131 @@ +import '@testing-library/jest-dom'; +import { render, screen, fireEvent, within } from '@testing-library/react'; + +import { AuthSettings } from './AuthSettings'; +import { createTestProps } from './helpers'; + +describe('AuthSettings', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: {}, + secureJsonData: {}, + secureJsonFields: {}, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('collapsible behaviour', () => { + it('starts collapsed when no auth option is active', () => { + render(); + + // Heading inside the collapsible body should be absent + expect(screen.queryByText(/Authentication Method/i)).not.toBeInTheDocument(); + }); + + it('expands when the top‑level switch is toggled', () => { + render(); + + fireEvent.click(screen.getByTestId('influxdb-v2-config-auth-settings-toggle')); + + expect(screen.getByText(/Authentication Method/i)).toBeInTheDocument(); + }); + }); + + describe('Basic Auth', () => { + beforeEach(() => { + render(); + + // open section first + fireEvent.click(screen.getByTestId('influxdb-v2-config-auth-settings-toggle')); + }); + + it('reveals Basic Auth inputs when Basic Auth is selected', () => { + fireEvent.click(screen.getByRole('radio', { name: /Basic Auth/i })); + + expect(screen.getByPlaceholderText('User')).toBeInTheDocument(); + expect(screen.getByPlaceholderText('Password')).toBeInTheDocument(); + }); + + it('propagates user input via onOptionsChange', async () => { + fireEvent.click(screen.getByRole('radio', { name: /Basic Auth/i })); + + fireEvent.change(screen.getByPlaceholderText('User'), { + target: { value: 'john_doe' }, + }); + + expect(onOptionsChangeMock).toHaveBeenCalledWith(expect.objectContaining({ basicAuthUser: 'john_doe' })); + }); + }); + + describe('TLS Settings', () => { + beforeEach(() => { + render(); + + // Expand the settings panel once for all tests + fireEvent.click(screen.getByTestId('influxdb-v2-config-auth-settings-toggle')); + }); + + describe('TLS Client Auth', () => { + it('shows and hides Server Name input when toggled Enabled/Disabled', () => { + const tlsRow = screen.getByTestId('influxdb-v2-config-auth-settings-tls-client-auth-toggle'); + + // Initially hidden + expect(screen.queryByPlaceholderText('domain.example.com')).not.toBeInTheDocument(); + + // Enable TLS Client Auth + fireEvent.click(within(tlsRow).getByText('Enabled')); + expect(screen.getByPlaceholderText('domain.example.com')).toBeInTheDocument(); + + // Disable again + fireEvent.click(within(tlsRow).getByText('Disabled')); + expect(screen.queryByPlaceholderText('domain.example.com')).not.toBeInTheDocument(); + }); + }); + + describe('CA Cert', () => { + it('shows and hides certificate textarea when toggled Enabled/Disabled', () => { + const placeholderText = 'Begins with -----BEGIN CERTIFICATE-----'; + + const caRow = screen.getByTestId('influxdb-v2-config-auth-settings-ca-cert-toggle'); + const enabledRadio = within(caRow).getByText('Enabled'); + const disabledRadio = within(caRow).getByText('Disabled'); + + // Initially hidden + expect(screen.queryByPlaceholderText(placeholderText)).not.toBeInTheDocument(); + + // Enable + fireEvent.click(enabledRadio); + expect(screen.getByPlaceholderText(placeholderText)).toBeInTheDocument(); + + // Disable + fireEvent.click(disabledRadio); + expect(screen.queryByPlaceholderText(placeholderText)).not.toBeInTheDocument(); + }); + }); + + describe('Skip TLS Verify', () => { + it('toggles checked state of the switch', () => { + const skipSwitch = screen.getByTestId('influxdb-v2-config-auth-settings-skip-tls-verify'); + + // Default unchecked + expect(skipSwitch).not.toBeChecked(); + + // Enable + fireEvent.click(skipSwitch); + expect(skipSwitch).toBeChecked(); + + // Disable + fireEvent.click(skipSwitch); + expect(skipSwitch).not.toBeChecked(); + }); + }); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.tsx new file mode 100644 index 00000000000..1f359afb594 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/AuthSettings.tsx @@ -0,0 +1,267 @@ +import { cx } from '@emotion/css'; +import { useCallback, useMemo, useState } from 'react'; + +import { + onUpdateDatasourceOption, + onUpdateDatasourceSecureJsonDataOption, + updateDatasourcePluginResetOption, +} from '@grafana/data'; +import { AuthMethod, convertLegacyAuthProps } from '@grafana/plugin-ui'; +import { + Box, + CertificationKey, + Field, + InlineField, + InlineSwitch, + Input, + Label, + RadioButtonGroup, + SecretInput, + useStyles2, + Text, + Stack, +} from '@grafana/ui'; + +import { AUTH_RADIO_BUTTON_OPTIONS, getInlineLabelStyles, RADIO_BUTTON_OPTIONS } from './constants'; +import { + trackInfluxDBConfigV2AuthSettingsAuthMethodSelected, + trackInfluxDBConfigV2AuthSettingsToggleClicked, +} from './tracking'; +import { Props } from './types'; + +type AuthOptionState = { + basicAuth: boolean; + tlsClientAuth: boolean; + caCert: boolean; + skipTLS: boolean; + oAuthForward: boolean; + withCredentials: boolean; +}; + +export const AuthSettings = (props: Props) => { + const { options, onOptionsChange } = props; + const styles = useStyles2(getInlineLabelStyles); + + /** + * Derived props from legacy helpers + */ + const authProps = useMemo( + () => + convertLegacyAuthProps({ + config: options, + onChange: onOptionsChange, + }), + [options, onOptionsChange] + ); + + /** + * Selected authentication method. Fallback to the most common if the selected one is missing. + */ + const isAuthMethod = (v: unknown): v is AuthMethod => + v === AuthMethod.NoAuth || v === AuthMethod.BasicAuth || v === AuthMethod.OAuthForward; + + const selectedMethod = useMemo(() => { + if (isAuthMethod(authProps.selectedMethod)) { + return authProps.selectedMethod; + } + return isAuthMethod(authProps.mostCommonMethod) ? authProps.mostCommonMethod : undefined; + }, [authProps.selectedMethod, authProps.mostCommonMethod]); + + /** + * Local UI state + */ + const [authOptions, setAuthOptions] = useState({ + basicAuth: selectedMethod === AuthMethod.BasicAuth, + tlsClientAuth: authProps.TLS?.TLSClientAuth.enabled ?? false, + caCert: authProps.TLS?.selfSignedCertificate.enabled ?? false, + skipTLS: authProps.TLS?.skipTLSVerification.enabled ?? false, + oAuthForward: selectedMethod === AuthMethod.OAuthForward, + withCredentials: options.withCredentials ?? false, + }); + + /** + * Expand/collapse top–level section + */ + const [authenticationSettingsIsOpen, setAuthenticationSettingsIsOpen] = useState( + Object.values(authOptions).some(Boolean) + ); + + const toggleOpen = useCallback(() => { + setAuthenticationSettingsIsOpen((prev) => { + trackInfluxDBConfigV2AuthSettingsToggleClicked(); + return !prev; + }); + }, []); + + const handleAuthMethodChange = useCallback( + (option: AuthMethod) => { + authProps.onAuthMethodSelect(option); + setAuthOptions((prev) => ({ + ...prev, + basicAuth: option === AuthMethod.BasicAuth, + oAuthForward: option === AuthMethod.OAuthForward, + })); + trackInfluxDBConfigV2AuthSettingsAuthMethodSelected({ authMethod: option }); + }, + [authProps] + ); + + /** + * Wraps the toggle of an auth option, updates the local state and calls the onToggle callback + * provided by the legacy `authProps` provided by `@grafana/plugin-ui`. + */ + const toggleOption = useCallback((key: keyof AuthOptionState, onToggle: (value: boolean) => void) => { + setAuthOptions((prev) => { + const nextValue = !prev[key]; + const next = { ...prev, [key]: nextValue }; + onToggle(nextValue); + return next; + }); + }, []); + + return ( + + {/* Header toggle */} + + Auth and TLS/SSL Settings} labelWidth={35}> + + + + + {/* Collapsible settings body */} + {authenticationSettingsIsOpen && ( + + {/* Authentication Method */} + + Authentication Method} noMargin> + + + + + + + + {/* Basic Auth settings */} + {authOptions.basicAuth && ( + <> + + + + + + updateDatasourcePluginResetOption(props, 'basicAuthPassword')} + value={options.secureJsonData?.basicAuthPassword || ''} + /> + + + + )} + + + {/* TLS Client Auth */} + + + <> + TLS Settings + + + toggleOption('tlsClientAuth', authProps.TLS!.TLSClientAuth.onToggle)} + size="sm" + /> + + + {authOptions.tlsClientAuth && ( + + + authProps.TLS?.TLSClientAuth.onServerNameChange(e.currentTarget.value)} + value={authProps.TLS?.TLSClientAuth.serverName || ''} + /> + + authProps.TLS?.TLSClientAuth.onClientCertificateChange(e.currentTarget.value)} + hasCert={!!authProps.TLS?.TLSClientAuth.clientCertificateConfigured} + onClick={() => authProps.TLS?.TLSClientAuth.onClientCertificateReset()} + /> + authProps.TLS?.TLSClientAuth.onClientKeyChange(e.currentTarget.value)} + hasCert={!!authProps.TLS?.TLSClientAuth.clientKeyConfigured} + onClick={() => authProps.TLS?.TLSClientAuth.onClientKeyReset()} + /> + + )} + + + + + {/* CA Cert */} + + + <> + + + toggleOption('caCert', authProps.TLS!.selfSignedCertificate.onToggle)} + size="sm" + /> + + {authOptions.caCert && ( + + authProps.TLS?.selfSignedCertificate.onCertificateChange(e.currentTarget.value)} + hasCert={!!authProps.TLS?.selfSignedCertificate.certificateConfigured} + onClick={() => authProps.TLS?.selfSignedCertificate.onCertificateReset()} + /> + + )} + + + + + {/* Skip TLS verify */} + + + toggleOption('skipTLS', authProps.TLS!.skipTLSVerification.onToggle)} + /> + + + )} + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.test.tsx new file mode 100644 index 00000000000..9035fc5c7a8 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.test.tsx @@ -0,0 +1,44 @@ +import '@testing-library/jest-dom'; + +import { render, screen } from '@testing-library/react'; + +import { ConfigEditor } from './ConfigEditor'; +import { createTestProps } from './helpers'; + +jest.mock('./LeftSideBar', () => ({ + LeftSideBar: () =>
, +})); + +jest.mock('./UrlAndAuthenticationSection', () => ({ + UrlAndAuthenticationSection: () =>
, +})); + +jest.mock('./DatabaseConnectionSection', () => ({ + DatabaseConnectionSection: () =>
, +})); + +describe('ConfigEditor', () => { + const defaultProps = createTestProps({ + options: { + jsonData: {}, + secureJsonData: {}, + secureJsonFields: {}, + }, + mocks: { + onOptionsChange: jest.fn(), + }, + }); + + it('renders the LeftSideBar, UrlAndAuthenticationSection, and DatabaseConnectionSection', () => { + render(); + + expect(screen.getByTestId('left-sidebar')).toBeInTheDocument(); + expect(screen.getByTestId('url-auth-section')).toBeInTheDocument(); + expect(screen.getByTestId('db-connection-section')).toBeInTheDocument(); + }); + + it('shows the informational alert', () => { + render(); + expect(screen.getByText(/You are viewing a new design/i)).toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.tsx new file mode 100644 index 00000000000..6ae9d8bf530 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/ConfigEditor.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +import { Alert, Box, Stack, TextLink } from '@grafana/ui'; + +import { DatabaseConnectionSection } from './DatabaseConnectionSection'; +import { LeftSideBar } from './LeftSideBar'; +import { UrlAndAuthenticationSection } from './UrlAndAuthenticationSection'; +import { trackInfluxDBConfigV2FeedbackButtonClicked } from './tracking'; +import { Props } from './types'; + +export const ConfigEditor: React.FC = ({ onOptionsChange, options }: Props) => { + return ( + + + + + + + + <> + If something isn't working correctly, you can revert to the original configuration page design by + disabling the newInfluxDSConfigPageDesign feature flag.{' '} + + Submit feedback. + + + + + + + + + {/* TODO: Right sidebar */} + + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.test.tsx new file mode 100644 index 00000000000..695bf78d4d0 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.test.tsx @@ -0,0 +1,96 @@ +import '@testing-library/jest-dom'; + +import { render, screen } from '@testing-library/react'; + +import { InfluxVersion } from '../../../types'; + +import { DatabaseConnectionSection } from './DatabaseConnectionSection'; +import { createTestProps } from './helpers'; + +jest.mock('./AdvancedDBConnectionSettings', () => ({ + AdvancedDbConnectionSettings: () =>
, +})); + +jest.mock('./InfluxFluxDBConnection', () => ({ + InfluxFluxDBConnection: () =>
, +})); + +jest.mock('./InfluxSQLDBConnection', () => ({ + InfluxSQLDBConnection: () =>
, +})); + +jest.mock('./InfluxInfluxQLDBConnection', () => ({ + InfluxInfluxQLDBConnection: () =>
, +})); + +describe('DatabaseConnectionSection', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: {}, + secureJsonData: {}, + secureJsonFields: {}, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + it('shows alert when version is missing', () => { + render(); + expect(screen.getByText(/To view connection settings/i)).toBeInTheDocument(); + }); + + it('renders Flux connection component when version is Flux', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.Flux }, + }, + }; + + render(); + expect(screen.getByTestId('flux-connection')).toBeInTheDocument(); + }); + + it('renders InfluxQL connection component when version is InfluxQL', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.InfluxQL }, + }, + }; + + render(); + expect(screen.getByTestId('influxql-connection')).toBeInTheDocument(); + }); + + it('renders SQL connection component when version is SQL', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.SQL }, + }, + }; + + render(); + expect(screen.getByTestId('sql-connection')).toBeInTheDocument(); + }); + + it('always renders AdvancedDbConnectionSettings', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { version: InfluxVersion.SQL }, + }, + }; + + render(); + expect(screen.getByTestId('advanced-db-settings')).toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.tsx new file mode 100644 index 00000000000..4635258b8cc --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/DatabaseConnectionSection.tsx @@ -0,0 +1,65 @@ +import { Box, CollapsableSection, Alert, Space, Text } from '@grafana/ui'; + +import { InfluxVersion } from '../../../types'; + +import { AdvancedDbConnectionSettings } from './AdvancedDBConnectionSettings'; +import { InfluxFluxDBConnection } from './InfluxFluxDBConnection'; +import { InfluxInfluxQLDBConnection } from './InfluxInfluxQLDBConnection'; +import { InfluxSQLDBConnection } from './InfluxSQLDBConnection'; +import { CONFIG_SECTION_HEADERS } from './constants'; +import { Props } from './types'; + +export const DatabaseConnectionSection = ({ options, onOptionsChange }: Props) => ( + <> + + 2. {CONFIG_SECTION_HEADERS[1].label}} + isOpen={CONFIG_SECTION_HEADERS[1].isOpen} + > + {!options.jsonData.version && ( + +

To view connection settings, first choose a query language in the URL and Connection section.

+
+ )} + {options.jsonData.version === InfluxVersion.InfluxQL && ( + <> + +

+ Setting the database for this datasource does not deny access to other databases. The InfluxDB query + syntax allows switching the database in the query. For example: + SHOW MEASUREMENTS ON _internal or + SELECT * FROM "_internal".."database" LIMIT 10 +
+
+ To support data isolation and security, make sure appropriate permissions are configured in InfluxDB. +

+
+ + )} + {options.jsonData.version && ( + <> + + Provide the necessary database connection details based on your selected InfluxDB product and query + language. + + + + )} + <> + {options.jsonData.version === InfluxVersion.InfluxQL && ( + + )} + {options.jsonData.version === InfluxVersion.Flux && ( + + )} + {options.jsonData.version === InfluxVersion.SQL && ( + + )} + {options.jsonData.version && ( + + )} + +
+
+ +); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.test.tsx new file mode 100644 index 00000000000..2288c1f3881 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.test.tsx @@ -0,0 +1,46 @@ +import '@testing-library/jest-dom'; + +import { render, screen, fireEvent } from '@testing-library/react'; + +import { InfluxFluxDBConnection } from './InfluxFluxDBConnection'; +import { createTestProps } from './helpers'; + +describe('InfluxFluxDBConnection', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: { + organization: 'MyOrg', + defaultBucket: 'MyBucket', + }, + secureJsonData: { + token: 'my-token', + }, + secureJsonFields: { + token: true, + }, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders organization, bucket and token inputs', () => { + render(); + expect(screen.getByLabelText(/Organization/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Default Bucket/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Token/i)).toBeInTheDocument(); + }); + + it('calls onOptionsChange on input change', () => { + render(); + const orgInput = screen.getByLabelText(/Organization/i); + fireEvent.change(orgInput, { target: { value: 'NewOrg' } }); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.tsx new file mode 100644 index 00000000000..0436f970742 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxFluxDBConnection.tsx @@ -0,0 +1,58 @@ +import { + onUpdateDatasourceJsonDataOption, + onUpdateDatasourceSecureJsonDataOption, + updateDatasourcePluginResetOption, +} from '@grafana/data'; +import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui'; + +import { + trackInfluxDBConfigV2FluxDBDetailsDefaultBucketInputField, + trackInfluxDBConfigV2FluxDBDetailsOrgInputField, + trackInfluxDBConfigV2FluxDBDetailsTokenInputField, +} from './tracking'; +import { Props } from './types'; + +export const InfluxFluxDBConnection = (props: Props) => { + const { + options: { jsonData, secureJsonData, secureJsonFields }, + } = props; + + return ( + <> + + + + + + + + + + + + + updateDatasourcePluginResetOption(props, 'token')} + value={secureJsonData?.token || ''} + /> + + + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.test.tsx new file mode 100644 index 00000000000..9351cbda5de --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.test.tsx @@ -0,0 +1,41 @@ +import '@testing-library/jest-dom'; + +import { render, screen, fireEvent } from '@testing-library/react'; + +import { InfluxInfluxQLDBConnection } from './InfluxInfluxQLDBConnection'; +import { createTestProps } from './helpers'; + +describe('InfluxInfluxQLDBConnection', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + user: 'admin', + jsonData: { + dbName: 'influxdb', + }, + secureJsonData: { + password: 'secret', + }, + secureJsonFields: { + password: true, + }, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + it('renders dbName, user and password fields', () => { + render(); + expect(screen.getByLabelText(/Database/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/User/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Password/i)).toBeInTheDocument(); + }); + + it('calls onOptionsChange on input changes', () => { + render(); + fireEvent.change(screen.getByLabelText(/User/i), { target: { value: 'newuser' } }); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.tsx new file mode 100644 index 00000000000..5bfd32732a7 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxInfluxQLDBConnection.tsx @@ -0,0 +1,57 @@ +import { + onUpdateDatasourceJsonDataOption, + onUpdateDatasourceOption, + onUpdateDatasourceSecureJsonDataOption, + updateDatasourcePluginResetOption, +} from '@grafana/data'; +import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui'; + +import { + trackInfluxDBConfigV2InfluxQLDBDetailsDatabaseInputField, + trackInfluxDBConfigV2InfluxQLDBDetailsPasswordInputField, + trackInfluxDBConfigV2InfluxQLDBDetailsUserInputField, +} from './tracking'; +import { Props } from './types'; + +export const InfluxInfluxQLDBConnection = (props: Props) => { + const { options } = props; + + return ( + <> + + + + + + + + + + + + + updateDatasourcePluginResetOption(props, 'password')} + onChange={onUpdateDatasourceSecureJsonDataOption(props, 'password')} + onBlur={trackInfluxDBConfigV2InfluxQLDBDetailsPasswordInputField} + /> + + + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.test.tsx new file mode 100644 index 00000000000..575198d61fb --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.test.tsx @@ -0,0 +1,39 @@ +import '@testing-library/jest-dom'; + +import { render, screen, fireEvent } from '@testing-library/react'; + +import { InfluxSQLDBConnection } from './InfluxSQLDBConnection'; +import { createTestProps } from './helpers'; + +describe('InfluxSQLDBConnection', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: { + dbName: 'testdb', + }, + secureJsonData: { + token: 'abc123', + }, + secureJsonFields: { + token: true, + }, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + it('renders database and token fields', () => { + render(); + expect(screen.getByLabelText(/Database/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Token/i)).toBeInTheDocument(); + }); + + it('calls onOptionsChange on dbName change', () => { + render(); + fireEvent.change(screen.getByLabelText(/Database/i), { target: { value: 'newdb' } }); + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.tsx new file mode 100644 index 00000000000..cdf49743e7e --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/InfluxSQLDBConnection.tsx @@ -0,0 +1,45 @@ +import { + onUpdateDatasourceJsonDataOption, + onUpdateDatasourceSecureJsonDataOption, + updateDatasourcePluginResetOption, +} from '@grafana/data'; +import { InlineFieldRow, InlineField, Input, SecretInput } from '@grafana/ui'; + +import { + trackInfluxDBConfigV2SQLDBDetailsDatabaseInputField, + trackInfluxDBConfigV2SQLDBDetailsTokenInputField, +} from './tracking'; +import { Props } from './types'; + +export const InfluxSQLDBConnection = (props: Props) => { + const { options } = props; + const { secureJsonData, secureJsonFields } = options; + + return ( + <> + + + + + + + + updateDatasourcePluginResetOption(props, 'token')} + value={secureJsonData?.token || ''} + /> + + + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.test.tsx new file mode 100644 index 00000000000..20fd0661ae7 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.test.tsx @@ -0,0 +1,16 @@ +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/react'; + +import { LeftSideBar } from './LeftSideBar'; + +describe('LeftSideBar', () => { + it('renders sidebar title when pdcInjected is true', () => { + render(); + expect(screen.getByTestId('Private data source connect-sidebar')).toBeInTheDocument(); + }); + + it('does not render sidebar title when pdcInjected is false', () => { + render(); + expect(screen.queryByTestId('Private data source connect-sidebar')).not.toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.tsx new file mode 100644 index 00000000000..ab6b7522a68 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/LeftSideBar.tsx @@ -0,0 +1,40 @@ +import { Box, InlineField, LinkButton, Space, Stack, Text } from '@grafana/ui'; + +import { CONFIG_SECTION_HEADERS, CONFIG_SECTION_HEADERS_WITH_PDC } from './constants'; + +interface LeftSideBarProps { + pdcInjected: boolean; +} + +export const LeftSideBar = ({ pdcInjected }: LeftSideBarProps) => { + const headers = pdcInjected ? CONFIG_SECTION_HEADERS_WITH_PDC : CONFIG_SECTION_HEADERS; + return ( + + + InfluxDB + + {headers.map((header, index) => ( +
+ + { + e.preventDefault(); + const target = document.getElementById(header.id); + if (target) { + target.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }} + > + {header.label} + + + +
+ ))} +
+
+
+ ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx new file mode 100644 index 00000000000..db5f9172a67 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.test.tsx @@ -0,0 +1,90 @@ +import { render, screen, fireEvent } from '@testing-library/react'; + +import { InfluxVersion } from '../../../types'; + +import { UrlAndAuthenticationSection } from './UrlAndAuthenticationSection'; +import { createTestProps } from './helpers'; + +describe('UrlAndAuthenticationSection', () => { + const onOptionsChangeMock = jest.fn(); + + const defaultProps = createTestProps({ + options: { + jsonData: { + url: 'http://localhost:8086', + product: '', + version: '', + }, + secureJsonData: {}, + secureJsonFields: {}, + }, + mocks: { + onOptionsChange: onOptionsChangeMock, + }, + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('calls onOptionsChange when URL is changed', () => { + render(); + + const input = screen.getByTestId('influxdb-v2-config-url-input'); + fireEvent.change(input, { target: { value: 'http://example.com' } }); + + expect(onOptionsChangeMock).toHaveBeenCalled(); + }); + + it('renders DRBP warning for InfluxDB OSS 1.x and InfluxQL', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { product: 'InfluxDB OSS 1.x', version: InfluxVersion.InfluxQL }, + }, + }; + + render(); + expect(screen.getByText(/requires DRBP mapping/i)).toBeInTheDocument(); + }); + + it('renders DRBP warning for InfluxDB OSS 2.x and InfluxQL', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { product: 'InfluxDB OSS 2.x', version: InfluxVersion.InfluxQL }, + }, + }; + + render(); + expect(screen.getByText(/requires DRBP mapping/i)).toBeInTheDocument(); + }); + + it('does not render DRBP warning for InfluxDB OSS 1.x and Flux', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { product: 'InfluxDB OSS 1.x', version: InfluxVersion.Flux }, + }, + }; + + render(); + expect(screen.queryByText(/requires DRBP mapping/i)).not.toBeInTheDocument(); + }); + + it('does not render DRBP warning for InfluxDB OSS 2.x and Flux', () => { + const props = { + ...defaultProps, + options: { + ...defaultProps.options, + jsonData: { product: 'InfluxDB OSS 2.x', version: InfluxVersion.Flux }, + }, + }; + + render(); + expect(screen.queryByText(/requires DRBP mapping/i)).not.toBeInTheDocument(); + }); +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx new file mode 100644 index 00000000000..425fec11210 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/UrlAndAuthenticationSection.tsx @@ -0,0 +1,131 @@ +import { onUpdateDatasourceJsonDataOptionSelect, onUpdateDatasourceOption } from '@grafana/data'; +import { + Box, + CollapsableSection, + TextLink, + Field, + Input, + Combobox, + Space, + Stack, + Text, + ComboboxOption, + Alert, +} from '@grafana/ui'; + +import { InfluxVersion } from '../../../types'; + +import { AdvancedHttpSettings } from './AdvancedHttpSettings'; +import { AuthSettings } from './AuthSettings'; +import { CONFIG_SECTION_HEADERS } from './constants'; +import { + trackInfluxDBConfigV2ProductSelected, + trackInfluxDBConfigV2QueryLanguageSelected, + trackInfluxDBConfigV2URLInputField, +} from './tracking'; +import { Props } from './types'; +import { INFLUXDB_VERSION_MAP } from './versions'; + +const getQueryLanguageOptions = (productName: string): Array<{ value: string }> => { + const product = INFLUXDB_VERSION_MAP.find(({ name }) => name === productName); + return product?.queryLanguages?.map(({ name }) => ({ value: name })) ?? []; +}; + +export const UrlAndAuthenticationSection = (props: Props) => { + const { options, onOptionsChange } = props; + + const isInfluxVersion = (v: string): v is InfluxVersion => + typeof v === 'string' && (v === InfluxVersion.Flux || v === InfluxVersion.InfluxQL || v === InfluxVersion.SQL); + + // Database + Retention Policy (DBRP) mapping is required for InfluxDB OSS 1.x and 2.x when using InfluxQL + const requiresDrbpMapping = + options.jsonData.product && + options.jsonData.version === InfluxVersion.InfluxQL && + ['InfluxDB OSS 1.x', 'InfluxDB OSS 2.x'].includes(options.jsonData.product); + + const onProductChange = ({ value }: ComboboxOption) => + onOptionsChange({ ...options, jsonData: { ...options.jsonData, product: value, version: undefined } }); + + const onQueryLanguageChange = (option: ComboboxOption) => { + const { value } = option; + + if (isInfluxVersion(value)) { + onUpdateDatasourceJsonDataOptionSelect(props, 'version')(option); + } + }; + + const onUrlChange = (event: React.ChangeEvent) => onUpdateDatasourceOption(props, 'url')(event); + + return ( + + 1. {CONFIG_SECTION_HEADERS[0].label}} + isOpen={CONFIG_SECTION_HEADERS[0].isOpen} + > + + Enter the URL of your InfluxDB instance, then select your product and query language. This will determine the + available settings and authentication methods in the next steps. If you are unsure what product you are using, + view the{' '} + + InfluxDB Docs. + + . + + + + URL
} noMargin> + + + + + + + Product
} noMargin> + ({ value: name }))} + onChange={onProductChange} + onBlur={() => trackInfluxDBConfigV2ProductSelected({ product: options.jsonData.product! })} + /> + + + + Query language
} noMargin> + trackInfluxDBConfigV2QueryLanguageSelected({ version: options.url })} + /> + + + + + + + + {requiresDrbpMapping && ( + + InfluxDB OSS 1.x and 2.x users must configure a Database + Retention Policy (DBRP) mapping via the CLI or + API before data can be queried.{' '} + + Learn how to set this up + + + )} + + + + + + + ); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts new file mode 100644 index 00000000000..3ae3122bffd --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/constants.ts @@ -0,0 +1,57 @@ +import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; +import { AuthMethod } from '@grafana/plugin-ui'; +import { ComboboxOption } from '@grafana/ui'; + +export const RADIO_BUTTON_OPTIONS = [ + { label: 'Enabled', value: true }, + { label: 'Disabled', value: false }, +]; + +export const AUTH_RADIO_BUTTON_OPTIONS = [ + { label: 'No Authentication', value: AuthMethod.NoAuth }, + { label: 'Basic Authentication', value: AuthMethod.BasicAuth }, + { label: 'Forward OAuth Identity', value: AuthMethod.OAuthForward }, +]; + +export const CONFIG_SECTION_HEADERS = [ + { label: 'URL and authentication', id: 'url', isOpen: true }, + { label: 'Database settings', id: 'tls', isOpen: true }, + { label: 'Save & test', id: `${selectors.pages.DataSource.saveAndTest}`, isOpen: true }, +]; + +export const CONFIG_SECTION_HEADERS_WITH_PDC = [ + { label: 'URL and authentication', id: 'url', isOpen: true }, + { label: 'Database settings', id: 'tls', isOpen: true }, + { label: 'Private data source connect', id: 'pdc', isOpen: true }, + { label: 'Save & test', id: `${selectors.pages.DataSource.saveAndTest}`, isOpen: true }, +]; + +export const HTTP_MODES: ComboboxOption[] = [ + { label: 'GET', value: 'GET' }, + { label: 'POST', value: 'POST' }, +]; + +export const getInlineLabelStyles = (theme: GrafanaTheme2, transparent = false, width?: number | 'auto') => { + return { + label: css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + flexShrink: 0, + padding: theme.spacing(0, 1), + fontWeight: theme.typography.fontWeightMedium, + fontSize: theme.typography.size.md, + backgroundColor: transparent ? 'transparent' : theme.colors.background.secondary, + height: theme.spacing(theme.components.height.md), + lineHeight: theme.spacing(theme.components.height.md), + marginRight: theme.spacing(0.5), + borderRadius: theme.shape.radius.default, + border: 'none', + width: '240px', + color: theme.colors.text.primary, + }), + }; +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/helpers.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/helpers.ts new file mode 100644 index 00000000000..4493a9328a2 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/helpers.ts @@ -0,0 +1,33 @@ +/** + * Creates a set of test props for the InfluxDB V2 config page for use in tests. + * This function allows you to override default properties for specific test cases. + */ +export const createTestProps = (overrides: { options?: object; mocks?: object }) => ({ + options: { + access: 'proxy', + basicAuth: false, + basicAuthUser: '', + database: '', + id: 1, + isDefault: false, + jsonData: { + httpMode: 'POST', + timeInterval: '5', + }, + name: 'InfluxDB', + orgId: 1, + readOnly: false, + secureJsonFields: {}, + type: 'influxdb', + typeLogoUrl: '', + typeName: 'Influx', + uid: 'z', + url: '', + user: '', + version: 1, + withCredentials: false, + ...overrides.options, + }, + onOptionsChange: jest.fn(), + ...overrides.mocks, +}); diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/tracking.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/tracking.ts new file mode 100644 index 00000000000..92d293d8f5c --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/tracking.ts @@ -0,0 +1,89 @@ +import { reportInteraction } from '@grafana/runtime'; + +// Config Section +export const trackInfluxDBConfigV2FeedbackButtonClicked = () => { + reportInteraction('influxdb-config-v2-feedback-button-clicked'); +}; + +// URL and Auth Section +export const trackInfluxDBConfigV2URLInputField = () => { + reportInteraction('influxdb-config-v2-url-input-field'); +}; + +export const trackInfluxDBConfigV2QueryLanguageSelected = (props: { version: string }) => { + reportInteraction('influxdb-config-v2-query-language-dropdown', props); +}; + +export const trackInfluxDBConfigV2ProductSelected = (props: { product: string }) => { + reportInteraction('influxdb-config-v2-product-selection-dropdown', props); +}; + +// Flux Database Details Fields +export const trackInfluxDBConfigV2FluxDBDetailsOrgInputField = () => { + reportInteraction('influxdb-config-v2-flux-dbdetails-org-input-field'); +}; + +export const trackInfluxDBConfigV2FluxDBDetailsDefaultBucketInputField = () => { + reportInteraction('influxdb-config-v2-flux-dbdetails-default-bucket-input-field'); +}; + +export const trackInfluxDBConfigV2FluxDBDetailsTokenInputField = () => { + reportInteraction('influxdb-config-v2-flux-dbdetails-token-input-field'); +}; + +// InfluxQL Database Details Fields +export const trackInfluxDBConfigV2InfluxQLDBDetailsDatabaseInputField = () => { + reportInteraction('influxdb-config-v2-influxql-dbdetails-database-input-field'); +}; + +export const trackInfluxDBConfigV2InfluxQLDBDetailsUserInputField = () => { + reportInteraction('influxdb-config-v2-influxql-dbdetails-user-input-field'); +}; + +export const trackInfluxDBConfigV2InfluxQLDBDetailsPasswordInputField = () => { + reportInteraction('influxdb-config-v2-influxql-dbdetails-password-input-field'); +}; + +// SQL Database Details Fields +export const trackInfluxDBConfigV2SQLDBDetailsDatabaseInputField = () => { + reportInteraction('influxdb-config-v2-sql-dbdetails-database-input-field'); +}; + +export const trackInfluxDBConfigV2SQLDBDetailsTokenInputField = () => { + reportInteraction('influxdb-config-v2-sql-dbdetails-token-input-field'); +}; + +// Advanced DB Connection Settings +export const trackInfluxDBConfigV2AdvancedDbConnectionSettingsToggleClicked = () => { + reportInteraction('influxdb-config-v2-advanceddb-settings-toggle-clicked'); +}; + +export const trackInfluxDBConfigV2AdvancedDbConnectionSettingsHTTPMethodClicked = () => { + reportInteraction('influxdb-config-v2-advanceddb-settings-http-method-clicked'); +}; + +export const trackInfluxDBConfigV2AdvancedDbConnectionSettingsInsecureConnectClicked = () => { + reportInteraction('influxdb-config-v2-advanceddb-settings-insecure-connection-clicked'); +}; + +export const trackInfluxDBConfigV2AdvancedDbConnectionSettingsMinTimeClicked = () => { + reportInteraction('influxdb-config-v2-advanceddb-settings-min-time-clicked'); +}; + +// Advanced HTTP Settings +export const trackInfluxDBConfigV2AdvancedHTTPSettingsToggleClicked = () => { + reportInteraction('influxdb-config-v2-advanced-http-settings-toggle-clicked'); +}; + +export const trackInfluxDBConfigV2AdvancedHTTPSettingsTimeoutField = () => { + reportInteraction('influxdb-config-v2-advanced-http-settings-timeout-field'); +}; + +// Auth Settings +export const trackInfluxDBConfigV2AuthSettingsToggleClicked = () => { + reportInteraction('influxdb-config-v2-auth-settings-toggle-clicked'); +}; + +export const trackInfluxDBConfigV2AuthSettingsAuthMethodSelected = (props: { authMethod: string }) => { + reportInteraction('influxdb-config-v2-advanced-http-settings-timeout-field', props); +}; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/types.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/types.ts new file mode 100644 index 00000000000..545b6e105c0 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/types.ts @@ -0,0 +1,22 @@ +import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; + +import { InfluxOptions, InfluxSecureJsonData } from '../../../types'; + +// As we're not using the auth component in `@grafana/plugin-ui`, we're defining the missing properties here +// to ensure the types are compatible with the existing code. +// +// They should be removed at a later point. + +type InfluxBasicAuthData = { + basicAuth?: boolean; + basicAuthUser?: string; +}; + +type InfluxSecureBasicAuthData = { + basicAuthPassword?: string; +}; + +export type Props = DataSourcePluginOptionsEditorProps< + InfluxOptions & InfluxBasicAuthData, + InfluxSecureJsonData & InfluxSecureBasicAuthData +>; diff --git a/public/app/plugins/datasource/influxdb/components/editor/config-v2/versions.ts b/public/app/plugins/datasource/influxdb/components/editor/config-v2/versions.ts new file mode 100644 index 00000000000..7cc16af1fb8 --- /dev/null +++ b/public/app/plugins/datasource/influxdb/components/editor/config-v2/versions.ts @@ -0,0 +1,141 @@ +import { InfluxVersion } from '../../../types'; + +interface AuthMethod { + type: 'Basic' | 'Token'; + fields: string[]; +} + +interface QueryLanguageConfig { + name: InfluxVersion; + fields: Array; +} + +interface DetectionMethod { + urlContains?: string[]; + pingHeaderResponse?: Record; +} +interface InfluxDBProduct { + name: string; + queryLanguages?: QueryLanguageConfig[]; + detectionMethod?: DetectionMethod; +} + +// Complete Data Structure: +export const INFLUXDB_VERSION_MAP: InfluxDBProduct[] = [ + { + name: 'InfluxDB Cloud Dedicated', + queryLanguages: [ + { name: InfluxVersion.SQL, fields: ['Host', 'Database', 'Token'] }, + { name: InfluxVersion.InfluxQL, fields: ['Host', 'Database', 'Token'] }, + ], + detectionMethod: { + urlContains: ['influxdb.io'], + }, + }, + { + name: 'InfluxDB Cloud Serverless', + queryLanguages: [ + { name: InfluxVersion.SQL, fields: ['Host', 'Bucket', 'Token'] }, + { name: InfluxVersion.InfluxQL, fields: ['Host', 'Bucket', 'Token'] }, + { name: InfluxVersion.Flux, fields: ['Host', 'Organization', 'Token', 'Default bucket'] }, + ], + detectionMethod: { + urlContains: ['us-east-1-1.aws.cloud2.influxdata.com', 'eu-central-1-1.aws.cloud2.influxdata.com'], + }, + }, + { + name: 'InfluxDB Clustered', + queryLanguages: [ + { name: InfluxVersion.SQL, fields: ['Host', 'Database', 'Token'] }, + { name: InfluxVersion.InfluxQL, fields: ['URL', 'Database', 'Token'] }, + ], + detectionMethod: { + pingHeaderResponse: { + 'x-influxdb-version': '\\s*influxqlbridged-development', + }, + }, + }, + { + name: 'InfluxDB Enterprise 1.x', + queryLanguages: [ + { name: InfluxVersion.InfluxQL, fields: ['URL', 'Database', 'User', 'Password'] }, + { name: InfluxVersion.Flux, fields: ['URL', 'User', 'Password', 'Default database'] }, + ], + detectionMethod: { + pingHeaderResponse: { + 'x-influxdb-build': 'Enterprise (needs confirmation)', + }, + }, + }, + { + name: 'InfluxDB Enterprise 3.x', + queryLanguages: [ + { name: InfluxVersion.SQL, fields: ['URL', 'Token'] }, + { name: InfluxVersion.InfluxQL, fields: ['URL', 'Token'] }, + ], + detectionMethod: { + pingHeaderResponse: { + 'x-influxdb-build': 'TBD', + }, + }, + }, + { + name: 'InfluxDB Cloud (TSM)', + queryLanguages: [ + { name: InfluxVersion.InfluxQL, fields: ['URL', 'Database', 'Token'] }, + { name: InfluxVersion.Flux, fields: ['URL', 'Organization', 'Token', 'Default bucket'] }, + ], + detectionMethod: { + urlContains: [ + 'us-west-2-1.aws.cloud2.influxdata.com', + 'us-west-2-2.aws.cloud2.influxdata.com', + 'us-east-1-1.aws.cloud2.influxdata.com', + 'eu-central-1-1.aws.cloud2.influxdata.com', + 'us-central1-1.gcp.cloud2.influxdata.com', + 'westeurope-1.azure.cloud2.influxdata.com', + 'eastus-1.azure.cloud2.influxdata.com', + ], + }, + }, + { + name: 'InfluxDB Cloud 1', + queryLanguages: [{ name: InfluxVersion.InfluxQL, fields: ['URL', 'Database', 'Username', 'Password'] }], + detectionMethod: { + urlContains: ['influxcloud.net'], + }, + }, + { + name: 'InfluxDB OSS 1.x', + queryLanguages: [ + { name: InfluxVersion.InfluxQL, fields: ['URL', 'Database', 'Username', 'Password'] }, + { name: InfluxVersion.Flux, fields: ['URL', 'Username', 'Password', 'Default database'] }, + ], + detectionMethod: { + pingHeaderResponse: { + 'x-influxdb-build': 'OSS', + 'x-influxdb-version': '^1\\.', + }, + }, + }, + { + name: 'InfluxDB OSS 2.x', + queryLanguages: [ + { + name: InfluxVersion.InfluxQL, + fields: [ + 'URL', + 'Database', + { type: 'Basic', fields: ['Username', 'Password'] }, + { type: 'Token', fields: ['Token'] }, + ], + }, + { name: InfluxVersion.Flux, fields: ['URL', 'Token', 'Default bucket'] }, + ], + detectionMethod: { + pingHeaderResponse: { + 'x-influxdb-build': 'OSS', + 'x-influxdb-version': '^2\\.', + }, + }, + }, +]; diff --git a/public/app/plugins/datasource/influxdb/module.ts b/public/app/plugins/datasource/influxdb/module.ts index f6e46d7d331..99d7b9f7bf1 100644 --- a/public/app/plugins/datasource/influxdb/module.ts +++ b/public/app/plugins/datasource/influxdb/module.ts @@ -1,11 +1,16 @@ import { DataSourcePlugin } from '@grafana/data'; +import { config } from '@grafana/runtime'; -import ConfigEditor from './components/editor/config/ConfigEditor'; +import { ConfigEditor as ConfigEditorV1 } from './components/editor/config/ConfigEditor'; +import { ConfigEditor as ConfigEditorV2 } from './components/editor/config-v2/ConfigEditor'; import { QueryEditor } from './components/editor/query/QueryEditor'; import { InfluxStartPage } from './components/editor/query/influxql/InfluxStartPage'; import InfluxDatasource from './datasource'; +// ConfigEditorV2 is the new design for the InfluxDB configuration page +const configEditor = config.featureToggles.newInfluxDSConfigPageDesign ? ConfigEditorV2 : ConfigEditorV1; + export const plugin = new DataSourcePlugin(InfluxDatasource) - .setConfigEditor(ConfigEditor) + .setConfigEditor(configEditor) .setQueryEditor(QueryEditor) .setQueryEditorHelp(InfluxStartPage); diff --git a/public/app/plugins/datasource/influxdb/types.ts b/public/app/plugins/datasource/influxdb/types.ts index e6940fdfb22..3f0b715b421 100644 --- a/public/app/plugins/datasource/influxdb/types.ts +++ b/public/app/plugins/datasource/influxdb/types.ts @@ -15,6 +15,8 @@ export interface InfluxOptions extends DataSourceJsonData { httpMode?: string; dbName?: string; + product?: string; + pdcInjected?: boolean; // With Flux organization?: string;