D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
usr
/
share
/
grafana
/
public
/
app
/
features
/
dashboard
/
services
/
Filename :
PublicDashboardDataSource.ts
back
Copy
import { catchError, from, Observable, of, switchMap } from 'rxjs'; import { AnnotationQuery, DataQuery, DataQueryRequest, DataQueryResponse, TestDataSourceResponse, DataSourceApi, DataSourceJsonData, DataSourcePluginMeta, DataSourceRef, toDataFrame, } from '@grafana/data'; import { BackendDataSourceResponse, getBackendSrv, toDataQueryResponse } from '@grafana/runtime'; import { GrafanaQueryType } from '../../../plugins/datasource/grafana/types'; import { MIXED_DATASOURCE_NAME } from '../../../plugins/datasource/mixed/MixedDataSource'; import { GRAFANA_DATASOURCE_NAME } from '../../alerting/unified/utils/datasource'; export const PUBLIC_DATASOURCE = '-- Public --'; export const DEFAULT_INTERVAL = '1min'; export class PublicDashboardDataSource extends DataSourceApi<DataQuery, DataSourceJsonData, {}> { constructor(datasource: DataSourceRef | string | DataSourceApi | null) { let meta = {} as DataSourcePluginMeta; if (PublicDashboardDataSource.isMixedDatasource(datasource)) { meta.mixed = true; } super({ name: 'public-ds', id: 0, type: 'public-ds', meta, uid: PublicDashboardDataSource.resolveUid(datasource), jsonData: {}, access: 'proxy', readOnly: true, }); this.interval = PublicDashboardDataSource.resolveInterval(datasource); this.annotations = { prepareQuery(anno: AnnotationQuery): DataQuery | undefined { return { ...anno, queryType: GrafanaQueryType.Annotations, refId: 'anno' }; }, }; } /** * Get the datasource uid based on the many types a datasource can be. */ private static resolveUid(datasource: DataSourceRef | string | DataSourceApi | null): string { if (typeof datasource === 'string') { return datasource; } return datasource?.uid ?? PUBLIC_DATASOURCE; } private static isMixedDatasource(datasource: DataSourceRef | string | DataSourceApi | null): boolean { if (typeof datasource === 'string' || datasource == null) { return false; } return datasource?.uid === MIXED_DATASOURCE_NAME; } private static resolveInterval(datasource: DataSourceRef | string | DataSourceApi | null): string { if (typeof datasource === 'string' || datasource == null) { return DEFAULT_INTERVAL; } const interval = 'interval' in datasource ? datasource.interval : undefined; return interval ?? DEFAULT_INTERVAL; } /** * Ideally final -- any other implementation may not work as expected */ query(request: DataQueryRequest<DataQuery>): Observable<DataQueryResponse> { const { intervalMs, maxDataPoints, requestId, publicDashboardAccessToken, panelId, queryCachingTTL, range: { from: fromRange, to: toRange }, } = request; let queries: DataQuery[]; // Return early if no queries exist if (!request.targets.length) { return of({ data: [] }); } // Its an annotations query // Currently, annotations requests come in one at a time, so there will only be one target const target = request.targets[0]; if (target.queryType === GrafanaQueryType.Annotations) { if (target?.datasource?.uid === GRAFANA_DATASOURCE_NAME) { return from(this.getAnnotations(request)); } return of({ data: [] }); } // Its a datasource query else { const body = { intervalMs, maxDataPoints, queryCachingTTL, timeRange: { from: fromRange.valueOf().toString(), to: toRange.valueOf().toString(), timezone: this.getBrowserTimezone(), }, }; return getBackendSrv() .fetch<BackendDataSourceResponse>({ url: `/api/public/dashboards/${publicDashboardAccessToken}/panels/${panelId}/query`, method: 'POST', data: body, requestId, }) .pipe( switchMap((raw) => { return of(toDataQueryResponse(raw, queries)); }), catchError((err) => { return of(toDataQueryResponse(err)); }) ); } } async getAnnotations(request: DataQueryRequest<DataQuery>): Promise<DataQueryResponse> { const { publicDashboardAccessToken: accessToken, range: { to, from }, } = request; const params = { from: from.valueOf(), to: to.valueOf(), }; const annotations = accessToken ? await getBackendSrv().get(`/api/public/dashboards/${accessToken}/annotations`, params) : []; return { data: [toDataFrame(annotations)] }; } testDatasource(): Promise<TestDataSourceResponse> { return Promise.resolve({ message: '', status: '' }); } // Try to get the browser timezone otherwise return blank getBrowserTimezone(): string { return window.Intl?.DateTimeFormat().resolvedOptions()?.timeZone || ''; } }