diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.test.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.test.ts index 00347fdf677..c6e0d9b26ee 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.test.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.test.ts @@ -56,6 +56,7 @@ import { getElementDatasource, transformSceneToSaveModelSchemaV2, validateDashboardSchemaV2, + getDataQueryKind, } from './transformSceneToSaveModelSchemaV2'; // Mock dependencies @@ -113,7 +114,14 @@ jest.mock('@grafana/runtime', () => ({ }, loki: { name: 'Loki', - meta: { id: 'loki' }, + meta: { + id: 'loki', + name: 'Loki', + type: 'datasource', + info: { version: '1.0.0' }, + module: 'app/plugins/datasource/loki/module', + baseUrl: '/plugins/loki', + }, type: 'datasource', }, }, @@ -498,6 +506,59 @@ describe('transformSceneToSaveModelSchemaV2', () => { expect(resultC).toEqual({}); }); }); + + describe('getDataQueryKind', () => { + it('should preserve original query datasource type when available', () => { + // 1. Test with a query that has its own datasource type + const queryWithDS: SceneDataQuery = { + refId: 'A', + datasource: { uid: 'prometheus-1', type: 'prometheus' }, + }; + + // Create a query runner with a different datasource type + const queryRunner = new SceneQueryRunner({ + datasource: { uid: 'default-ds', type: 'loki' }, + queries: [], + }); + + // Should use the query's own datasource type (prometheus) + expect(getDataQueryKind(queryWithDS, queryRunner)).toBe('prometheus'); + }); + + it('should use queryRunner datasource type as fallback when query has no datasource', () => { + // 2. Test with a query that has no datasource + const queryWithoutDS: SceneDataQuery = { + refId: 'A', + }; + + // Create a query runner with a datasource + const queryRunner = new SceneQueryRunner({ + datasource: { uid: 'influxdb-1', type: 'influxdb' }, + queries: [], + }); + + // Should fall back to queryRunner's datasource type + expect(getDataQueryKind(queryWithoutDS, queryRunner)).toBe('influxdb'); + }); + + it('should fall back to default datasource when neither query nor queryRunner has datasource type', () => { + // 3. Test with neither query nor queryRunner having a datasource type + const queryWithoutDS: SceneDataQuery = { + refId: 'A', + }; + + // Create a query runner with no datasource + const queryRunner = new SceneQueryRunner({ + queries: [], + }); + + expect(getDataQueryKind(queryWithoutDS, queryRunner)).toBe('loki'); + + // Also verify the function's behavior by checking the args + expect(queryWithoutDS.datasource?.type).toBeUndefined(); // No query datasource + expect(queryRunner.state.datasource?.type).toBeUndefined(); // No queryRunner datasource + }); + }); }); describe('getElementDatasource', () => { diff --git a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts index 018d71e0775..4a9b025388a 100644 --- a/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts +++ b/public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts @@ -254,7 +254,7 @@ function getVizPanelQueries(vizPanel: VizPanel, dsReferencesMapping?: DSReferenc vizPanelQueries.forEach((query) => { const queryDatasource = getElementDatasource(vizPanel, query, 'panel', queryRunner, dsReferencesMapping); const dataQuery: DataQueryKind = { - kind: getDataQueryKind(query), + kind: getDataQueryKind(query, queryRunner), spec: omit(query, 'datasource', 'refId', 'hide'), }; const querySpec: PanelQuerySpec = { @@ -272,12 +272,26 @@ function getVizPanelQueries(vizPanel: VizPanel, dsReferencesMapping?: DSReferenc return queries; } -export function getDataQueryKind(query: SceneDataQuery | string): string { +export function getDataQueryKind(query: SceneDataQuery | string, queryRunner?: SceneQueryRunner): string { + // Query is a string - get default data source type if (typeof query === 'string') { - return getDefaultDataSourceRef()?.type ?? ''; + const defaultDS = getDefaultDataSourceRef(); + return defaultDS?.type || ''; } - return query.datasource?.type ?? getDefaultDataSourceRef()?.type ?? ''; + // Query has explicit datasource with type + if (query.datasource?.type) { + return query.datasource.type; + } + + // Get type from query runner's datasource + if (queryRunner?.state.datasource?.type) { + return queryRunner.state.datasource.type; + } + + // Fall back to default datasource + const defaultDS = getDefaultDataSourceRef(); + return defaultDS?.type || ''; } export function getDataQuerySpec(query: SceneDataQuery): DataQueryKind['spec'] { diff --git a/public/app/features/dashboard-scene/v2schema/SchemaV2EditorDrawer.tsx b/public/app/features/dashboard-scene/v2schema/SchemaV2EditorDrawer.tsx index 57402e69db6..fc98332d98d 100644 --- a/public/app/features/dashboard-scene/v2schema/SchemaV2EditorDrawer.tsx +++ b/public/app/features/dashboard-scene/v2schema/SchemaV2EditorDrawer.tsx @@ -74,7 +74,7 @@ export class SchemaV2EditorDrawer extends SceneObjectBase {renderBody()}