Commit 331b50dc by Torkel Ödegaard

grid: edit/view now works

parent 9785e6b6
...@@ -49,6 +49,7 @@ export class PanelModel { ...@@ -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) {
......
...@@ -59,7 +59,8 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> { ...@@ -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> { ...@@ -93,7 +94,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
} }
} }
panelAdded() { triggerForceUpdate() {
this.forceUpdate(); this.forceUpdate();
} }
......
...@@ -9,7 +9,7 @@ function (angular, _, $, config) { ...@@ -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) { ...@@ -27,8 +27,8 @@ function (angular, _, $, config) {
} }
}); });
self.dashboard.on('view-mode-changed', function(panel) { $scope.onAppEvent('panel-change-view', function(evt, payload) {
self.update({fullscreen: panel.fullscreen, edit: panel.isEditing}); self.update(payload);
}); });
$scope.onAppEvent('panel-initialized', function(evt, payload) { $scope.onAppEvent('panel-initialized', function(evt, payload) {
...@@ -155,13 +155,17 @@ function (angular, _, $, config) { ...@@ -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) { ...@@ -176,9 +180,8 @@ function (angular, _, $, config) {
this.oldTimeRange = ctrl.range; this.oldTimeRange = ctrl.range;
this.fullscreenPanel = panelScope; this.fullscreenPanel = panelScope;
$timeout(function() { this.dashboard.setViewMode(ctrl.panel, true, ctrl.editMode);
ctrl.render(); this.$scope.appEvent('panel-fullscreen-enter', {panelId: ctrl.panel.id});
});
}; };
DashboardViewState.prototype.registerPanel = function(panelScope) { DashboardViewState.prototype.registerPanel = function(panelScope) {
......
...@@ -72,7 +72,9 @@ export class PanelCtrl { ...@@ -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() {
......
...@@ -54,7 +54,6 @@ function graphDirective($rootScope, timeSrv, popoverSrv, contextSrv) { ...@@ -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;
......
...@@ -65,7 +65,7 @@ describe('grafanaGraph', function() { ...@@ -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();
......
...@@ -3,4 +3,22 @@ ...@@ -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;
}
} }
declare let helpers: any;
export default helpers;
define([ import _ from 'lodash';
'lodash', import config from 'app/core/config';
'app/core/config', import * as dateMath from 'app/core/utils/datemath';
'app/core/utils/datemath', import {angularMocks, sinon} from '../lib/common';
], function(_, config, dateMath) { import {PanelModel} from 'app/features/dashboard/PanelModel';
'use strict';
export function ControllerTestContext() {
function ControllerTestContext() {
var self = this; var self = this;
this.datasource = {}; this.datasource = {};
...@@ -19,13 +18,13 @@ define([ ...@@ -19,13 +18,13 @@ define([
return { return {
then: function(callback) { then: function(callback) {
callback(self.datasource); callback(self.datasource);
} },
}; };
} },
}; };
this.providePhase = function(mocks) { this.providePhase = function(mocks) {
return window.module(function($provide) { return angularMocks.module(function($provide) {
$provide.value('datasourceSrv', self.datasourceSrv); $provide.value('datasourceSrv', self.datasourceSrv);
$provide.value('annotationsSrv', self.annotationsSrv); $provide.value('annotationsSrv', self.annotationsSrv);
$provide.value('timeSrv', self.timeSrv); $provide.value('timeSrv', self.timeSrv);
...@@ -38,35 +37,41 @@ define([ ...@@ -38,35 +37,41 @@ define([
}; };
this.createPanelController = function(Ctrl) { this.createPanelController = function(Ctrl) {
return window.inject(function($controller, $rootScope, $q, $location, $browser) { return angularMocks.inject(function($controller, $rootScope, $q, $location, $browser) {
self.scope = $rootScope.$new(); self.scope = $rootScope.$new();
self.$location = $location; self.$location = $location;
self.$browser = $browser; self.$browser = $browser;
self.$q = $q; self.$q = $q;
self.panel = {type: 'test'}; self.panel = new PanelModel({type: 'test'});
self.dashboard = {meta: {}}; self.dashboard = {meta: {}};
$rootScope.appEvent = sinon.spy(); $rootScope.appEvent = sinon.spy();
$rootScope.onAppEvent = sinon.spy(); $rootScope.onAppEvent = sinon.spy();
$rootScope.colors = []; $rootScope.colors = [];
for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); } for (var i = 0; i < 50; i++) {
$rootScope.colors.push('#' + i);
}
config.panels['test'] = {info: {}}; config.panels['test'] = {info: {}};
self.ctrl = $controller(Ctrl, {$scope: self.scope}, { self.ctrl = $controller(
panel: self.panel, dashboard: self.dashboard, row: {} Ctrl,
}); {$scope: self.scope},
{
panel: self.panel,
dashboard: self.dashboard,
},
);
}); });
}; };
this.createControllerPhase = function(controllerName) { this.createControllerPhase = function(controllerName) {
return window.inject(function($controller, $rootScope, $q, $location, $browser) { return angularMocks.inject(function($controller, $rootScope, $q, $location, $browser) {
self.scope = $rootScope.$new(); self.scope = $rootScope.$new();
self.$location = $location; self.$location = $location;
self.$browser = $browser; self.$browser = $browser;
self.scope.contextSrv = {}; self.scope.contextSrv = {};
self.scope.panel = {}; self.scope.panel = {};
self.scope.row = { panels:[] };
self.scope.dashboard = {meta: {}}; self.scope.dashboard = {meta: {}};
self.scope.dashboardMeta = {}; self.scope.dashboardMeta = {};
self.scope.dashboardViewState = new DashboardViewStateStub(); self.scope.dashboardViewState = new DashboardViewStateStub();
...@@ -74,19 +79,21 @@ define([ ...@@ -74,19 +79,21 @@ define([
self.scope.onAppEvent = sinon.spy(); self.scope.onAppEvent = sinon.spy();
$rootScope.colors = []; $rootScope.colors = [];
for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); } for (var i = 0; i < 50; i++) {
$rootScope.colors.push('#' + i);
}
self.$q = $q; self.$q = $q;
self.scope.skipDataOnInit = true; self.scope.skipDataOnInit = true;
self.scope.skipAutoInit = true; self.scope.skipAutoInit = true;
self.controller = $controller(controllerName, { self.controller = $controller(controllerName, {
$scope: self.scope $scope: self.scope,
}); });
}); });
}; };
} }
function ServiceTestContext() { export function ServiceTestContext() {
var self = this; var self = this;
self.templateSrv = new TemplateSrvStub(); self.templateSrv = new TemplateSrvStub();
self.timeSrv = new TimeSrvStub(); self.timeSrv = new TimeSrvStub();
...@@ -95,7 +102,7 @@ define([ ...@@ -95,7 +102,7 @@ define([
self.$routeParams = {}; self.$routeParams = {};
this.providePhase = function(mocks) { this.providePhase = function(mocks) {
return window.module(function($provide) { return angularMocks.module(function($provide) {
_.each(mocks, function(key) { _.each(mocks, function(key) {
$provide.value(key, self[key]); $provide.value(key, self[key]);
}); });
...@@ -103,7 +110,7 @@ define([ ...@@ -103,7 +110,7 @@ define([
}; };
this.createService = function(name) { this.createService = function(name) {
return window.inject(function($q, $rootScope, $httpBackend, $injector, $location, $timeout) { return angularMocks.inject(function($q, $rootScope, $httpBackend, $injector, $location, $timeout) {
self.$q = $q; self.$q = $q;
self.$rootScope = $rootScope; self.$rootScope = $rootScope;
self.$httpBackend = $httpBackend; self.$httpBackend = $httpBackend;
...@@ -116,23 +123,22 @@ define([ ...@@ -116,23 +123,22 @@ define([
self.service = $injector.get(name); self.service = $injector.get(name);
}); });
}; };
} }
function DashboardViewStateStub() { export function DashboardViewStateStub() {
this.registerPanel = function() { this.registerPanel = function() {};
}; }
}
function TimeSrvStub() { export function TimeSrvStub() {
this.init = sinon.spy(); this.init = sinon.spy();
this.time = { from:'now-1h', to: 'now'}; this.time = {from: 'now-1h', to: 'now'};
this.timeRange = function(parse) { this.timeRange = function(parse) {
if (parse === false) { if (parse === false) {
return this.time; return this.time;
} }
return { return {
from : dateMath.parse(this.time.from, false), from: dateMath.parse(this.time.from, false),
to : dateMath.parse(this.time.to, true) to: dateMath.parse(this.time.to, true),
}; };
}; };
...@@ -143,38 +149,47 @@ define([ ...@@ -143,38 +149,47 @@ define([
this.setTime = function(time) { this.setTime = function(time) {
this.time = time; this.time = time;
}; };
} }
function ContextSrvStub() { export function ContextSrvStub() {
this.hasRole = function() { this.hasRole = function() {
return true; return true;
}; };
} }
function TemplateSrvStub() { export function TemplateSrvStub() {
this.variables = []; this.variables = [];
this.templateSettings = { interpolate : /\[\[([\s\S]+?)\]\]/g }; this.templateSettings = {interpolate: /\[\[([\s\S]+?)\]\]/g};
this.data = {}; this.data = {};
this.replace = function(text) { this.replace = function(text) {
return _.template(text, this.templateSettings)(this.data); return _.template(text, this.templateSettings)(this.data);
}; };
this.init = function() {}; this.init = function() {};
this.getAdhocFilters = function() { return []; }; this.getAdhocFilters = function() {
return [];
};
this.fillVariableValuesForUrl = function() {}; this.fillVariableValuesForUrl = function() {};
this.updateTemplateData = function() { }; this.updateTemplateData = function() {};
this.variableExists = function() { return false; }; this.variableExists = function() {
this.variableInitialized = function() { }; return false;
this.highlightVariablesAsHtml = function(str) { return str; }; };
this.variableInitialized = function() {};
this.highlightVariablesAsHtml = function(str) {
return str;
};
this.setGrafanaVariable = function(name, value) { this.setGrafanaVariable = function(name, value) {
this.data[name] = value; this.data[name] = value;
}; };
} }
return { var allDeps = {
ControllerTestContext: ControllerTestContext,
TimeSrvStub: TimeSrvStub,
ContextSrvStub: ContextSrvStub, ContextSrvStub: ContextSrvStub,
ServiceTestContext: ServiceTestContext TemplateSrvStub: TemplateSrvStub,
}; TimeSrvStub: TimeSrvStub,
ControllerTestContext: ControllerTestContext,
ServiceTestContext: ServiceTestContext,
DashboardViewStateStub: DashboardViewStateStub
};
}); // for legacy
export default allDeps;
(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);
});
})();
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