123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import $ from 'jquery';
- import _, { isFunction } from 'lodash'; // eslint-disable-line lodash/import-scope
- import moment from 'moment'; // eslint-disable-line no-restricted-imports
- import { AppEvents, dateMath, UrlQueryValue } from '@grafana/data';
- import { getBackendSrv, locationService } from '@grafana/runtime';
- import { backendSrv } from 'app/core/services/backend_srv';
- import impressionSrv from 'app/core/services/impression_srv';
- import kbn from 'app/core/utils/kbn';
- import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
- import { appEvents } from '../../../core/core';
- import { getDashboardSrv } from './DashboardSrv';
- export class DashboardLoaderSrv {
- constructor() {}
- _dashboardLoadFailed(title: string, snapshot?: boolean) {
- snapshot = snapshot || false;
- return {
- meta: {
- canStar: false,
- isSnapshot: snapshot,
- canDelete: false,
- canSave: false,
- canEdit: false,
- dashboardNotFound: true,
- },
- dashboard: { title },
- };
- }
- loadDashboard(type: UrlQueryValue, slug: any, uid: any) {
- let promise;
- if (type === 'script') {
- promise = this._loadScriptedDashboard(slug);
- } else if (type === 'snapshot') {
- promise = backendSrv.get('/api/snapshots/' + slug).catch(() => {
- return this._dashboardLoadFailed('Snapshot not found', true);
- });
- } else if (type === 'ds') {
- promise = this._loadFromDatasource(slug); // explore dashboards as code
- } else {
- promise = backendSrv
- .getDashboardByUid(uid)
- .then((result: any) => {
- if (result.meta.isFolder) {
- appEvents.emit(AppEvents.alertError, ['Dashboard not found']);
- throw new Error('Dashboard not found');
- }
- return result;
- })
- .catch(() => {
- return this._dashboardLoadFailed('Not found', true);
- });
- }
- promise.then((result: any) => {
- if (result.meta.dashboardNotFound !== true) {
- impressionSrv.addDashboardImpression(result.dashboard.id);
- }
- return result;
- });
- return promise;
- }
- _loadScriptedDashboard(file: string) {
- const url = 'public/dashboards/' + file.replace(/\.(?!js)/, '/') + '?' + new Date().getTime();
- return getBackendSrv()
- .get(url)
- .then(this._executeScript.bind(this))
- .then(
- (result: any) => {
- return {
- meta: {
- fromScript: true,
- canDelete: false,
- canSave: false,
- canStar: false,
- },
- dashboard: result.data,
- };
- },
- (err: any) => {
- console.error('Script dashboard error ' + err);
- appEvents.emit(AppEvents.alertError, [
- 'Script Error',
- 'Please make sure it exists and returns a valid dashboard',
- ]);
- return this._dashboardLoadFailed('Scripted dashboard');
- }
- );
- }
- /**
- * This is a temporary solution to load dashboards dynamically from a datasource
- * Eventually this should become a plugin type or a special handler in the dashboard
- * loading code
- */
- async _loadFromDatasource(dsid: string) {
- const ds = await getDatasourceSrv().get(dsid);
- if (!ds) {
- return Promise.reject('can not find datasource: ' + dsid);
- }
- const params = new URLSearchParams(window.location.search);
- const path = params.get('path');
- if (!path) {
- return Promise.reject('expecting path parameter');
- }
- const queryParams: { [key: string]: any } = {};
- params.forEach((value, key) => {
- queryParams[key] = value;
- });
- return getBackendSrv()
- .get(`/api/datasources/${ds.id}/resources/${path}`, queryParams)
- .then((data) => {
- return {
- meta: {
- fromScript: true,
- canDelete: false,
- canSave: false,
- canStar: false,
- },
- dashboard: data,
- };
- });
- }
- _executeScript(result: any) {
- const services = {
- dashboardSrv: getDashboardSrv(),
- datasourceSrv: getDatasourceSrv(),
- };
- const scriptFunc = new Function(
- 'ARGS',
- 'kbn',
- 'dateMath',
- '_',
- 'moment',
- 'window',
- 'document',
- '$',
- 'jQuery',
- 'services',
- result
- );
- const scriptResult = scriptFunc(
- locationService.getSearchObject(),
- kbn,
- dateMath,
- _,
- moment,
- window,
- document,
- $,
- $,
- services
- );
- // Handle async dashboard scripts
- if (isFunction(scriptResult)) {
- return new Promise((resolve) => {
- scriptResult((dashboard: any) => {
- resolve({ data: dashboard });
- });
- });
- }
- return { data: scriptResult };
- }
- }
- let dashboardLoaderSrv = new DashboardLoaderSrv();
- export { dashboardLoaderSrv };
- /** @internal
- * Used for tests only
- */
- export const setDashboardLoaderSrv = (srv: DashboardLoaderSrv) => {
- if (process.env.NODE_ENV !== 'test') {
- throw new Error('dashboardLoaderSrv can be only overriden in test environment');
- }
- dashboardLoaderSrv = srv;
- };
|