diff --git a/public/app/features/plugins/datasource_srv.test.ts b/public/app/features/plugins/datasource_srv.test.ts index 9734aaa9b02..eaa8c15c5f3 100644 --- a/public/app/features/plugins/datasource_srv.test.ts +++ b/public/app/features/plugins/datasource_srv.test.ts @@ -299,6 +299,19 @@ describe('datasource_srv', () => { const settings = dataSourceSrv.getInstanceSettings(runtimeDataSource.name); expect(settings).toBe(undefined); }); + + it('should handle type-only datasource references consistently', async () => { + const typeOnlyRef = { type: 'jaeger-db' }; + + const datasource = await dataSourceSrv.get(typeOnlyRef); + const settings = dataSourceSrv.getInstanceSettings(typeOnlyRef); + + expect(datasource.uid).toBe('uid-code-Jaeger'); + expect(datasource.type).toBe('jaeger-db'); + expect(settings?.uid).toBe(datasource.uid); + expect(settings?.type).toBe(datasource.type); + expect(settings?.name).toBe('Jaeger'); + }); }); describe('when loading datasource', () => { diff --git a/public/app/features/plugins/datasource_srv.ts b/public/app/features/plugins/datasource_srv.ts index a7d081244c6..99dda9e89a1 100644 --- a/public/app/features/plugins/datasource_srv.ts +++ b/public/app/features/plugins/datasource_srv.ts @@ -107,6 +107,14 @@ export class DatasourceSrv implements DataSourceService { } if (nameOrUid === 'default' || nameOrUid == null) { + // Handle type-only datasource references (e.g., {type: 'prometheus'}) + if (isDatasourceRef(ref) && ref.type) { + const ds = this.findDatasourceByType(ref.type); + if (ds) { + return ds; + } + } + // Fall back to default datasource if no type match found return this.settingsMapByUid[this.defaultName] ?? this.settingsMapByName[this.defaultName]; } @@ -143,13 +151,12 @@ export class DatasourceSrv implements DataSourceService { get(ref?: string | DataSourceRef | null, scopedVars?: ScopedVars): Promise { let nameOrUid = getNameOrUid(ref); if (!nameOrUid) { - // type exists, but not the other properties - if (isDatasourceRef(ref)) { - const settings = this.getList({ type: ref.type }); - if (!settings?.length) { + // Handle type-only datasource references + if (isDatasourceRef(ref) && ref.type) { + const ds = this.findDatasourceByType(ref.type); + if (!ds) { return Promise.reject('no datasource of type'); } - const ds = settings.find((v) => v.isDefault) ?? settings[0]; return this.get(ds.uid); } return this.get(this.defaultName); @@ -184,6 +191,18 @@ export class DatasourceSrv implements DataSourceService { return this.loadDatasource(nameOrUid); } + /** + * Finds the best datasource instance settings for a given type. + * Prefers the default datasource of that type, otherwise returns the first one found. + */ + private findDatasourceByType(type: string): DataSourceInstanceSettings | undefined { + const settings = this.getList({ type }); + if (!settings?.length) { + return undefined; + } + return settings.find((v) => v.isDefault) ?? settings[0]; + } + async loadDatasource(key: string): Promise { if (this.datasources[key]) { return Promise.resolve(this.datasources[key]);