浏览代码

ux(dashboar): added shortcut for build mode, switched keybinding lib to mousetrap, supports sequences so also added for Go to home dashboard, open search with starred dashbords prefiltered, go to profile, #6442

Torkel Ödegaard 9 年之前
父节点
当前提交
40ea014fa8

+ 1 - 0
package.json

@@ -73,6 +73,7 @@
     "grunt-sync": "^0.4.1",
     "karma-sinon": "^1.0.3",
     "lodash": "^2.4.1",
+    "mousetrap": "^1.6.0",
     "remarkable": "^1.6.2",
     "sinon": "1.16.1",
     "systemjs-builder": "^0.15.13",

+ 5 - 1
public/app/core/components/search/search.ts

@@ -29,7 +29,7 @@ export class SearchCtrl {
     this.isOpen = this.ignoreClose;
   }
 
-  openSearch() {
+  openSearch(evt, payload) {
     if (this.isOpen) {
       this.isOpen = false;
       return;
@@ -43,6 +43,10 @@ export class SearchCtrl {
     this.currentSearchId = 0;
     this.ignoreClose = true;
 
+    if (payload && payload.starred) {
+      this.query.starred = true;
+    }
+
     this.$timeout(() => {
       this.ignoreClose = false;
       this.giveSearchFocus = this.giveSearchFocus + 1;

+ 2 - 0
public/app/core/core.ts

@@ -44,6 +44,7 @@ import appEvents from './app_events';
 import colors from './utils/colors';
 import {assignModelProperties} from './utils/model_utils';
 import {contextSrv} from './services/context_srv';
+import {KeybindingSrv} from './services/keybindingSrv';
 
 
 export {
@@ -66,4 +67,5 @@ export {
   colors,
   assignModelProperties,
   contextSrv,
+  KeybindingSrv,
 };

+ 118 - 0
public/app/core/services/keybindingSrv.ts

@@ -0,0 +1,118 @@
+///<reference path="../../headers/common.d.ts" />
+
+import $ from 'jquery';
+
+import coreModule from 'app/core/core_module';
+import appEvents from 'app/core/app_events';
+
+import Mousetrap from 'mousetrap';
+
+export class KeybindingSrv {
+  helpModal: boolean;
+
+  /** @ngInject */
+  constructor(private $rootScope, private $modal, private $location) {
+    // clear out all shortcuts on route change
+    $rootScope.$on('$routeChangeSuccess', () => {
+      Mousetrap.reset();
+      // rebind global shortcuts
+      this.setupGlobal();
+    });
+
+    this.setupGlobal();
+  }
+
+
+  setupGlobal() {
+    this.bind("?", this.showHelpModal);
+    this.bind("g h", this.goToHome);
+    this.bind("g p", this.goToProfile);
+    this.bind("s s", this.openSearchStarred);
+    this.bind(['f'], this.openSearch);
+  }
+
+  openSearchStarred() {
+    this.$rootScope.appEvent('show-dash-search', {starred: true});
+  }
+
+  openSearch() {
+    this.$rootScope.appEvent('show-dash-search');
+  }
+
+  goToHome() {
+    this.$location.path("/");
+  }
+
+  goToProfile() {
+    this.$location.path("/profile");
+  }
+
+  showHelpModal() {
+    console.log('showing help modal');
+    appEvents.emit('show-modal', {
+      src: 'public/app/partials/help_modal.html',
+      model: {}
+    });
+  }
+
+  bind(keyArg, fn) {
+    Mousetrap.bind(keyArg, evt => {
+      evt.preventDefault();
+      evt.stopPropagation();
+      return this.$rootScope.$apply(fn.bind(this));
+    });
+  }
+
+  setupDashboardBindings(scope, dashboard) {
+    this.bind('b', () => {
+      dashboard.toggleEditMode();
+    });
+
+    this.bind('ctrl+o', () => {
+      dashboard.sharedCrosshair = !dashboard.sharedCrosshair;
+      scope.broadcastRefresh();
+    });
+
+    this.bind(['ctrl+s', 'command+s'], () => {
+      scope.appEvent('save-dashboard');
+    });
+
+    this.bind('r', () => {
+      scope.broadcastRefresh();
+    });
+
+    this.bind('ctrl+z', () => {
+      scope.appEvent('zoom-out');
+    });
+
+    this.bind('left', () => {
+      scope.appEvent('shift-time-backward');
+    });
+
+    this.bind('right', () => {
+      scope.appEvent('shift-time-forward');
+    });
+
+    this.bind('ctrl+i', () => {
+      scope.appEvent('quick-snapshot');
+    });
+
+    this.bind('esc', () => {
+      var popups = $('.popover.in');
+      if (popups.length > 0) {
+        return;
+      }
+      // close modals
+      var modalData = $(".modal").data();
+      if (modalData && modalData.$scope && modalData.$scope.dismiss) {
+        modalData.$scope.dismiss();
+      }
+
+      scope.appEvent('hide-dash-editor');
+
+      scope.exitFullscreen();
+    });
+  }
+}
+
+coreModule.service('keybindingSrv', KeybindingSrv);

+ 8 - 1
public/app/core/services/util_srv.ts

@@ -8,6 +8,7 @@ import coreModule from 'app/core/core_module';
 import appEvents from 'app/core/app_events';
 
 export class UtilSrv {
+  modalScope: any;
 
   /** @ngInject */
   constructor(private $rootScope, private $modal) {
@@ -18,9 +19,15 @@ export class UtilSrv {
   }
 
   showModal(options) {
+    if (this.modalScope && this.modalScope.dismiss) {
+      this.modalScope.dismiss();
+    }
+
     if (options.model) {
-      options.scope = this.$rootScope.$new();
+      options.scope = this.modalScope = this.$rootScope.$new();
       options.scope.model = options.model;
+    } else {
+      this.modalScope = options.scope;
     }
 
     var modal = this.$modal({

+ 0 - 1
public/app/features/dashboard/all.js

@@ -9,7 +9,6 @@ define([
   './shareModalCtrl',
   './shareSnapshotCtrl',
   './dashboard_srv',
-  './keybindings',
   './viewStateSrv',
   './timeSrv',
   './unsavedChangesSrv',

+ 2 - 2
public/app/features/dashboard/dashboard_ctrl.ts

@@ -13,7 +13,7 @@ export class DashboardCtrl {
   constructor(
     private $scope,
     private $rootScope,
-    dashboardKeybindings,
+    keybindingSrv,
     timeSrv,
     variableSrv,
     alertingSrv,
@@ -61,7 +61,7 @@ export class DashboardCtrl {
           $scope.dashboardMeta = dashboard.meta;
           $scope.dashboardViewState = dashboardViewStateSrv.create($scope);
 
-          dashboardKeybindings.shortcuts($scope);
+          keybindingSrv.setupDashboardBindings($scope, dashboard);
 
           $scope.dashboard.updateSubmenuVisibility();
           $scope.setWindowTitleAndTheme();

+ 0 - 96
public/app/features/dashboard/keybindings.js

@@ -1,96 +0,0 @@
-define([
-  'angular',
-  'jquery',
-],
-function(angular, $) {
-  "use strict";
-
-  var module = angular.module('grafana.services');
-
-  module.service('dashboardKeybindings', function($rootScope, keyboardManager, $modal, $q) {
-
-    this.shortcuts = function(scope) {
-
-      var unbindDestroy = scope.$on('$destroy', function() {
-        keyboardManager.unbindAll();
-        unbindDestroy();
-      });
-
-      var helpModalScope = null;
-      keyboardManager.bind('shift+?', function() {
-        if (helpModalScope) { return; }
-
-        helpModalScope = $rootScope.$new();
-        var helpModal = $modal({
-          template: 'public/app/partials/help_modal.html',
-          persist: false,
-          show: false,
-          scope: helpModalScope,
-          keyboard: false
-        });
-
-        var unbindModalDestroy = helpModalScope.$on('$destroy', function() {
-          helpModalScope = null;
-          unbindModalDestroy();
-        });
-
-        $q.when(helpModal).then(function(modalEl) { modalEl.modal('show'); });
-
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('f', function() {
-        scope.appEvent('show-dash-search');
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('ctrl+o', function() {
-        var current = scope.dashboard.sharedCrosshair;
-        scope.dashboard.sharedCrosshair = !current;
-        scope.broadcastRefresh();
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('b', function() {
-        scope.dashboard.toggleEditMode();
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('ctrl+s', function(evt) {
-        scope.appEvent('save-dashboard', evt);
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('r', function() {
-        scope.broadcastRefresh();
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('ctrl+z', function(evt) {
-        scope.appEvent('zoom-out', evt);
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('left', function(evt) {
-        scope.appEvent('shift-time-backward', evt);
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('right', function(evt) {
-        scope.appEvent('shift-time-forward', evt);
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('ctrl+i', function(evt) {
-        scope.appEvent('quick-snapshot', evt);
-      }, { inputDisabled: true });
-
-      keyboardManager.bind('esc', function() {
-        var popups = $('.popover.in');
-        if (popups.length > 0) {
-          return;
-        }
-        // close modals
-        var modalData = $(".modal").data();
-        if (modalData && modalData.$scope && modalData.$scope.dismiss) {
-          modalData.$scope.dismiss();
-        }
-
-        scope.appEvent('hide-dash-editor');
-
-        scope.exitFullscreen();
-      }, { inputDisabled: true });
-    };
-  });
-});

+ 0 - 6
public/app/features/dashboard/partials/settings.html

@@ -55,12 +55,6 @@
                         checked="dashboard.editable"
                         label-class="width-11">
         </gf-form-switch>
-        <gf-form-switch class="gf-form"
-                        label="Build Mode"
-                        tooltip="Enable build mode. Shortcut: CTRL+B"
-                        checked="dashboard.editMode"
-                        label-class="width-11">
-        </gf-form-switch>
         <gf-form-switch class="gf-form"
                         label="Shared Crosshair"
                         tooltip="Shared Crosshair line on all graphs. Shortcut: CTRL+O"

+ 5 - 0
public/app/headers/common.d.ts

@@ -57,3 +57,8 @@ declare module 'virtual-scroll' {
   var config: any;
   export default config;
 }
+
+declare module 'mousetrap' {
+  var config: any;
+  export default config;
+}

+ 3 - 3
public/app/plugins/panel/graph/graph.ts

@@ -535,9 +535,9 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
         return "%H:%M";
       }
 
-      // new GraphTooltip(elem, dashboard, scope, function() {
-      //   return sortedSeries;
-      // });
+      new GraphTooltip(elem, dashboard, scope, function() {
+        return sortedSeries;
+      });
 
       elem.bind("plotselected", function (event, ranges) {
         scope.$apply(function() {

+ 2 - 2
public/app/plugins/panel/graph/threshold_manager.ts

@@ -153,8 +153,8 @@ export class ThresholdManager {
       this.renderHandle(1, this.height-30);
     }
 
-    // this.placeholder.off('mousedown', '.alert-handle');
-    // this.placeholder.on('mousedown', '.alert-handle', this.initDragging.bind(this));
+    this.placeholder.off('mousedown', '.alert-handle');
+    this.placeholder.on('mousedown', '.alert-handle', this.initDragging.bind(this));
     this.needsCleanup = true;
   }
 

+ 5 - 0
public/app/system.conf.js

@@ -3,6 +3,7 @@ System.config({
   baseURL: 'public',
   paths: {
     'virtual-scroll': 'vendor/npm/virtual-scroll/src/index.js',
+    'mousetrap': 'vendor/npm/mousetrap/mousetrap.js',
     'remarkable': 'vendor/npm/remarkable/dist/remarkable.js',
     'tether': 'vendor/npm/tether/dist/js/tether.js',
     'eventemitter3': 'vendor/npm/eventemitter3/index.js',
@@ -66,5 +67,9 @@ System.config({
       format: 'cjs',
       exports: 'EventEmitter'
     },
+    'vendor/npm/mousetrap/mousetrap.js': {
+      format: 'global',
+      exports: 'Mousetrap'
+    },
   }
 });

+ 1 - 1
public/sass/_variables.dark.scss

@@ -265,7 +265,7 @@ $tooltipBackground:       $popover-help-bg;
 $tooltipArrowWidth:       5px;
 $tooltipArrowColor:       $tooltipBackground;
 $tooltipLinkColor:        $link-color;
-$graph-tooltip-bg:        $dark-4;
+$graph-tooltip-bg:        $dark-1;
 
 // images
 $checkboxImageUrl: '../img/checkbox.png';

+ 2 - 0
public/sass/components/_panel_graph.scss

@@ -244,6 +244,8 @@
     position: relative;
     top: -3px;
     padding: 0.2rem;
+    font-weight: bold;
+    color: $text-color;
   }
 
   .graph-tooltip-list-item {

+ 1 - 0
tasks/options/copy.js

@@ -33,6 +33,7 @@ module.exports = function(config) {
         'remarkable/dist/*',
         'remarkable/dist/*',
         'virtual-scroll/**/*',
+        'mousetrap/**/*',
       ],
       dest: '<%= srcDir %>/vendor/npm'
     }