keybindingSrv.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. import $ from 'jquery';
  2. import _ from 'lodash';
  3. import coreModule from 'app/core/core_module';
  4. import appEvents from 'app/core/app_events';
  5. import Mousetrap from 'mousetrap';
  6. import 'mousetrap-global-bind';
  7. export class KeybindingSrv {
  8. helpModal: boolean;
  9. modalOpen = false;
  10. timepickerOpen = false;
  11. /** @ngInject */
  12. constructor(private $rootScope, private $location) {
  13. // clear out all shortcuts on route change
  14. $rootScope.$on('$routeChangeSuccess', () => {
  15. Mousetrap.reset();
  16. // rebind global shortcuts
  17. this.setupGlobal();
  18. });
  19. this.setupGlobal();
  20. appEvents.on('show-modal', () => (this.modalOpen = true));
  21. $rootScope.onAppEvent('openTimepicker', () => (this.timepickerOpen = true));
  22. }
  23. setupGlobal() {
  24. this.bind(['?', 'h'], this.showHelpModal);
  25. this.bind('g h', this.goToHome);
  26. this.bind('g a', this.openAlerting);
  27. this.bind('g p', this.goToProfile);
  28. this.bind('s s', this.openSearchStarred);
  29. this.bind('s o', this.openSearch);
  30. this.bind('s t', this.openSearchTags);
  31. this.bind('f', this.openSearch);
  32. this.bindGlobal('esc', this.exit);
  33. }
  34. openSearchStarred() {
  35. appEvents.emit('show-dash-search', { starred: true });
  36. }
  37. openSearchTags() {
  38. appEvents.emit('show-dash-search', { tagsMode: true });
  39. }
  40. openSearch() {
  41. appEvents.emit('show-dash-search');
  42. }
  43. openAlerting() {
  44. this.$location.url('/alerting');
  45. }
  46. goToHome() {
  47. this.$location.url('/');
  48. }
  49. goToProfile() {
  50. this.$location.url('/profile');
  51. }
  52. showHelpModal() {
  53. appEvents.emit('show-modal', { templateHtml: '<help-modal></help-modal>' });
  54. }
  55. exit() {
  56. var popups = $('.popover.in');
  57. if (popups.length > 0) {
  58. return;
  59. }
  60. appEvents.emit('hide-modal');
  61. if (!this.modalOpen) {
  62. if (this.timepickerOpen) {
  63. this.$rootScope.appEvent('closeTimepicker');
  64. this.timepickerOpen = false;
  65. } else {
  66. this.$rootScope.appEvent('panel-change-view', { fullscreen: false, edit: false });
  67. }
  68. } else {
  69. this.modalOpen = false;
  70. }
  71. // close settings view
  72. var search = this.$location.search();
  73. if (search.editview) {
  74. delete search.editview;
  75. this.$location.search(search);
  76. }
  77. }
  78. bind(keyArg, fn) {
  79. Mousetrap.bind(
  80. keyArg,
  81. evt => {
  82. evt.preventDefault();
  83. evt.stopPropagation();
  84. evt.returnValue = false;
  85. return this.$rootScope.$apply(fn.bind(this));
  86. },
  87. 'keydown'
  88. );
  89. }
  90. bindGlobal(keyArg, fn) {
  91. Mousetrap.bindGlobal(
  92. keyArg,
  93. evt => {
  94. evt.preventDefault();
  95. evt.stopPropagation();
  96. evt.returnValue = false;
  97. return this.$rootScope.$apply(fn.bind(this));
  98. },
  99. 'keydown'
  100. );
  101. }
  102. showDashEditView() {
  103. var search = _.extend(this.$location.search(), { editview: 'settings' });
  104. this.$location.search(search);
  105. }
  106. setupDashboardBindings(scope, dashboard) {
  107. this.bind('mod+o', () => {
  108. dashboard.graphTooltip = (dashboard.graphTooltip + 1) % 3;
  109. appEvents.emit('graph-hover-clear');
  110. this.$rootScope.$broadcast('refresh');
  111. });
  112. this.bind('mod+s', e => {
  113. scope.appEvent('save-dashboard');
  114. });
  115. this.bind('t z', () => {
  116. scope.appEvent('zoom-out', 2);
  117. });
  118. this.bind('ctrl+z', () => {
  119. scope.appEvent('zoom-out', 2);
  120. });
  121. this.bind('t left', () => {
  122. scope.appEvent('shift-time-backward');
  123. });
  124. this.bind('t right', () => {
  125. scope.appEvent('shift-time-forward');
  126. });
  127. // edit panel
  128. this.bind('e', () => {
  129. if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
  130. this.$rootScope.appEvent('panel-change-view', {
  131. fullscreen: true,
  132. edit: true,
  133. panelId: dashboard.meta.focusPanelId,
  134. toggle: true,
  135. });
  136. }
  137. });
  138. // view panel
  139. this.bind('v', () => {
  140. if (dashboard.meta.focusPanelId) {
  141. this.$rootScope.appEvent('panel-change-view', {
  142. fullscreen: true,
  143. edit: null,
  144. panelId: dashboard.meta.focusPanelId,
  145. toggle: true,
  146. });
  147. }
  148. });
  149. // delete panel
  150. this.bind('p r', () => {
  151. if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
  152. this.$rootScope.appEvent('panel-remove', {
  153. panelId: dashboard.meta.focusPanelId,
  154. });
  155. dashboard.meta.focusPanelId = 0;
  156. }
  157. });
  158. // duplicate panel
  159. this.bind('p d', () => {
  160. if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
  161. let panelIndex = dashboard.getPanelInfoById(dashboard.meta.focusPanelId).index;
  162. dashboard.duplicatePanel(dashboard.panels[panelIndex]);
  163. }
  164. });
  165. // share panel
  166. this.bind('p s', () => {
  167. if (dashboard.meta.focusPanelId) {
  168. var shareScope = scope.$new();
  169. var panelInfo = dashboard.getPanelInfoById(dashboard.meta.focusPanelId);
  170. shareScope.panel = panelInfo.panel;
  171. shareScope.dashboard = dashboard;
  172. appEvents.emit('show-modal', {
  173. src: 'public/app/features/dashboard/partials/shareModal.html',
  174. scope: shareScope,
  175. });
  176. }
  177. });
  178. // collapse all rows
  179. this.bind('d shift+c', () => {
  180. dashboard.collapseRows();
  181. });
  182. // expand all rows
  183. this.bind('d shift+e', () => {
  184. dashboard.expandRows();
  185. });
  186. this.bind('d n', e => {
  187. this.$location.url('/dashboard/new');
  188. });
  189. this.bind('d r', () => {
  190. this.$rootScope.$broadcast('refresh');
  191. });
  192. this.bind('d s', () => {
  193. this.showDashEditView();
  194. });
  195. this.bind('d k', () => {
  196. appEvents.emit('toggle-kiosk-mode');
  197. });
  198. this.bind('d v', () => {
  199. appEvents.emit('toggle-view-mode');
  200. });
  201. }
  202. }
  203. coreModule.service('keybindingSrv', KeybindingSrv);