Kaynağa Gözat

grid: edit/view now works

Torkel Ödegaard 8 yıl önce
ebeveyn
işleme
331b50dcaa

+ 1 - 0
public/app/features/dashboard/PanelModel.ts

@@ -49,6 +49,7 @@ export class PanelModel {
   setViewMode(fullscreen: boolean, isEditing: boolean) {
   setViewMode(fullscreen: boolean, isEditing: boolean) {
     this.fullscreen = fullscreen;
     this.fullscreen = fullscreen;
     this.isEditing = isEditing;
     this.isEditing = isEditing;
+    this.events.emit('panel-size-changed');
   }
   }
 
 
   updateGridPos(newPos: GridPos) {
   updateGridPos(newPos: GridPos) {

+ 3 - 2
public/app/features/dashboard/dashgrid/DashboardGrid.tsx

@@ -59,7 +59,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
 
 
     // subscribe to dashboard events
     // subscribe to dashboard events
     this.dashboard = this.panelContainer.getDashboard();
     this.dashboard = this.panelContainer.getDashboard();
-    this.dashboard.on('panel-added', this.panelAdded.bind(this));
+    this.dashboard.on('panel-added', this.triggerForceUpdate.bind(this));
+    this.dashboard.on('view-mode-changed', this.triggerForceUpdate.bind(this));
   }
   }
 
 
   buildLayout() {
   buildLayout() {
@@ -93,7 +94,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     }
     }
   }
   }
 
 
-  panelAdded() {
+  triggerForceUpdate() {
     this.forceUpdate();
     this.forceUpdate();
   }
   }
 
 

+ 11 - 8
public/app/features/dashboard/viewStateSrv.js

@@ -9,7 +9,7 @@ function (angular, _, $, config) {
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.factory('dashboardViewStateSrv', function($location, $timeout) {
+  module.factory('dashboardViewStateSrv', function($location, $timeout, $rootScope) {
 
 
     // represents the transient view state
     // represents the transient view state
     // like fullscreen panel & edit
     // like fullscreen panel & edit
@@ -27,8 +27,8 @@ function (angular, _, $, config) {
         }
         }
       });
       });
 
 
