Commit 917cd350 by Torkel Ödegaard

Dashboard: View dashboard json, edit/update any panel using json editor, makes…

Dashboard: View dashboard json, edit/update any panel using json editor, makes it possible to quickly copy a graph from one dashboard to another.
Closes #304
parent b989183f
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
**New features and improvements** **New features and improvements**
- [Issue #117](https://github.com/grafana/grafana/issues/117). Graphite: Graphite query builder can now handle functions that multiple series as arguments! - [Issue #117](https://github.com/grafana/grafana/issues/117). Graphite: Graphite query builder can now handle functions that multiple series as arguments!
- [Issue #281](https://github.com/grafana/grafana/issues/281). Graphite: Metric node/segment selection is now a textbox with autocomplete dropdown, allow for custom glob expression for single node segment without entering text editor mode. - [Issue #281](https://github.com/grafana/grafana/issues/281). Graphite: Metric node/segment selection is now a textbox with autocomplete dropdown, allow for custom glob expression for single node segment without entering text editor mode.
- [Issue #304](https://github.com/grafana/grafana/issues/304). Dashboard: View dashboard json, edit/update any panel using json editor, makes it possible to quickly copy a graph from one dashboard to another.
- [Issue #578](https://github.com/grafana/grafana/issues/578). Dashboard: Row option to display row title even when the row is visible - [Issue #578](https://github.com/grafana/grafana/issues/578). Dashboard: Row option to display row title even when the row is visible
- [Issue #672](https://github.com/grafana/grafana/issues/672). Dashboard: panel fullscreen & edit state is present in url, can now link to graph in edit & fullscreen mode. - [Issue #672](https://github.com/grafana/grafana/issues/672). Dashboard: panel fullscreen & edit state is present in url, can now link to graph in edit & fullscreen mode.
- [Issue #709](https://github.com/grafana/grafana/issues/709). Dashboard: Small UI look polish to search results, made dashboard title link are larger - [Issue #709](https://github.com/grafana/grafana/issues/709). Dashboard: Small UI look polish to search results, made dashboard title link are larger
......
...@@ -15,4 +15,5 @@ define([ ...@@ -15,4 +15,5 @@ define([
'./opentsdbTargetCtrl', './opentsdbTargetCtrl',
'./annotationsEditorCtrl', './annotationsEditorCtrl',
'./templateEditorCtrl', './templateEditorCtrl',
'./jsonEditorCtrl',
], function () {}); ], function () {});
...@@ -29,6 +29,7 @@ function (angular, $, config, _) { ...@@ -29,6 +29,7 @@ function (angular, $, config, _) {
$scope.init = function() { $scope.init = function() {
$scope.availablePanels = config.panels; $scope.availablePanels = config.panels;
$scope.onAppEvent('setup-dashboard', $scope.setupDashboard); $scope.onAppEvent('setup-dashboard', $scope.setupDashboard);
$scope.onAppEvent('show-json-editor', $scope.showJsonEditor);
$scope.reset_row(); $scope.reset_row();
$scope.registerWindowResizeEvent(); $scope.registerWindowResizeEvent();
}; };
...@@ -107,6 +108,13 @@ function (angular, $, config, _) { ...@@ -107,6 +108,13 @@ function (angular, $, config, _) {
} }
}; };
$scope.showJsonEditor = function(evt, options) {
var editScope = $rootScope.$new();
editScope.object = options.object;
editScope.updateHandler = options.updateHandler;
$scope.emitAppEvent('show-dash-editor', { src: 'app/partials/edit_json.html', scope: editScope });
};
$scope.checkFeatureToggles = function() { $scope.checkFeatureToggles = function() {
$scope.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable; $scope.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable;
}; };
......
...@@ -140,9 +140,7 @@ function (angular, _, moment, config, store) { ...@@ -140,9 +140,7 @@ function (angular, _, moment, config, store) {
}; };
$scope.editJson = function() { $scope.editJson = function() {
var editScope = $rootScope.$new(); $scope.emitAppEvent('show-json-editor', { object: $scope.dashboard });
editScope.json = angular.toJson($scope.dashboard, true);
$scope.emitAppEvent('show-dash-editor', { src: 'app/partials/edit_json.html', scope: editScope });
}; };
$scope.openSaveDropdown = function() { $scope.openSaveDropdown = function() {
......
...@@ -7,7 +7,15 @@ function (angular) { ...@@ -7,7 +7,15 @@ function (angular) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('JsonEditorCtrl', function() { module.controller('JsonEditorCtrl', function($scope) {
$scope.json = angular.toJson($scope.object, true);
$scope.canUpdate = $scope.updateHandler !== void 0;
$scope.update = function () {
var newObject = angular.fromJson($scope.json);
$scope.updateHandler(newObject, $scope.object);
};
}); });
......
...@@ -13,7 +13,6 @@ function (angular, app, _) { ...@@ -13,7 +13,6 @@ function (angular, app, _) {
title: "Row", title: "Row",
height: "150px", height: "150px",
collapse: false, collapse: false,
editable: true,
panels: [], panels: [],
}; };
...@@ -76,6 +75,19 @@ function (angular, app, _) { ...@@ -76,6 +75,19 @@ function (angular, app, _) {
} }
}; };
$scope.replacePanel = function(newPanel, oldPanel) {
var row = $scope.row;
var index = _.indexOf(row.panels, oldPanel);
row.panels.splice(index, 1);
// adding it back needs to be done in next digest
$timeout(function() {
newPanel.id = oldPanel.id;
newPanel.span = oldPanel.span;
row.panels.splice(index, 0, newPanel);
});
};
$scope.duplicatePanel = function(panel, row) { $scope.duplicatePanel = function(panel, row) {
$scope.dashboard.duplicatePanel(panel, row || $scope.row); $scope.dashboard.duplicatePanel(panel, row || $scope.row);
}; };
......
...@@ -8,9 +8,7 @@ ...@@ -8,9 +8,7 @@
{ {
"title": "New row", "title": "New row",
"height": "150px", "height": "150px",
"editable": true,
"collapse": false, "collapse": false,
"collapsable": true,
"panels": [ "panels": [
{ {
"error": false, "error": false,
...@@ -22,15 +20,12 @@ ...@@ -22,15 +20,12 @@
"style": {}, "style": {},
"title": "Welcome to" "title": "Welcome to"
} }
], ]
"notice": false
}, },
{ {
"title": "Welcome to Grafana", "title": "Welcome to Grafana",
"height": "210px", "height": "210px",
"editable": true,
"collapse": false, "collapse": false,
"collapsable": true,
"panels": [ "panels": [
{ {
"error": false, "error": false,
...@@ -53,15 +48,12 @@ ...@@ -53,15 +48,12 @@
"style": {}, "style": {},
"title": "Tips & Shortcuts" "title": "Tips & Shortcuts"
} }
], ]
"notice": false
}, },
{ {
"title": "test", "title": "test",
"height": "250px", "height": "250px",
"editable": true,
"collapse": false, "collapse": false,
"collapsable": true,
"panels": [ "panels": [
{ {
"span": 12, "span": 12,
...@@ -132,27 +124,13 @@ ...@@ -132,27 +124,13 @@
"enable": false "enable": false
} }
} }
], ]
"notice": false
}
],
"pulldowns": [
{
"type": "filtering",
"collapse": false,
"notice": false,
"enable": false
},
{
"type": "annotations",
"enable": false
} }
], ],
"nav": [ "nav": [
{ {
"type": "timepicker", "type": "timepicker",
"collapse": false, "collapse": false,
"notice": false,
"enable": true, "enable": true,
"status": "Stable", "status": "Stable",
"time_options": [ "time_options": [
...@@ -188,5 +166,5 @@ ...@@ -188,5 +166,5 @@
"templating": { "templating": {
"list": [] "list": []
}, },
"version": 2 "version": 5
} }
\ No newline at end of file
...@@ -17,22 +17,10 @@ ...@@ -17,22 +17,10 @@
} }
], ],
"editable": true, "editable": true,
"failover": false,
"panel_hints": true,
"style": "dark", "style": "dark",
"pulldowns": [
{
"type": "filtering",
"collapse": false,
"notice": false,
"enable": false
}
],
"nav": [ "nav": [
{ {
"type": "timepicker", "type": "timepicker",
"collapse": false,
"notice": false,
"enable": true, "enable": true,
"status": "Stable", "status": "Stable",
"time_options": [ "time_options": [
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
<a class="link" ng-click="removeAsFavorite()">Remove as favorite</a> <a class="link" ng-click="removeAsFavorite()">Remove as favorite</a>
</li> </li>
<li> <li>
<a class="link" ng-click="editJson()">Edit Json</a> <a class="link" ng-click="editJson()">Dashboard JSON</a>
</li> </li>
<li> <li>
<a class="link" ng-click="exportDashboard()">Export dashboard</a> <a class="link" ng-click="exportDashboard()">Export dashboard</a>
......
<div> <div ng-controller="JsonEditorCtrl">
<div class="dashboard-editor-header"> <div class="dashboard-editor-header">
<div class="dashboard-editor-title"> <div class="dashboard-editor-title">
<i class="icon icon-edit"></i> <i class="icon icon-edit"></i>
Edit / View JSON JSON
</div> </div>
</div> </div>
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
</div> </div>
<div class="dashboard-editor-footer"> <div class="dashboard-editor-footer">
<button type="button" class="btn btn-success pull-left" ng-show="canUpdate" ng-click="update(); dismiss();">Update</button>
<button type="button" class="btn btn-success pull-right" ng-click="dismiss();">Close</button> <button type="button" class="btn btn-success pull-right" ng-click="dismiss();">Close</button>
</div> </div>
......
...@@ -53,6 +53,13 @@ function (angular, _) { ...@@ -53,6 +53,13 @@ function (angular, _) {
condition: true condition: true
}, },
{ {
text: 'Advanced',
submenu: [
{ text: 'Panel JSON', click: 'editPanelJson()' },
],
condition: true
},
{
text: 'Remove', text: 'Remove',
click: 'remove_panel_from_row(row, panel)', click: 'remove_panel_from_row(row, panel)',
condition: true condition: true
...@@ -62,6 +69,10 @@ function (angular, _) { ...@@ -62,6 +69,10 @@ function (angular, _) {
$scope.inspector = {}; $scope.inspector = {};
$scope.panelMeta.menu = _.where(menu, { condition: true }); $scope.panelMeta.menu = _.where(menu, { condition: true });
$scope.editPanelJson = function() {
$scope.emitAppEvent('show-json-editor', { object: $scope.panel, updateHandler: $scope.replacePanel });
};
$scope.updateColumnSpan = function(span) { $scope.updateColumnSpan = function(span) {
$scope.panel.span = span; $scope.panel.span = span;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment