dashboard_ctrl.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Utils
  2. import config from 'app/core/config';
  3. import appEvents from 'app/core/app_events';
  4. import coreModule from 'app/core/core_module';
  5. // Services
  6. import { AnnotationsSrv } from '../annotations/annotations_srv';
  7. // Types
  8. import { DashboardModel } from './dashboard_model';
  9. import { PanelModel } from './panel_model';
  10. export class DashboardCtrl {
  11. dashboard: DashboardModel;
  12. dashboardViewState: any;
  13. loadedFallbackDashboard: boolean;
  14. editTab: number;
  15. /** @ngInject */
  16. constructor(
  17. private $scope,
  18. private $rootScope,
  19. private keybindingSrv,
  20. private timeSrv,
  21. private variableSrv,
  22. private alertingSrv,
  23. private dashboardSrv,
  24. private unsavedChangesSrv,
  25. private dashboardViewStateSrv,
  26. private annotationsSrv: AnnotationsSrv,
  27. public playlistSrv
  28. ) {
  29. // temp hack due to way dashboards are loaded
  30. // can't use controllerAs on route yet
  31. $scope.ctrl = this;
  32. // TODO: break out settings view to separate view & controller
  33. this.editTab = 0;
  34. // funcs called from React component bindings and needs this binding
  35. this.getPanelContainer = this.getPanelContainer.bind(this);
  36. }
  37. setupDashboard(data) {
  38. try {
  39. this.setupDashboardInternal(data);
  40. } catch (err) {
  41. this.onInitFailed(err, 'Dashboard init failed', true);
  42. }
  43. }
  44. setupDashboardInternal(data) {
  45. const dashboard = this.dashboardSrv.create(data.dashboard, data.meta);
  46. this.dashboardSrv.setCurrent(dashboard);
  47. // init services
  48. this.timeSrv.init(dashboard);
  49. this.alertingSrv.init(dashboard, data.alerts);
  50. this.annotationsSrv.init(dashboard);
  51. // template values service needs to initialize completely before
  52. // the rest of the dashboard can load
  53. this.variableSrv
  54. .init(dashboard)
  55. // template values failes are non fatal
  56. .catch(this.onInitFailed.bind(this, 'Templating init failed', false))
  57. // continue
  58. .finally(() => {
  59. this.dashboard = dashboard;
  60. this.dashboard.processRepeats();
  61. this.dashboard.updateSubmenuVisibility();
  62. this.dashboard.autoFitPanels(window.innerHeight);
  63. this.unsavedChangesSrv.init(dashboard, this.$scope);
  64. // TODO refactor ViewStateSrv
  65. this.$scope.dashboard = dashboard;
  66. this.dashboardViewState = this.dashboardViewStateSrv.create(this.$scope);
  67. this.keybindingSrv.setupDashboardBindings(this.$scope, dashboard);
  68. this.setWindowTitleAndTheme();
  69. appEvents.emit('dashboard-initialized', dashboard);
  70. })
  71. .catch(this.onInitFailed.bind(this, 'Dashboard init failed', true));
  72. }
  73. onInitFailed(msg, fatal, err) {
  74. console.log(msg, err);
  75. if (err.data && err.data.message) {
  76. err.message = err.data.message;
  77. } else if (!err.message) {
  78. err = { message: err.toString() };
  79. }
  80. this.$scope.appEvent('alert-error', [msg, err.message]);
  81. // protect against recursive fallbacks
  82. if (fatal && !this.loadedFallbackDashboard) {
  83. this.loadedFallbackDashboard = true;
  84. this.setupDashboard({ dashboard: { title: 'Dashboard Init failed' } });
  85. }
  86. }
  87. templateVariableUpdated() {
  88. this.dashboard.processRepeats();
  89. }
  90. setWindowTitleAndTheme() {
  91. window.document.title = config.windowTitlePrefix + this.dashboard.title;
  92. }
  93. showJsonEditor(evt, options) {
  94. const editScope = this.$rootScope.$new();
  95. editScope.object = options.object;
  96. editScope.updateHandler = options.updateHandler;
  97. this.$scope.appEvent('show-dash-editor', {
  98. src: 'public/app/partials/edit_json.html',
  99. scope: editScope,
  100. });
  101. }
  102. getDashboard() {
  103. return this.dashboard;
  104. }
  105. getPanelContainer() {
  106. return this;
  107. }
  108. onRemovingPanel(evt, options) {
  109. options = options || {};
  110. if (!options.panelId) {
  111. return;
  112. }
  113. const panelInfo = this.dashboard.getPanelInfoById(options.panelId);
  114. this.removePanel(panelInfo.panel, true);
  115. }
  116. removePanel(panel: PanelModel, ask: boolean) {
  117. // confirm deletion
  118. if (ask !== false) {
  119. let text2, confirmText;
  120. if (panel.alert) {
  121. text2 = 'Panel includes an alert rule, removing panel will also remove alert rule';
  122. confirmText = 'YES';
  123. }
  124. this.$scope.appEvent('confirm-modal', {
  125. title: 'Remove Panel',
  126. text: 'Are you sure you want to remove this panel?',
  127. text2: text2,
  128. icon: 'fa-trash',
  129. confirmText: confirmText,
  130. yesText: 'Remove',
  131. onConfirm: () => {
  132. this.removePanel(panel, false);
  133. },
  134. });
  135. return;
  136. }
  137. this.dashboard.removePanel(panel);
  138. }
  139. onDestroy() {
  140. if (this.dashboard) {
  141. this.dashboard.destroy();
  142. }
  143. }
  144. init(dashboard) {
  145. this.$scope.onAppEvent('show-json-editor', this.showJsonEditor.bind(this));
  146. this.$scope.onAppEvent('template-variable-value-updated', this.templateVariableUpdated.bind(this));
  147. this.$scope.onAppEvent('panel-remove', this.onRemovingPanel.bind(this));
  148. this.$scope.$on('$destroy', this.onDestroy.bind(this));
  149. this.setupDashboard(dashboard);
  150. }
  151. }
  152. coreModule.controller('DashboardCtrl', DashboardCtrl);