dashboard_loader_srv.ts 3.5 KB

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