Skip to content

Commit 95e7ead

Browse files
committed
ux(dashboard): varius dashboard ux fixes and keybinding improvements, press 'e' while hovering over panel will open dashboard in edit mode, pressing 'd' will remove panel, grafana#6442
1 parent 19509d1 commit 95e7ead

File tree

13 files changed

+162
-19
lines changed

13 files changed

+162
-19
lines changed

public/app/core/services/keybindingSrv.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ export class KeybindingSrv {
9797
scope.appEvent('quick-snapshot');
9898
});
9999

100+
this.bind('e', () => {
101+
if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
102+
this.$rootScope.appEvent('panel-change-view', {
103+
fullscreen: true, edit: true, panelId: dashboard.meta.focusPanelId
104+
});
105+
}
106+
});
107+
108+
this.bind('d', () => {
109+
if (dashboard.meta.focusPanelId && dashboard.meta.canEdit) {
110+
var panelInfo = dashboard.getPanelInfoById(dashboard.meta.focusPanelId);
111+
panelInfo.row.removePanel(panelInfo.panel);
112+
dashboard.meta.focusPanelId = 0;
113+
}
114+
});
115+
100116
this.bind('esc', () => {
101117
var popups = $('.popover.in');
102118
if (popups.length > 0) {

public/app/features/dashboard/model.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,20 @@ export class DashboardModel {
185185
}
186186

187187
toggleEditMode() {
188+
if (!this.meta.canEdit) {
189+
console.log('Not allowed to edit dashboard');
190+
return;
191+
}
192+
188193
this.editMode = !this.editMode;
189194
this.updateSubmenuVisibility();
190195
}
191196

197+
setPanelFocus(id) {
198+
console.log('setting focus panel id', id);
199+
this.meta.focusPanelId = id;
200+
}
201+
192202
updateSubmenuVisibility() {
193203
if (this.editMode) {
194204
this.meta.submenuEnabled = true;

public/app/features/dashboard/row/row.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@
4141
</div>
4242

4343
<div ng-if="!ctrl.dashboard.editMode">
44+
<div class="row-open">
45+
<div class='row-tab dropdown' ng-show="dashboardMeta.canEdit" ng-hide="dashboard.meta.fullscreen">
46+
<span class="row-tab-button dropdown-toggle" data-toggle="dropdown">
47+
<i class="fa fa-bars"></i>
48+
</span>
49+
<ul class="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="drop1">
50+
<li>
51+
<a ng-click="ctrl.onMenuAddPanel()">Add Panel</a>
52+
</li>
53+
<li>
54+
<a ng-click="ctrl.onMenuRowOptions()">Row Options</a>
55+
</li>
56+
<li>
57+
<a ng-click="ctrl.onMenuDeleteRow()">Delete row</a>
58+
</li>
59+
</ul>
60+
</div>
61+
</div>
62+
4463
<div class="dash-row-header" ng-if="ctrl.showtitle">
4564
<a class="dash-row-header-title" ng-click="ctrl.toggleCollapse()">
4665
<span class="dash-row-collapse-toggle pointer">

public/app/features/dashboard/row/row_ctrl.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ export class DashRowCtrl {
5858
// insert after
5959
dropTarget.row.panels.splice(dropTarget.index+1, 0, dragObject.panel);
6060
// remove from source row
61-
dragObject.row.removePanel(dragObject.panel);
61+
dragObject.row.removePanel(dragObject.panel, false);
6262
}
6363
} else {
6464
dragObject.panel.span = 12 - this.row.span;
6565
this.row.panels.push(dragObject.panel);
6666

6767
// if not new remove from source row
6868
if (!dragObject.isNew) {
69-
dragObject.row.removePanel(dragObject.panel);
69+
dragObject.row.removePanel(dragObject.panel, false);
7070
}
7171
}
7272

@@ -104,6 +104,20 @@ export class DashRowCtrl {
104104
showRowOptions() {
105105
this.dropView = this.dropView === 2 ? 0 : 2;
106106
}
107+
108+
onMenuAddPanel() {
109+
this.dashboard.toggleEditMode();
110+
this.dropView = 1;
111+
}
112+
113+
onMenuRowOptions() {
114+
this.dashboard.toggleEditMode();
115+
this.dropView = 2;
116+
}
117+
118+
onMenuDeleteRow() {
119+
this.dashboard.removeRow(this.row);
120+
}
107121
}
108122

109123
coreModule.directive('dashRow', function($rootScope) {

public/app/features/dashboard/row/row_model.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
///<reference path="../../../headers/common.d.ts" />
22

33
import _ from 'lodash';
4-
import {Emitter, contextSrv} from 'app/core/core';
5-
import {assignModelProperties} from 'app/core/core';
4+
import {Emitter, contextSrv, appEvents, assignModelProperties} from 'app/core/core';
65

76
export class DashboardRow {
87
panels: any;
@@ -79,10 +78,23 @@ export class DashboardRow {
7978
this.panelSpanChanged();
8079
}
8180

82-
removePanel(panel) {
81+
removePanel(panel, ask?) {
82+
console.log('remove panel');
83+
if (ask !== false) {
84+
appEvents.emit('confirm-modal', {
85+
title: 'Remove Panel',
86+
text: 'Are you sure you want to remove this panel?',
87+
icon: 'fa-trash',
88+
yesText: 'Remove',
89+
onConfirm: () => {
90+
this.removePanel(panel, false);
91+
}
92+
});
93+
return;
94+
}
95+
8396
var index = _.indexOf(this.panels, panel);
8497
this.panels.splice(index, 1);
85-
8698
this.events.emit('panel-removed', panel);
8799
this.panelSpanChanged();
88100
}

public/app/features/panel/panel_ctrl.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,7 @@ export class PanelCtrl {
201201
}
202202

203203
removePanel() {
204-
this.publishAppEvent('confirm-modal', {
205-
title: 'Remove Panel',
206-
text: 'Are you sure you want to remove this panel?',
207-
icon: 'fa-trash',
208-
yesText: 'Remove',
209-
onConfirm: () => {
210-
this.row.removePanel(this.panel);
211-
}
212-
});
204+
this.row.removePanel(this.panel);
213205
}
214206

215207
editPanelJson() {

public/app/features/panel/panel_directive.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ module.directive('grafanaPanel', function($rootScope) {
7474
var hasAlertRule;
7575
var lastHeight = 0;
7676

77+
function mouseEnter() {
78+
panelContainer.toggleClass('panel-hover-highlight', true);
79+
ctrl.dashboard.setPanelFocus(ctrl.panel.id);
80+
}
81+
82+
function mouseLeave() {
83+
panelContainer.toggleClass('panel-hover-highlight', false);
84+
ctrl.dashboard.setPanelFocus(0);
85+
}
86+
7787
// set initial height
7888
if (!ctrl.containerHeight) {
7989
ctrl.calculatePanelHeight();
@@ -122,6 +132,13 @@ module.directive('grafanaPanel', function($rootScope) {
122132
lastFullscreen = ctrl.fullscreen;
123133
}
124134
}, scope);
135+
136+
panelContainer.on('mouseenter', mouseEnter);
137+
panelContainer.on('mouseleave', mouseLeave);
138+
139+
scope.$on('$destroy', function() {
140+
panelContainer.off();
141+
});
125142
}
126143
};
127144
});

public/app/partials/confirm_modal.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ <h2 class="modal-header-title">
2828

2929
<div class="confirm-modal-buttons">
3030
<button type="button" class="btn btn-inverse" ng-click="dismiss()">{{noText}}</button>
31-
<button type="button" class="btn btn-danger" ng-click="onConfirm();dismiss();" ng-disabled="!confirmTextValid">{{yesText}}</button>
31+
<button type="button" class="btn btn-danger" ng-click="onConfirm();dismiss();" ng-disabled="!confirmTextValid" give-focus="true">{{yesText}}</button>
3232
<button ng-show="onAltAction" type="button" class="btn btn-success" ng-click="dismiss();onAltAction();">{{altActionText}}</button>
3333
</div>
3434
</div>

public/app/plugins/panel/graph/graph.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
5959
}, scope);
6060

6161
rootScope.onAppEvent('clearCrosshair', function() {
62-
plot.clearCrosshair();
62+
if (plot) {
63+
plot.clearCrosshair();
64+
}
6365
}, scope);
6466

6567
// Receive render events
@@ -535,7 +537,7 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
535537
return "%H:%M";
536538
}
537539

538-
new GraphTooltip(elem, dashboard, scope, function() {
540+
var tooltip = new GraphTooltip(elem, dashboard, scope, function() {
539541
return sortedSeries;
540542
});
541543

@@ -547,6 +549,12 @@ module.directive('grafanaGraph', function($rootScope, timeSrv) {
547549
});
548550
});
549551
});
552+
553+
scope.$on('$destroy', function() {
554+
tooltip.destroy();
555+
elem.off();
556+
elem.remove();
557+
});
550558
}
551559
};
552560
});

