DashboardLoaderSrv.ts 3.5 KB

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