Skip to content

Commit

Permalink
feat(tag): Workspace variable resolution (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
cameronwaterman authored Oct 5, 2023
1 parent 335fb5f commit f4fe35a
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 8 deletions.
14 changes: 12 additions & 2 deletions src/core/DataSourceBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ import {
DataSourceApi,
DataSourceInstanceSettings,
} from '@grafana/data';
import { BackendSrv, BackendSrvRequest, TestingStatus, isFetchError } from '@grafana/runtime';
import {
BackendSrv,
BackendSrvRequest,
TemplateSrv,
TestingStatus,
isFetchError
} from '@grafana/runtime';
import { DataQuery } from '@grafana/schema';
import { Workspace } from './types';
import { sleep } from './utils';
import { lastValueFrom } from 'rxjs';

export abstract class DataSourceBase<TQuery extends DataQuery> extends DataSourceApi<TQuery> {
constructor(readonly instanceSettings: DataSourceInstanceSettings, readonly backendSrv: BackendSrv) {
constructor(
readonly instanceSettings: DataSourceInstanceSettings,
readonly backendSrv: BackendSrv,
readonly templateSrv: TemplateSrv
) {
super(instanceSettings);
}

Expand Down
11 changes: 10 additions & 1 deletion src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,19 @@ export function throwIfNullish<T>(value: T, error: string | Error): NonNullable<
export function useWorkspaceOptions<DSType extends DataSourceBase<any>>(datasource: DSType) {
return useAsync(async () => {
const workspaces = await datasource.getWorkspaces();
return workspaces.map(w => ({ label: w.name, value: w.id }));
const workspaceOptions = workspaces.map(w => ({ label: w.name, value: w.id }));
workspaceOptions?.unshift(...getVariableOptions(datasource))
return workspaceOptions;
});
}

/** Gets Dashboard variables as an array of {@link SelectableValue}. */
export function getVariableOptions<DSType extends DataSourceBase<any>>(datasource: DSType) {
return datasource.templateSrv
.getVariables()
.map((variable) => ({ label: '$' + variable.name, value: '$' + variable.name }));
}

export function getWorkspaceName(workspaces: Workspace[], id: string) {
return workspaces.find(w => w.id === id)?.name ?? id;
}
Expand Down
2 changes: 1 addition & 1 deletion src/datasources/data-frame/DataFrameDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class DataFrameDataSource extends DataSourceBase<DataFrameQuery> {
readonly backendSrv: BackendSrv = getBackendSrv(),
readonly templateSrv: TemplateSrv = getTemplateSrv()
) {
super(instanceSettings, backendSrv);
super(instanceSettings, backendSrv, templateSrv);
}

baseUrl = this.instanceSettings.url + '/nidataframe/v1';
Expand Down
2 changes: 1 addition & 1 deletion src/datasources/system/SystemDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class SystemDataSource extends DataSourceBase<SystemQuery> {
readonly backendSrv: BackendSrv = getBackendSrv(),
readonly templateSrv: TemplateSrv = getTemplateSrv()
) {
super(instanceSettings, backendSrv);
super(instanceSettings, backendSrv, templateSrv);
}

baseUrl = this.instanceSettings.url + '/nisysmgmt/v1';
Expand Down
11 changes: 11 additions & 0 deletions src/datasources/tag/TagDataSource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,17 @@ describe('queries', () => {

expect(backendSrv.fetch).toHaveBeenCalledTimes(5);
});

test('attempts to replace variables in history query', async () => {
const workspaceVariable = '$workspace';
backendSrv.fetch.mockReturnValueOnce(createQueryTagsResponse());
templateSrv.replace.calledWith(workspaceVariable).mockReturnValue('1');

await ds.query(buildQuery({ path: 'my.tag', workspace: workspaceVariable }));

expect(templateSrv.replace).toHaveBeenCalledTimes(2);
expect(templateSrv.replace.mock.calls[1][0]).toBe(workspaceVariable);
});
});

function createQueryTagsResponse(
Expand Down
4 changes: 2 additions & 2 deletions src/datasources/tag/TagDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class TagDataSource extends DataSourceBase<TagQuery> {
readonly backendSrv: BackendSrv = getBackendSrv(),
readonly templateSrv: TemplateSrv = getTemplateSrv()
) {
super(instanceSettings, backendSrv);
super(instanceSettings, backendSrv, templateSrv);
}

tagUrl = this.instanceSettings.url + '/nitag/v2';
Expand All @@ -25,7 +25,7 @@ export class TagDataSource extends DataSourceBase<TagQuery> {
async runQuery(query: TagQuery, { range, maxDataPoints, scopedVars }: DataQueryRequest): Promise<DataFrameDTO> {
const { tag, current } = await this.getLastUpdatedTag(
this.templateSrv.replace(query.path, scopedVars),
query.workspace
this.templateSrv.replace(query.workspace, scopedVars)
);

const name = tag.properties?.displayName ?? tag.path;
Expand Down
2 changes: 1 addition & 1 deletion src/datasources/workspace/WorkspaceDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class WorkspaceDataSource extends DataSourceBase<WorkspaceQuery> {
readonly backendSrv: BackendSrv = getBackendSrv(),
readonly templateSrv: TemplateSrv = getTemplateSrv()
) {
super(instanceSettings, backendSrv);
super(instanceSettings, backendSrv, templateSrv);
}

baseUrl = this.instanceSettings.url + '/niuser/v1';
Expand Down
1 change: 1 addition & 0 deletions src/test/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function setupDataSource<T>(
);
const mockTemplateSrv = mock<TemplateSrv>({
replace: calledWithFn({ fallbackMockImplementation: target => target ?? '' }),
getVariables: calledWithFn({ fallbackMockImplementation: () => [] })
});
const ds = new ctor({ url: '' } as DataSourceInstanceSettings, mockBackendSrv, mockTemplateSrv);
return [ds, mockBackendSrv, mockTemplateSrv] as const;
Expand Down

0 comments on commit f4fe35a

Please sign in to comment.