DashboardLoaderSrv.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* tslint:disable:import-blacklist */
  2. import angular, { IQService } from 'angular';
  3. import moment from 'moment';
  4. import _ from 'lodash';
  5. import $ from 'jquery';
  6. import kbn from 'app/core/utils/kbn';
  7. import { dateMath } from '@grafana/data';
  8. import impressionSrv from 'app/core/services/impression_srv';
  9. import { BackendSrv } from 'app/core/services/backend_srv';
  10. import { DashboardSrv } from './DashboardSrv';
  11. import DatasourceSrv from 'app/features/plugins/datasource_srv';
  12. import { UrlQueryValue } from '@grafana/runtime';
  13. export class DashboardLoaderSrv {
  14. /** @ngInject */
  15. constructor(
  16. private backendSrv: BackendSrv,
  17. private dashboardSrv: DashboardSrv,
  18. private datasourceSrv: DatasourceSrv,
  19. private $http: any,
  20. private $q: IQService,
  21. private $timeout: any,
  22. contextSrv: any,
  23. private $routeParams: any,
  24. private $rootScope: any
  25. ) {}
  26. _dashboardLoadFailed(title: string, snapshot?: boolean) {
  27. snapshot = snapshot || false;
  28. return {
  29. meta: {
  30. canStar: false,
  31. isSnapshot: snapshot,
  32. canDelete: false,
  33. canSave: false,
  34. canEdit: false,
  35. dashboardNotFound: true,
  36. },
  37. dashboard: { title },
  38. };
  39. }
  40. loadDashboard(type: UrlQueryValue, slug: any, uid: any) {
  41. let promise;
  42. if (type === 'script') {
  43. promise = this._loadScriptedDashboard(slug);
  44. } else if (type === 'snapshot') {
  45. promise = this.backendSrv.get('/api/snapshots/' + slug).catch(() => {
  46. return this._dashboardLoadFailed('Snapshot not found', true);
  47. });
  48. } else {
  49. promise = this.backendSrv
  50. .getDashboardByUid(uid)
  51. .then((result: any) => {
  52. if (result.meta.isFolder) {
  53. this.$rootScope.appEvent('alert-error', ['Dashboard not found']);
  54. throw new Error('Dashboard not found');
  55. }
  56. return result;
  57. })
  58. .catch(() => {
  59. return this._dashboardLoadFailed('Not found', true);
  60. });
  61. }
  62. promise.then((result: any) => {
  63. if (result.meta.dashboardNotFound !== true) {
  64. impressionSrv.addDashboardImpression(result.dashboard.id);
  65. }
  66. return result;
  67. });
  68. return promise;
  69. }
  70. _loadScriptedDashboard(file: string) {
  71. const url = 'public/dashboards/' + file.replace(/\.(?!js)/, '/') + '?' + new Date().getTime();
  72. return this.$http({ url: url, method: 'GET' })
  73. .then(this._executeScript.bind(this))
  74. .then(
  75. (result: any) => {
  76. return {
  77. meta: {
  78. fromScript: true,
  79. canDelete: false,
  80. canSave: false,
  81. canStar: false,
  82. },
  83. dashboard: result.data,
  84. };
  85. },
  86. (err: any) => {
  87. console.log('Script dashboard error ' + err);
  88. this.$rootScope.appEvent('alert-error', [
  89. 'Script Error',
  90. 'Please make sure it exists and returns a valid dashboard',
  91. ]);
  92. return this._dashboardLoadFailed('Scripted dashboard');
  93. }
  94. );
  95. }
  96. _executeScript(result: any) {
  97. const services = {
  98. dashboardSrv: this.dashboardSrv,
  99. datasourceSrv: this.datasourceSrv,
  100. $q: this.$q,
  101. };
  102. /*jshint -W054 */
  103. const scriptFunc = new Function(
  104. 'ARGS',
  105. 'kbn',
  106. 'dateMath',
  107. '_',
  108. 'moment',
  109. 'window',
  110. 'document',
  111. '$',
  112. 'jQuery',
  113. 'services',
  114. result.data
  115. );
  116. const scriptResult = scriptFunc(this.$routeParams, kbn, dateMath, _, moment, window, document, $, $, services);
  117. // Handle async dashboard scripts
  118. if (_.isFunction(scriptResult)) {
  119. const deferred = this.$q.defer();
  120. scriptResult((dashboard: any) => {
  121. this.$timeout(() => {
  122. deferred.resolve({ data: dashboard });
  123. });
  124. });
  125. return deferred.promise;
  126. }
  127. return { data: scriptResult };
  128. }
  129. }
  130. angular.module('grafana.services').service('dashboardLoaderSrv', DashboardLoaderSrv);