Selaa lähdekoodia

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

Torkel Ödegaard 11 vuotta sitten
vanhempi
commit
917cd35005

+ 1 - 0
CHANGELOG.md

@@ -12,6 +12,7 @@
 **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 #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 #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

+ 1 - 0
src/app/controllers/all.js

@@ -15,4 +15,5 @@ define([
   './opentsdbTargetCtrl',
   './annotationsEditorCtrl',
   './templateEditorCtrl',
+  './jsonEditorCtrl',
 ], function () {});

+ 8 - 0
src/app/controllers/dashboardCtrl.js

@@ -29,6 +29,7 @@ function (angular, $, config, _) {
     $scope.init = function() {
       $scope.availablePanels = config.panels;
       $scope.onAppEvent('setup-dashboard', $scope.setupDashboard);
+      $scope.onAppEvent('show-json-editor', $scope.showJsonEditor);
       $scope.reset_row();
       $scope.registerWindowResizeEvent();
     };
@@ -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.submenuEnabled = $scope.dashboard.templating.enable || $scope.dashboard.annotations.enable;
     };

+ 1 - 3
src/app/controllers/dashboardNavCtrl.js

@@ -140,9 +140,7 @@ function (angular, _, moment, config, store) {
     };
 
     $scope.editJson = function() {
-      var editScope = $rootScope.$new();
-      editScope.json = angular.toJson($scope.dashboard, true);
-      $scope.emitAppEvent('show-dash-editor', { src: 'app/partials/edit_json.html', scope: editScope });
+      $scope.emitAppEvent('show-json-editor', { object: $scope.dashboard });
     };
 
     $scope.openSaveDropdown = function() {

+ 9 - 1
src/app/controllers/jsonEditorCtrl.js

@@ -7,7 +7,15 @@ function (angular) {
 
   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 - 1
src/app/controllers/row.js

@@ -13,7 +13,6 @@ function (angular, app, _) {
       title: "Row",
       height: "150px",
       collapse: false,
-      editable: true,
       panels: [],
     };
 
@@ -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.dashboard.duplicatePanel(panel, row || $scope.row);
     };

+ 5 - 27
src/app/dashboards/default.json

@@ -8,9 +8,7 @@
     {
       "title": "New row",
       "height": "150px",
-      "editable": true,
       "collapse": false,
-      "collapsable": true,
       "panels": [
         {
           "error": false,
@@ -22,15 +20,12 @@
           "style": {},
           "title": "Welcome to"
         }
-      ],
-      "notice": false
+      ]
     },
     {
       "title": "Welcome to Grafana",
       "height": "210px",
-      "editable": true,
       "collapse": false,
-      "collapsable": true,
       "panels": [
         {
           "error": false,
@@ -53,15 +48,12 @@
           "style": {},
           "title": "Tips & Shortcuts"
         }
-      ],
-      "notice": false
+      ]
     },
     {
       "title": "test",
       "height": "250px",
-      "editable": true,
       "collapse": false,
-      "collapsable": true,
       "panels": [
         {
           "span": 12,
@@ -132,27 +124,13 @@
             "enable": false
           }
         }
-      ],
-      "notice": false
-    }
-  ],
-  "pulldowns": [
-    {
-      "type": "filtering",
-      "collapse": false,
-      "notice": false,
-      "enable": false
-    },
-    {
-      "type": "annotations",
-      "enable": false
+      ]
     }
   ],
   "nav": [
     {
       "type": "timepicker",
       "collapse": false,
-      "notice": false,
       "enable": true,
       "status": "Stable",
       "time_options": [
@@ -188,5 +166,5 @@
   "templating": {
     "list": []
   },
-  "version": 2
-}
+  "version": 5
+}

+ 0 - 12
src/app/dashboards/empty.json

@@ -17,22 +17,10 @@
     }
   ],
   "editable": true,
-  "failover": false,
-  "panel_hints": true,
   "style": "dark",
-  "pulldowns": [
-    {
-      "type": "filtering",
-      "collapse": false,
-      "notice": false,
-      "enable": false
-    }
-  ],
   "nav": [
     {
       "type": "timepicker",
-      "collapse": false,
-      "notice": false,
       "enable": true,
       "status": "Stable",
       "time_options": [

+ 1 - 1
src/app/partials/dashboard_topnav.html

@@ -47,7 +47,7 @@
 							<a class="link" ng-click="removeAsFavorite()">Remove as favorite</a>
 						</li>
 						<li>
-							<a class="link" ng-click="editJson()">Edit Json</a>
+							<a class="link" ng-click="editJson()">Dashboard JSON</a>
 						</li>
 						<li>
 							<a class="link" ng-click="exportDashboard()">Export dashboard</a>

+ 3 - 2
src/app/partials/edit_json.html

@@ -1,9 +1,9 @@
-<div>
+<div ng-controller="JsonEditorCtrl">
 
 	<div class="dashboard-editor-header">
 		<div class="dashboard-editor-title">
 			<i class="icon icon-edit"></i>
-		  Edit / View JSON
+		  JSON
 		</div>
 	</div>
 
@@ -12,6 +12,7 @@
 	</div>
 
 	<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>
 	</div>
 

+ 11 - 0
src/app/services/panelSrv.js

@@ -52,6 +52,13 @@ function (angular, _) {
           ],
           condition: true
         },
+        {
+          text: 'Advanced',
+          submenu: [
+            { text: 'Panel JSON', click: 'editPanelJson()' },
+          ],
+          condition: true
+        },
         {
           text: 'Remove',
           click: 'remove_panel_from_row(row, panel)',
@@ -62,6 +69,10 @@ function (angular, _) {
       $scope.inspector = {};
       $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.panel.span = span;