-      self.dashboard.on('view-mode-changed', function(panel) {
-        self.update({fullscreen: panel.fullscreen, edit: panel.isEditing});
+      $scope.onAppEvent('panel-change-view', function(evt, payload) {
+        self.update(payload);
       });
       });
 
 
       $scope.onAppEvent('panel-initialized', function(evt, payload) {
       $scope.onAppEvent('panel-initialized', function(evt, payload) {
@@ -155,13 +155,17 @@ function (angular, _, $, config) {
       ctrl.editMode = false;
       ctrl.editMode = false;
       ctrl.fullscreen = false;
       ctrl.fullscreen = false;
 
 
+      this.dashboard.setViewMode(ctrl.panel, false, false);
+
+      this.$scope.appEvent('panel-fullscreen-exit', {panelId: ctrl.panel.id});
+
       if (!render) { return false;}
       if (!render) { return false;}
 
 
       $timeout(function() {
       $timeout(function() {
         if (self.oldTimeRange !== ctrl.range) {
         if (self.oldTimeRange !== ctrl.range) {
-          self.$scope.broadcastRefresh();
+          $rootScope.$broadcast('refresh');
         } else {
         } else {
-          self.$scope.$broadcast('render');
+          $rootScope.$broadcast('render');
         }
         }
         delete self.fullscreenPanel;
         delete self.fullscreenPanel;
       });
       });
@@ -176,9 +180,8 @@ function (angular, _, $, config) {
       this.oldTimeRange = ctrl.range;
       this.oldTimeRange = ctrl.range;
       this.fullscreenPanel = panelScope;
       this.fullscreenPanel = panelScope;
 
 
-      $timeout(function() {
-        ctrl.render();
-      });
+      this.dashboard.setViewMode(ctrl.panel, true, ctrl.editMode);
+      this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id});
     };
     };
 
 
     DashboardViewState.prototype.registerPanel = function(panelScope) {
     DashboardViewState.prototype.registerPanel = function(panelScope) {

+ 3 - 1
public/app/features/panel/panel_ctrl.ts

@@ -72,7 +72,9 @@ export class PanelCtrl {
   }
   }
 
 
   changeView(fullscreen, edit) {
   changeView(fullscreen, edit) {
-    this.dashboard.setViewMode(this.panel, fullscreen, edit);
+    this.publishAppEvent('panel-change-view', {
+      fullscreen: fullscreen, edit: edit, panelId: this.panel.id
+    });
   }
   }
 
 
   viewPanel() {
   viewPanel() {

+ 0 - 1
public/app/plugins/panel/graph/graph.ts

@@ -54,7 +54,6 @@ function graphDirective($rootScope, timeSrv, popoverSrv, contextSrv) {
       });
       });
 
 
       ctrl.events.on('render', function(renderData) {
       ctrl.events.on('render', function(renderData) {
-        console.log('graph render');
         data = renderData || data;
         data = renderData || data;
         if (!data) {
         if (!data) {
           return;
           return;

+ 1 - 1
public/app/plugins/panel/graph/specs/graph_specs.ts

@@ -65,7 +65,7 @@ describe('grafanaGraph', function() {
 
 
           var scope = $rootScope.$new();
           var scope = $rootScope.$new();
           scope.ctrl = ctrl;
           scope.ctrl = ctrl;
-
+          scope.ctrl.events = ctrl.panel.events;
 
 
           $rootScope.onAppEvent = sinon.spy();
           $rootScope.onAppEvent = sinon.spy();
 
 

+ 18 - 0
public/sass/components/_dashboard_grid.scss

@@ -3,4 +3,22 @@
 
 
 .panel-in-fullscreen {
 .panel-in-fullscreen {
 
 
+  .react-grid-layout {
+    height: 100% !important;
+  }
+
+  .react-grid-item {
+    display: none;
+    transition-property: none !important;
+  }
+
+  .panel--fullscreen {
+    display: block !important;
+    position: unset !important;
+    width: 100% !important;
+    height: 100% !important;
+    transform: translate(0px, 0px) !important;
+  }
 }
 }
+
+

+ 0 - 4
public/test/specs/helpers.d.ts

@@ -1,4 +0,0 @@
-declare let helpers: any;
-export default helpers;
-
-

+ 0 - 180
public/test/specs/helpers.js

@@ -1,180 +0,0 @@
-define([
- 'lodash',
- 'app/core/config',
- 'app/core/utils/datemath',
-], function(_, config, dateMath) {
-  'use strict';
-
-  function ControllerTestContext() {
-    var self = this;
-
-    this.datasource = {};
-    this.$element = {};
-    this.annotationsSrv = {};
-    this.timeSrv = new TimeSrvStub();
-    this.templateSrv = new TemplateSrvStub();
-    this.datasourceSrv = {
-      getMetricSources: function() {},
-      get: function() {
-        return {
-          then: function(callback) {
-            callback(self.datasource);
-          }
-        };
-      }
-    };
-
-    this.providePhase = function(mocks) {
-      return window.module(function($provide) {
-        $provide.value('datasourceSrv', self.datasourceSrv);
-        $provide.value('annotationsSrv', self.annotationsSrv);
-        $provide.value('timeSrv', self.timeSrv);
-        $provide.value('templateSrv', self.templateSrv);
-        $provide.value('$element', self.$element);
-        _.each(mocks, function(value, key) {
-          $provide.value(key, value);
-        });
-      });
-    };
-
-    this.createPanelController = function(Ctrl) {
-      return window.inject(function($controller, $rootScope, $q, $location, $browser) {
-        self.scope = $rootScope.$new();
-        self.$location = $location;
-        self.$browser = $browser;
-        self.$q = $q;
-        self.panel = {type: 'test'};
-        self.dashboard = {meta: {}};
-
-        $rootScope.appEvent = sinon.spy();
-        $rootScope.onAppEvent = sinon.spy();
-        $rootScope.colors = [];
-
-        for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); }
-
-        config.panels['test'] = {info: {}};
-        self.ctrl = $controller(Ctrl, {$scope: self.scope}, {
-          panel: self.panel, dashboard: self.dashboard, row: {}
-        });
-      });
-    };
-
-    this.createControllerPhase = function(controllerName) {
-      return window.inject(function($controller, $rootScope, $q, $location, $browser) {
-        self.scope = $rootScope.$new();
-        self.$location = $location;
-        self.$browser = $browser;
-        self.scope.contextSrv = {};
-        self.scope.panel = {};
-        self.scope.row = { panels:[] };
-        self.scope.dashboard = {meta: {}};
-        self.scope.dashboardMeta = {};
-        self.scope.dashboardViewState = new DashboardViewStateStub();
-        self.scope.appEvent = sinon.spy();
-        self.scope.onAppEvent = sinon.spy();
-
-        $rootScope.colors = [];
-        for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); }
-
-        self.$q = $q;
-        self.scope.skipDataOnInit = true;
-        self.scope.skipAutoInit = true;
-        self.controller = $controller(controllerName, {
-          $scope: self.scope
-        });
-      });
-    };
-  }
-
-  function ServiceTestContext() {
-    var self = this;
-    self.templateSrv = new TemplateSrvStub();
-    self.timeSrv = new TimeSrvStub();
-    self.datasourceSrv = {};
-    self.backendSrv = {};
-    self.$routeParams = {};
-
-    this.providePhase = function(mocks) {
-      return window.module(function($provide) {
-        _.each(mocks, function(key) {
-          $provide.value(key, self[key]);
-        });
-      });
-    };
-
-    this.createService = function(name) {
-      return window.inject(function($q, $rootScope, $httpBackend, $injector, $location, $timeout) {
-        self.$q = $q;
-        self.$rootScope = $rootScope;
-        self.$httpBackend =  $httpBackend;
-        self.$location = $location;
-
-        self.$rootScope.onAppEvent = function() {};
-        self.$rootScope.appEvent = function() {};
-        self.$timeout = $timeout;
-
-        self.service = $injector.get(name);
-      });
-    };
-  }
-
-  function DashboardViewStateStub() {
-    this.registerPanel = function() {
-    };
-  }
-
-  function TimeSrvStub() {
-    this.init = sinon.spy();
-    this.time = { from:'now-1h', to: 'now'};
-    this.timeRange = function(parse) {
-      if (parse === false) {
-        return this.time;
-      }
-      return {
-        from : dateMath.parse(this.time.from, false),
-        to : dateMath.parse(this.time.to, true)
-      };
-    };
-
-    this.replace = function(target) {
-      return target;
-    };
-
-    this.setTime = function(time) {
-      this.time = time;
-    };
-  }
-
-  function ContextSrvStub() {
-    this.hasRole = function() {
-      return true;
-    };
-  }
-
-  function TemplateSrvStub() {
-    this.variables = [];
-    this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g };
-    this.data = {};
-    this.replace = function(text) {
-      return _.template(text, this.templateSettings)(this.data);
-    };
-    this.init = function() {};
-    this.getAdhocFilters = function() { return []; };
-    this.fillVariableValuesForUrl = function() {};
-    this.updateTemplateData = function() { };
-    this.variableExists = function() { return false; };
-    this.variableInitialized = function() { };
-    this.highlightVariablesAsHtml = function(str) { return str; };
-    this.setGrafanaVariable = function(name, value) {
-      this.data[name] = value;
-    };
-  }
-
-  return {
-    ControllerTestContext: ControllerTestContext,
-    TimeSrvStub: TimeSrvStub,
-    ContextSrvStub: ContextSrvStub,
-    ServiceTestContext: ServiceTestContext
-  };
-
-});

+ 195 - 0
public/test/specs/helpers.ts

@@ -0,0 +1,195 @@
+import _ from 'lodash';
+import config from 'app/core/config';
+import * as dateMath from 'app/core/utils/datemath';
+import {angularMocks, sinon} from '../lib/common';
+import {PanelModel} from 'app/features/dashboard/PanelModel';
+
+export function ControllerTestContext() {
+  var self = this;
+
+  this.datasource = {};
+  this.$element = {};
+  this.annotationsSrv = {};
+  this.timeSrv = new TimeSrvStub();
+  this.templateSrv = new TemplateSrvStub();
+  this.datasourceSrv = {
+    getMetricSources: function() {},
+    get: function() {
+      return {
+        then: function(callback) {
+          callback(self.datasource);
+        },
+      };
+    },
+  };
+
+  this.providePhase = function(mocks) {
+    return angularMocks.module(function($provide) {
+      $provide.value('datasourceSrv', self.datasourceSrv);
+      $provide.value('annotationsSrv', self.annotationsSrv);
+      $provide.value('timeSrv', self.timeSrv);
+      $provide.value('templateSrv', self.templateSrv);
+      $provide.value('$element', self.$element);
+      _.each(mocks, function(value, key) {
+        $provide.value(key, value);
+      });
+    });
+  };
+
+  this.createPanelController = function(Ctrl) {
+    return angularMocks.inject(function($controller, $rootScope, $q, $location, $browser) {
+      self.scope = $rootScope.$new();
+      self.$location = $location;
+      self.$browser = $browser;
+      self.$q = $q;
+      self.panel = new PanelModel({type: 'test'});
+      self.dashboard = {meta: {}};
+
+      $rootScope.appEvent = sinon.spy();
+      $rootScope.onAppEvent = sinon.spy();
+      $rootScope.colors = [];
+
+      for (var i = 0; i < 50; i++) {
+        $rootScope.colors.push('#' + i);
+      }
+
+      config.panels['test'] = {info: {}};
+      self.ctrl = $controller(
+        Ctrl,
+        {$scope: self.scope},
+        {
+          panel: self.panel,
+          dashboard: self.dashboard,
+        },
+      );
+    });
+  };
+
+  this.createControllerPhase = function(controllerName) {
+    return angularMocks.inject(function($controller, $rootScope, $q, $location, $browser) {
+      self.scope = $rootScope.$new();
+      self.$location = $location;
+      self.$browser = $browser;
+      self.scope.contextSrv = {};
+      self.scope.panel = {};
+      self.scope.dashboard = {meta: {}};
+      self.scope.dashboardMeta = {};
+      self.scope.dashboardViewState = new DashboardViewStateStub();
+      self.scope.appEvent = sinon.spy();
+      self.scope.onAppEvent = sinon.spy();
+
+      $rootScope.colors = [];
+      for (var i = 0; i < 50; i++) {
+        $rootScope.colors.push('#' + i);
+      }
+
+      self.$q = $q;
+      self.scope.skipDataOnInit = true;
+      self.scope.skipAutoInit = true;
+      self.controller = $controller(controllerName, {
+        $scope: self.scope,
+      });
+    });
+  };
+}
+
+export function ServiceTestContext() {
+  var self = this;
+  self.templateSrv = new TemplateSrvStub();
+  self.timeSrv = new TimeSrvStub();
+  self.datasourceSrv = {};
+  self.backendSrv = {};
+  self.$routeParams = {};
+
+  this.providePhase = function(mocks) {
+    return angularMocks.module(function($provide) {
+      _.each(mocks, function(key) {
+        $provide.value(key, self[key]);
+      });
+    });
+  };
+
+  this.createService = function(name) {
+    return angularMocks.inject(function($q, $rootScope, $httpBackend, $injector, $location, $timeout) {
+      self.$q = $q;
+      self.$rootScope = $rootScope;
+      self.$httpBackend = $httpBackend;
+      self.$location = $location;
+
+      self.$rootScope.onAppEvent = function() {};
+      self.$rootScope.appEvent = function() {};
+      self.$timeout = $timeout;
+
+      self.service = $injector.get(name);
+    });
+  };
+}
+
+export function DashboardViewStateStub() {
+  this.registerPanel = function() {};
+}
+
+export function TimeSrvStub() {
+  this.init = sinon.spy();
+  this.time = {from: 'now-1h', to: 'now'};
+  this.timeRange = function(parse) {
+    if (parse === false) {
+      return this.time;
+    }
+    return {
+      from: dateMath.parse(this.time.from, false),
+      to: dateMath.parse(this.time.to, true),
+    };
+  };
+
+  this.replace = function(target) {
+    return target;
+  };
+
+  this.setTime = function(time) {
+    this.time = time;
+  };
+}
+
+export function ContextSrvStub() {
+  this.hasRole = function() {
+    return true;
+  };
+}
+
+export function TemplateSrvStub() {
+  this.variables = [];
+  this.templateSettings = {interpolate: /\[\[([\s\S]+?)\]\]/g};
+  this.data = {};
+  this.replace = function(text) {
+    return _.template(text, this.templateSettings)(this.data);
+  };
+  this.init = function() {};
+  this.getAdhocFilters = function() {
+    return [];
+  };
+  this.fillVariableValuesForUrl = function() {};
+  this.updateTemplateData = function() {};
+  this.variableExists = function() {
+    return false;
+  };
+  this.variableInitialized = function() {};
+  this.highlightVariablesAsHtml = function(str) {
+    return str;
+  };
+  this.setGrafanaVariable = function(name, value) {
+    this.data[name] = value;
+  };
+}
+
+var allDeps = {
+  ContextSrvStub: ContextSrvStub,
+  TemplateSrvStub: TemplateSrvStub,
+  TimeSrvStub: TimeSrvStub,
+  ControllerTestContext: ControllerTestContext,
+  ServiceTestContext: ServiceTestContext,
+  DashboardViewStateStub: DashboardViewStateStub
+};
+
+// for legacy
+export default allDeps;

+ 0 - 130
public/test/test-main.js

@@ -1,130 +0,0 @@
-(function() {
-  "use strict";
-
-  // Tun on full stack traces in errors to help debugging
-  Error.stackTraceLimit=Infinity;
-
-  window.__karma__.loaded = function() {};
-
-  System.config({
-    baseURL: '/base/',
-    defaultJSExtensions: true,
-    paths: {
-      'mousetrap': 'vendor/npm/mousetrap/mousetrap.js',
-      'eventemitter3': 'vendor/npm/eventemitter3/index.js',
-      'remarkable': 'vendor/npm/remarkable/dist/remarkable.js',
-      'tether': 'vendor/npm/tether/dist/js/tether.js',
-      'tether-drop': 'vendor/npm/tether-drop/dist/js/drop.js',
-      'moment': 'vendor/moment.js',
-      "jquery": "vendor/jquery/dist/jquery.js",
-      'lodash-src': 'vendor/lodash/dist/lodash.js',
-      "lodash": 'app/core/lodash_extended.js',
-      "angular": 'vendor/angular/angular.js',
-      'angular-mocks': 'vendor/angular-mocks/angular-mocks.js',
-      "bootstrap":  "vendor/bootstrap/bootstrap.js",
-      'angular-route':          'vendor/angular-route/angular-route.js',
-      'angular-sanitize':       'vendor/angular-sanitize/angular-sanitize.js',
-      "angular-ui":             "vendor/angular-ui/ui-bootstrap-tpls.js",
-      "angular-strap":          "vendor/angular-other/angular-strap.js",
-      "angular-dragdrop":       "vendor/angular-native-dragdrop/draganddrop.js",
-      "angular-bindonce":       "vendor/angular-bindonce/bindonce.js",
-      "spectrum": "vendor/spectrum.js",
-      "bootstrap-tagsinput": "vendor/tagsinput/bootstrap-tagsinput.js",
-      "jquery.flot": "vendor/flot/jquery.flot",
-      "jquery.flot.pie": "vendor/flot/jquery.flot.pie",
-      "jquery.flot.selection": "vendor/flot/jquery.flot.selection",
-      "jquery.flot.stack": "vendor/flot/jquery.flot.stack",
-      "jquery.flot.stackpercent": "vendor/flot/jquery.flot.stackpercent",
-      "jquery.flot.time": "vendor/flot/jquery.flot.time",
-      "jquery.flot.crosshair": "vendor/flot/jquery.flot.crosshair",
-      "jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
-      "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
-      "d3": "vendor/d3/d3.js",
-      "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes",
-      "twemoji": "vendor/npm/twemoji/2/twemoji.amd.js",
-      "ace": "vendor/npm/ace-builds/src-noconflict/ace",
-    },
-
-    packages: {
-      app: {
-        defaultExtension: 'js',
-      },
-      vendor: {
-        defaultExtension: 'js',
-      },
-    },
-
-    map: {
-    },
-
-    meta: {
-      'vendor/angular/angular.js': {
-        format: 'global',
-        deps: ['jquery'],
-        exports: 'angular',
-      },
-      'vendor/angular-mocks/angular-mocks.js': {
-        format: 'global',
-        deps: ['angular'],
-      },
-      'vendor/npm/eventemitter3/index.js': {
-        format: 'cjs',
-        exports: 'EventEmitter'
-      },
-      'vendor/npm/mousetrap/mousetrap.js': {
-        format: 'global',
-        exports: 'Mousetrap'
-      },
-      'vendor/npm/ace-builds/src-noconflict/ace.js': {
-        format: 'global',
-        exports: 'ace'
-      },
-    }
-  });
-
-  function file2moduleName(filePath) {
-    return filePath.replace(/\\/g, '/')
-    .replace(/^\/base\//, '')
-      .replace(/\.\w*$/, '');
-  }
-
-  function onlySpecFiles(path) {
-    return /specs.*/.test(path);
-  }
-
-  window.grafanaBootData = {settings: {}};
-
-  var modules = ['angular', 'angular-mocks', 'app/app'];
-  var promises = modules.map(function(name) {
-    return System.import(name);
-  });
-
-  Promise.all(promises).then(function(deps) {
-    var angular = deps[0];
-
-    angular.module('grafana', ['ngRoute']);
-    angular.module('grafana.services', ['ngRoute', '$strap.directives']);
-    angular.module('grafana.panels', []);
-    angular.module('grafana.controllers', []);
-    angular.module('grafana.directives', []);
-    angular.module('grafana.filters', []);
-    angular.module('grafana.routes', ['ngRoute']);
-
-    // load specs
-    return Promise.all(
-      Object.keys(window.__karma__.files) // All files served by Karma.
-      .filter(onlySpecFiles)
-      .map(file2moduleName)
-      .map(function(path) {
-        // console.log(path);
-        return System.import(path);
-      }));
-  }).then(function()  {
-    window.__karma__.start();
-  }, function(error) {
-    window.__karma__.error(error.stack || error);
-  }).catch(function(error) {
-    window.__karma__.error(error.stack || error);
-  });
-
-})();