From 829672759c12b27f849c92c3a2aee4a6b0037920 Mon Sep 17 00:00:00 2001 From: Nathan Marrs Date: Thu, 8 Feb 2024 15:00:48 -0700 Subject: [PATCH] Deprecation: Create explicit feature toggle to auto-migrate from graph panel (#79369) --- .../dev-dashboards/migrations/migrations.json | 30 ++++++++++++++-- .../feature-toggles/index.md | 1 + e2e/various-suite/graph-auto-migrate.spec.ts | 36 +++++++++++++++++-- .../src/types/featureToggles.gen.ts | 1 + pkg/services/featuremgmt/registry.go | 8 +++++ pkg/services/featuremgmt/toggles_gen.csv | 1 + pkg/services/featuremgmt/toggles_gen.go | 4 +++ .../dashboard/state/DashboardModel.ts | 23 +++++++++++- .../features/dashboard/state/PanelModel.ts | 2 ++ 9 files changed, 100 insertions(+), 6 deletions(-) diff --git a/devenv/dev-dashboards/migrations/migrations.json b/devenv/dev-dashboards/migrations/migrations.json index e39a6bd83a7..9b75a6d8345 100644 --- a/devenv/dev-dashboards/migrations/migrations.json +++ b/devenv/dev-dashboards/migrations/migrations.json @@ -21,7 +21,31 @@ "links": [ { "asDropdown": false, - "icon": "dashboard", + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", "includeVars": false, "keepTime": false, "tags": [], @@ -45,7 +69,7 @@ }, { "asDropdown": false, - "icon": "dashboard", + "icon": "external link", "includeVars": false, "keepTime": false, "tags": [], @@ -198,7 +222,7 @@ "sort": 0, "value_type": "individual" }, - "type": "timeseries", + "type": "graph", "xaxis": { "mode": "time", "show": true, diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 5478de1aabd..d55ddae6997 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -64,6 +64,7 @@ Some features are enabled by default. You can disable these feature by setting t | `panelTitleSearch` | Search for dashboards using panel title | | `migrationLocking` | Lock database during migrations | | `autoMigrateOldPanels` | Migrate old angular panels to supported versions (graph, table-old, worldmap, etc) | +| `autoMigrateGraphPanel` | Migrate old graph panel to supported time series panel - broken out from autoMigrateOldPanels to enable granular tracking | | `disableAngular` | Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime. | | `newVizTooltips` | New visualizations tooltips UX | | `grpcServer` | Run the GRPC server | diff --git a/e2e/various-suite/graph-auto-migrate.spec.ts b/e2e/various-suite/graph-auto-migrate.spec.ts index 2889eae6382..eedb7a043e6 100644 --- a/e2e/various-suite/graph-auto-migrate.spec.ts +++ b/e2e/various-suite/graph-auto-migrate.spec.ts @@ -1,18 +1,50 @@ import { e2e } from '../utils'; + const DASHBOARD_ID = 'XMjIZPmik'; const DASHBOARD_NAME = 'Panel Tests - Graph Time Regions'; +const UPLOT_MAIN_DIV_SELECTOR = '[data-testid="uplot-main-div"]'; describe('Auto-migrate graph panel', () => { beforeEach(() => { e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); }); + it('Graph panel is migrated with `autoMigrateOldPanels` feature toggle', () => { + e2e.flows.openDashboard({ uid: DASHBOARD_ID }); + cy.contains(DASHBOARD_NAME).should('be.visible'); + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('not.exist'); + + e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.autoMigrateOldPanels': true } }); + + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('exist'); + }); + + it('Graph panel is migrated with config `disableAngular` feature toggle', () => { + e2e.flows.openDashboard({ uid: DASHBOARD_ID }); + cy.contains(DASHBOARD_NAME).should('be.visible'); + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('not.exist'); + + e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.disableAngular': true } }); + + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('exist'); + }); + + it('Graph panel is migrated with `autoMigrateGraphPanel` feature toggle', () => { + e2e.flows.openDashboard({ uid: DASHBOARD_ID }); + cy.contains(DASHBOARD_NAME).should('be.visible'); + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('not.exist'); + + e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.autoMigrateGraphPanel': true } }); + + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('exist'); + }); + it('Annotation markers exist for time regions', () => { e2e.flows.openDashboard({ uid: DASHBOARD_ID }); cy.contains(DASHBOARD_NAME).should('be.visible'); - cy.contains('uplot-main-div').should('not.exist'); + cy.get(UPLOT_MAIN_DIV_SELECTOR).should('not.exist'); - e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.autoMigrateOldPanels': true } }); + e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { '__feature.autoMigrateGraphPanel': true } }); e2e.components.Panels.Panel.title('Business Hours') .should('exist') diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 31c426f63e5..90dfc96b506 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -33,6 +33,7 @@ export interface FeatureToggles { datasourceQueryMultiStatus?: boolean; traceToMetrics?: boolean; autoMigrateOldPanels?: boolean; + autoMigrateGraphPanel?: boolean; disableAngular?: boolean; canvasPanelNesting?: boolean; newVizTooltips?: boolean; diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index c031115d7db..97b62d848ee 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -134,6 +134,14 @@ var ( Owner: grafanaDatavizSquad, Created: time.Date(2022, time.June, 11, 12, 0, 0, 0, time.UTC), }, + { + Name: "autoMigrateGraphPanel", + Description: "Migrate old graph panel to supported time series panel - broken out from autoMigrateOldPanels to enable granular tracking", + Stage: FeatureStagePublicPreview, + FrontendOnly: true, + Owner: grafanaDatavizSquad, + Created: time.Date(2023, time.December, 11, 7, 0, 0, 0, time.UTC), + }, { Name: "disableAngular", Description: "Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime.", diff --git a/pkg/services/featuremgmt/toggles_gen.csv b/pkg/services/featuremgmt/toggles_gen.csv index c5361edf388..40fdc057987 100644 --- a/pkg/services/featuremgmt/toggles_gen.csv +++ b/pkg/services/featuremgmt/toggles_gen.csv @@ -14,6 +14,7 @@ exploreContentOutline,GA,@grafana/explore-squad,2023-11-03,false,false,true datasourceQueryMultiStatus,experimental,@grafana/plugins-platform-backend,2022-05-03,false,false,false traceToMetrics,experimental,@grafana/observability-traces-and-profiling,2022-03-07,false,false,true autoMigrateOldPanels,preview,@grafana/dataviz-squad,2022-06-11,false,false,true +autoMigrateGraphPanel,preview,@grafana/dataviz-squad,2023-12-11,false,false,true disableAngular,preview,@grafana/dataviz-squad,2023-03-23,false,false,true canvasPanelNesting,experimental,@grafana/dataviz-squad,2022-05-31,false,false,true newVizTooltips,preview,@grafana/dataviz-squad,2023-11-03,false,false,true diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index 1c3b7444e48..5be1a1a1cc7 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -67,6 +67,10 @@ const ( // Migrate old angular panels to supported versions (graph, table-old, worldmap, etc) FlagAutoMigrateOldPanels = "autoMigrateOldPanels" + // FlagAutoMigrateGraphPanel + // Migrate old graph panel to supported time series panel - broken out from autoMigrateOldPanels to enable granular tracking + FlagAutoMigrateGraphPanel = "autoMigrateGraphPanel" + // FlagDisableAngular // Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime. FlagDisableAngular = "disableAngular" diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index 360c89791bf..1e937d035ce 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -44,7 +44,7 @@ import { getTimeSrv } from '../services/TimeSrv'; import { mergePanels, PanelMergeInfo } from '../utils/panelMerge'; import { DashboardMigrator } from './DashboardMigrator'; -import { PanelModel, autoMigrateAngular } from './PanelModel'; +import { PanelModel, autoMigrateAngular, explicitlyControlledMigrationPanels } from './PanelModel'; import { TimeModel } from './TimeModel'; import { deleteScopeVars, isOnTheSameGridRow } from './utils'; @@ -173,6 +173,12 @@ export class DashboardModel implements TimeModel { if (options?.autoMigrateOldPanels || !config.angularSupportEnabled || config.featureToggles.autoMigrateOldPanels) { for (const p of this.panelIterator()) { const newType = autoMigrateAngular[p.type]; + + // Skip explicitly controlled panels + if (explicitlyControlledMigrationPanels.includes(p.type)) { + continue; + } + if (!p.autoMigrateFrom && newType) { p.autoMigrateFrom = p.type; p.type = newType; @@ -180,6 +186,21 @@ export class DashboardModel implements TimeModel { } } + // Explicit handling of graph -> time series migration (and eventually others) + if ( + options?.autoMigrateOldPanels || + !config.angularSupportEnabled || + config.featureToggles.autoMigrateOldPanels || + config.featureToggles.autoMigrateGraphPanel + ) { + for (const p of this.panelIterator()) { + if (!p.autoMigrateFrom && p.type === 'graph') { + p.autoMigrateFrom = p.type; + p.type = 'timeseries'; + } + } + } + this.addBuiltInAnnotationQuery(); this.sortPanelsByGridPos(); this.panelsAffectedByVariableChange = null; diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index be6821aabe3..447cce8518e 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -130,6 +130,8 @@ const defaults: any = { title: '', }; +export const explicitlyControlledMigrationPanels = ['graph']; + export const autoMigrateAngular: Record = { graph: 'timeseries', 'table-old': 'table',