public/app/plugins/panel/graph/graph_tooltip.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ function ($, _) {
1212

1313
var $tooltip = $('<div id="tooltip" class="graph-tooltip">');
1414

15+
this.destroy = function() {
16+
$tooltip.remove();
17+
};
18+
1519
this.findHoverIndexFromDataPoints = function(posX, series, last) {
1620
var ps = series.datapoints.pointsize;
1721
var initial = last*ps;

public/sass/components/_row.scss

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,45 @@ a.dash-row-header-actions--tight {
215215
width: 2rem;
216216
}
217217

218+
219+
// Legacy mode
220+
.row-tab {
221+
.dropdown-menu-right {
222+
top: 0;
223+
left: 33px;
224+
}
225+
}
226+
227+
.row-tab-button {
228+
padding: 0px;
229+
cursor: pointer;
230+
vertical-align: middle;
231+
width: 30px;
232+
height: 30px;
233+
text-align: center;
234+
display: inline-block;
235+
line-height: 30px;
236+
background: $btn-success-bg;
237+
color: rgba(255,255,255,.90);
238+
}
239+
240+
.row-button {
241+
width: 24px;
242+
float: left;
243+
cursor: pointer;
244+
line-height: 31px;
245+
background-color: $blue-dark;
246+
}
247+
248+
.row-open {
249+
margin-top: 1px;
250+
left: -22px;
251+
position: absolute;
252+
z-index: 100;
253+
transition: .10s left;
254+
transition-delay: .05s;
255+
256+
&:hover {
257+
left: 0px;
258+
}
259+
}

public/sass/pages/_dashboard.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ div.flot-text {
152152
}
153153

154154
.panel-highlight {
155-
box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 5px rgba(82,168,236,10.8)
155+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 5px rgba(82,168,236,10.8)
156+
}
157+
158+
.panel-hover-highlight {
159+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 1px rgba(82,168,236,10.8)
156160
}
157161

158162
.on-drag-hover {

public/test/test-main.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
baseURL: '/base/',
1111
defaultJSExtensions: true,
1212
paths: {
13+
'mousetrap': 'vendor/npm/mousetrap/mousetrap.js',
1314
'eventemitter3': 'vendor/npm/eventemitter3/index.js',
1415
'tether': 'vendor/npm/tether/dist/js/tether.js',
1516
'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
@@ -65,6 +66,10 @@
6566
format: 'cjs',
6667
exports: 'EventEmitter'
6768
},
69+
'vendor/npm/mousetrap/mousetrap.js': {
70+
format: 'global',
71+
exports: 'Mousetrap'
72+
},
6873
}
6974
});
7075

0 commit comments

Comments
 (0)