Commit 79404e75 by Torkel Ödegaard

started on some big refactoring of how the app starts and how dashboard object…

started on some big refactoring of how the app starts and how dashboard object is loaded, created. This should make it easier to add other dashboard storage backends and other views
parent 92318d58
......@@ -6,15 +6,16 @@ define([
'jquery',
'underscore',
'require',
'config',
'elasticjs',
'bootstrap',
'angular-sanitize',
'angular-strap',
'angular-dragdrop',
'extend-jquery',
'bindonce'
'bindonce',
],
function (angular, $, _, appLevelRequire) {
function (angular, $, _, appLevelRequire, config) {
"use strict";
......@@ -67,19 +68,7 @@ function (angular, $, _, appLevelRequire) {
app.config(function ($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
$routeProvider
.when('/dashboard', {
templateUrl: 'app/partials/dashboard.html',
})
.when('/dashboard/:kbnType/:kbnId', {
templateUrl: 'app/partials/dashboard.html',
})
.when('/dashboard/:kbnType/:kbnId/:params', {
templateUrl: 'app/partials/dashboard.html'
})
.otherwise({
redirectTo: 'dashboard'
});
$routeProvider.otherwise({ redirectTo: config.default_route });
// this is how the internet told me to dynamically add modules :/
register_fns.controller = $controllerProvider.register;
......@@ -98,7 +87,7 @@ function (angular, $, _, appLevelRequire) {
'pasvaz.bindonce'
];
var module_types = ['controllers', 'directives', 'factories', 'services', 'services.dashboard', 'filters'];
var module_types = ['controllers', 'directives', 'factories', 'services', 'filters', 'routes'];
_.each(module_types, function (type) {
var module_name = 'kibana.'+type;
......@@ -120,6 +109,7 @@ function (angular, $, _, appLevelRequire) {
'directives/all',
'filters/all',
'components/partials',
'routes/dashboard-loader',
], function () {
// bootstrap the app
......
......@@ -31,11 +31,9 @@ function (angular, $, config, _) {
var module = angular.module('kibana.controllers');
module.controller('DashCtrl', function(
$scope, $rootScope, $timeout, ejsResource, dashboard, filterSrv, dashboardKeybindings,
$scope, $rootScope, $timeout, ejsResource, filterSrv, dashboardKeybindings,
alertSrv, panelMove, keyboardManager, grafanaVersion) {
$scope.requiredElasticSearchVersion = ">=0.90.3";
$scope.editor = {
index: 0
};
......@@ -54,16 +52,8 @@ function (angular, $, config, _) {
// Make stuff, including underscore.js available to views
$scope._ = _;
$scope.dashboard = dashboard;
$scope.dashAlerts = alertSrv;
$scope.filter = filterSrv;
$scope.filter.init(dashboard.current);
$rootScope.$on("dashboard-loaded", function(event, dashboard) {
$scope.filter.init(dashboard);
});
// Clear existing alerts
alertSrv.clearAll();
......
......@@ -8,8 +8,7 @@ function (angular, _, moment) {
var module = angular.module('kibana.controllers');
module.controller('dashLoader', function($scope, $rootScope, $http, dashboard, alertSrv, $location, playlistSrv) {
$scope.loader = dashboard.current.loader;
module.controller('dashLoader', function($scope, $rootScope, $http, alertSrv, $location, playlistSrv) {
$scope.init = function() {
$scope.gist_pattern = /(^\d{5,}$)|(^[a-z0-9]{10,}$)|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
......@@ -23,6 +22,10 @@ function (angular, _, moment) {
$rootScope.$on('zoom-out', function() {
$scope.zoom(2);
});
$rootScope.$on('dashboard-loaded', function(event, dashboard) {
$scope.loader = dashboard.loader;
});
};
$scope.exitFullscreen = function() {
......@@ -30,11 +33,11 @@ function (angular, _, moment) {
};
$scope.showDropdown = function(type) {
if(_.isUndefined(dashboard.current.loader)) {
if(_.isUndefined($scope.loader)) {
return true;
}
var _l = dashboard.current.loader;
var _l = $scope.loader;
if(type === 'load') {
return (_l.load_elasticsearch || _l.load_gist || _l.load_local);
}
......@@ -129,7 +132,7 @@ function (angular, _, moment) {
// function $scope.zoom
// factor :: Zoom factor, so 0.5 = cuts timespan in half, 2 doubles timespan
$scope.zoom = function(factor) {
var _range = this.filter.timeRange();
var _range = $scope.filter.timeRange();
var _timespan = (_range.to.valueOf() - _range.from.valueOf());
var _center = _range.to.valueOf() - _timespan/2;
......@@ -143,7 +146,7 @@ function (angular, _, moment) {
_to = Date.now();
}
this.filter.setTime({
$scope.filter.setTime({
from:moment.utc(_from).toDate(),
to:moment.utc(_to).toDate(),
});
......
......@@ -15,8 +15,12 @@ function (angular, app, _) {
var lastPulldownVal;
var lastHideControlsVal;
$scope.$watch('dashboard.current.pulldowns', function() {
var panel = _.find($scope.dashboard.current.pulldowns, function(pulldown) { return pulldown.enable; });
$scope.$watch('dashboard.pulldowns', function() {
if (!$scope.dashboard) {
return;
}
var panel = _.find($scope.dashboard.pulldowns, function(pulldown) { return pulldown.enable; });
var panelEnabled = panel ? panel.enable : false;
if (lastPulldownVal !== panelEnabled) {
elem.toggleClass('submenu-controls-visible', panelEnabled);
......@@ -24,8 +28,12 @@ function (angular, app, _) {
}
}, true);
$scope.$watch('dashboard.current.hideControls', function() {
var hideControls = $scope.dashboard.current.hideControls || $scope.playlist_active;
$scope.$watch('dashboard.hideControls', function() {
if (!$scope.dashboard) {
return;
}
var hideControls = $scope.dashboard.hideControls || $scope.playlist_active;
if (lastHideControlsVal !== hideControls) {
elem.toggleClass('hide-controls', hideControls);
......
......@@ -10,13 +10,14 @@ function (angular, $, kbn, moment, _) {
var module = angular.module('kibana.directives');
module.directive('grafanaGraph', function($rootScope, dashboard) {
module.directive('grafanaGraph', function($rootScope) {
return {
restrict: 'A',
template: '<div> </div>',
link: function(scope, elem) {
var data, plot, annotations;
var hiddenData = {};
var dashboard = scope.dashboard;
scope.$on('refresh',function() {
if (scope.otherPanelInFullscreenMode()) { return; }
......@@ -172,7 +173,7 @@ function (angular, $, kbn, moment, _) {
var max = _.isUndefined(scope.range.to) ? null : scope.range.to.getTime();
options.xaxis = {
timezone: dashboard.current.timezone,
timezone: dashboard.timezone,
show: scope.panel['x-axis'],
mode: "time",
min: min,
......@@ -329,7 +330,7 @@ function (angular, $, kbn, moment, _) {
value = kbn.getFormatFunction(format, 2)(value);
timestamp = dashboard.current.timezone === 'browser' ?
timestamp = dashboard.timezone === 'browser' ?
moment(item.datapoint[0]).format('YYYY-MM-DD HH:mm:ss') :
moment.utc(item.datapoint[0]).format('YYYY-MM-DD HH:mm:ss');
$tooltip
......
......@@ -259,10 +259,11 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
targets: $scope.panel.targets,
format: $scope.panel.renderer === 'png' ? 'png' : 'json',
maxDataPoints: $scope.resolution,
datasource: $scope.panel.datasource
datasource: $scope.panel.datasource,
timezone: $scope.dashboard.timezone
};
$scope.annotationsPromise = annotationsSrv.getAnnotations($scope.filter, $scope.rangeUnparsed);
$scope.annotationsPromise = annotationsSrv.getAnnotations($scope.filter, $scope.rangeUnparsed, $scope.dashboard);
return $scope.datasource.query($scope.filter, graphiteQuery)
.then($scope.dataHandler)
......
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<span class="brand"><img src="img/small.png" bs-tooltip="'Grafana'" data-placement="bottom"> {{dashboard.title}}</span>
<ul class="nav pull-right" ng-controller='dashLoader' ng-init="init()" ng-include="'app/partials/dashLoader.html'">
</ul>
</div>
</div>
</div>
<div class="submenu-controls">
<div class="submenu-panel" ng-controller="SubmenuCtrl" ng-repeat="pulldown in dashboard.current.pulldowns | filter:{ enable: true }">
<div class="submenu-panel" ng-controller="SubmenuCtrl" ng-repeat="pulldown in dashboard.pulldowns | filter:{ enable: true }">
<div class="submenu-panel-title">
<span class="small"><strong>{{pulldown.type}}:</strong></span>
</div>
......@@ -15,7 +25,7 @@
<div>
<div class="grafana-container container">
<!-- Rows -->
<div class="kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboard.current.rows" ng-style="row_style(row)">
<div class="kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboard.rows" ng-style="row_style(row)">
<div class="row-control">
<div class="grafana-row" style="padding:0px;margin:0px;position:relative;">
<div class="row-close" ng-show="row.collapse" data-placement="bottom" >
......@@ -97,7 +107,7 @@
</div>
</div>
<div ng-show='dashboard.current.editable && dashboard.current.panel_hints' class="row-fluid add-row-panel-hint">
<div ng-show='dashboard.editable && dashboard.current.panel_hints' class="row-fluid add-row-panel-hint">
<div class="span12" style="text-align:right;">
<span style="margin-right: 10px;" ng-click="add_row_default()" class="pointer btn btn-info btn-mini">
<span><i class="icon-plus-sign"></i> ADD A ROW</span>
......
define([
'angular',
'jquery',
'config',
'underscore'
],
function (angular, $, config, _) {
"use strict";
var module = angular.module('kibana.routes');
module.config(function($routeProvider) {
$routeProvider
.when('/dashboard/file/:jsonFile', {
templateUrl: 'app/partials/dashboard.html',
controller : 'DashFromFileProvider',
});
});
module.controller('DashFromFileProvider', function($scope, $rootScope, $http, $routeParams, alertSrv, dashboard, filterSrv) {
$scope.init = function() {
console.log('DashFromFileProvider->init()')
file_load($routeParams.jsonFile)
.then(function(data) {
$scope.dashboard = dashboard.create(data);
$scope.filter = filterSrv;
$scope.filter.init($scope.dashboard);
$rootScope.$emit("dashboard-loaded", $scope.dashboard);
});
};
var renderTemplate = function(json,params) {
var _r;
_.templateSettings = {interpolate : /\{\{(.+?)\}\}/g};
var template = _.template(json);
var rendered = template({ARGS:params});
try {
_r = angular.fromJson(rendered);
} catch(e) {
_r = false;
}
return _r;
};
var file_load = function(file) {
return $http({
url: "app/dashboards/"+file.replace(/\.(?!json)/,"/")+'?' + new Date().getTime(),
method: "GET",
transformResponse: function(response) {
return renderTemplate(response,$routeParams);
}
}).then(function(result) {
if(!result) {
return false;
}
return result.data;
},function() {
alertSrv.set('Error',"Could not load <i>dashboards/"+file+"</i>. Please make sure it exists" ,'error');
return false;
});
};
$scope.init();
});
});
......@@ -7,20 +7,12 @@ define([
var module = angular.module('kibana.services');
module.service('annotationsSrv', function(dashboard, datasourceSrv, $q, alertSrv, $rootScope) {
module.service('annotationsSrv', function(datasourceSrv, $q, alertSrv, $rootScope) {
var promiseCached;
var annotationPanel;
var list = [];
this.init = function() {
$rootScope.$on('refresh', this.clearCache);
$rootScope.$on('dashboard-loaded', this.dashboardLoaded);
this.dashboardLoaded();
};
this.dashboardLoaded = function () {
annotationPanel = _.findWhere(dashboard.current.pulldowns, { type: 'annotations' });
};
this.clearCache = function() {
......@@ -28,7 +20,8 @@ define([
list = [];
};
this.getAnnotations = function(filterSrv, rangeUnparsed) {
this.getAnnotations = function(filterSrv, rangeUnparsed, dashboard) {
var annotationPanel = _.findWhere(dashboard.pulldowns, { type: 'annotations' });
if (!annotationPanel.enable) {
return $q.when(null);
}
......
......@@ -8,33 +8,28 @@ define([
'modernizr',
'filesaver'
],
function (angular, $, kbn, _, config, moment, Modernizr) {
function (angular, $, kbn, _) {
'use strict';
var module = angular.module('kibana.services');
module.service('dashboard', function(
$routeParams, $http, $rootScope, $injector, $location, $timeout,
ejsResource, timer, alertSrv, $q
) {
// A hash of defaults to use when loading a dashboard
var _dash = {
title: "",
tags: [],
style: "dark",
timezone: 'browser',
editable: true,
failover: false,
panel_hints: true,
rows: [],
pulldowns: [{ type: 'templating' }, { type: 'annotations' }],
nav: [{ type: 'timepicker' }],
services: {},
loader: {
module.service('dashboard', function(timer, $rootScope) {
function DashboardModel (data) {
this.title = data.title;
this.tags = data.tags || [];
this.style = data.style || "dark";
this.timezone = data.browser || 'browser';
this.editable = data.editble || true;
this.rows = data.rows || [];
this.pulldowns = data.pulldowns || [];
this.nav = data.nav || [];
this.services = data.services || {};
this.loader = data.loader;
_.defaults(this.loader, {
save_gist: false,
save_elasticsearch: true,
save_local: true,
save_default: true,
save_temp: true,
save_temp_ttl_enable: true,
......@@ -42,10 +37,64 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
load_gist: false,
load_elasticsearch: true,
load_elasticsearch_size: 20,
load_local: false,
hide: false
},
refresh: false
});
if (this.nav.length === 0) {
this.nav.push({ type: 'timepicker' });
}
if (!_.findWhere(this.pulldowns, {type: 'filtering'})) {
this.pulldowns.push({ type: 'filtering', enable: false });
}
if (!_.findWhere(this.pulldowns, {type: 'annotations'})) {
this.pulldowns.push({ type: 'annotations', enable: false });
}
_.each(this.rows, function(row) {
_.each(row.panels, function(panel) {
if (panel.type === 'graphite') {
panel.type = 'graph';
}
});
});
}
var p = DashboardModel.prototype;
p.refresh = function() {
$rootScope.$broadcast('refresh');
};
p.set_interval = function(interval) {
this.refresh = interval;
if (interval) {
var _i = kbn.interval_to_ms(interval);
timer.cancel(this.refresh_timer);
var dashboard_reference = this;
this.refresh_timer = timer.register($timeout(function() {
dashboard_reference.set_interval(interval);
dashboard_reference.full_refresh();
},_i));
this.full_refresh();
} else {
timer.cancel(this.refresh_timer);
}
};
return {
create: function(dashboard) {
return new DashboardModel(dashboard);
}
};
/*// A hash of defaults to use when loading a dashboard
var _dash = {
};
// An elasticJS client to use
......@@ -326,6 +375,7 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
})
.then(function(result) {
/*jshint -W054 */
/*
var script_func = new Function('ARGS','kbn','_','moment','window','document','$','jQuery', result.data);
var script_result = script_func($routeParams,kbn,_,moment, window, document, $, $);
......@@ -459,6 +509,7 @@ function (angular, $, kbn, _, config, moment, Modernizr) {
timer.cancel(self.refresh_timer);
}
};
});
*/
});
});
......@@ -6,7 +6,7 @@ define([
function(angular, $) {
"use strict";
var module = angular.module('kibana.services.dashboard');
var module = angular.module('kibana.services');
module.service('dashboardKeybindings', function($rootScope, keyboardManager, dashboard) {
this.shortcuts = function() {
......
......@@ -8,7 +8,7 @@ define([
var module = angular.module('kibana.services');
module.factory('filterSrv', function(dashboard, $rootScope, $timeout, $routeParams) {
module.factory('filterSrv', function($rootScope, $timeout, $routeParams) {
// defaults
var _d = {
templateParameters: [],
......@@ -53,16 +53,14 @@ define([
// disable refresh if we have an absolute time
if (time.to !== 'now') {
this.old_refresh = this.dashboard.refresh;
dashboard.set_interval(false);
this.dashboard.set_interval(false);
}
else if (this.old_refresh && this.old_refresh !== this.dashboard.refresh) {
dashboard.set_interval(this.old_refresh);
this.dashboard.set_interval(this.old_refresh);
this.old_refresh = null;
}
$timeout(function() {
dashboard.refresh();
},0);
$timeout(this.dashboard.refresh, 0);
},
timeRange: function(parse) {
......
......@@ -11,7 +11,7 @@ function (angular, _, $, config, kbn, moment) {
var module = angular.module('kibana.services');
module.factory('GraphiteDatasource', function(dashboard, $q, $http) {
module.factory('GraphiteDatasource', function($q, $http) {
function GraphiteDatasource(datasource) {
this.type = 'graphite';
......@@ -25,8 +25,8 @@ function (angular, _, $, config, kbn, moment) {
GraphiteDatasource.prototype.query = function(filterSrv, options) {
try {
var graphOptions = {
from: this.translateTime(options.range.from, 'round-down'),
until: this.translateTime(options.range.to, 'round-up'),
from: this.translateTime(options.range.from, options.timezone, 'round-down'),
until: this.translateTime(options.range.to, options.timezone, 'round-up'),
targets: options.targets,
format: options.format,
maxDataPoints: options.maxDataPoints,
......@@ -72,7 +72,7 @@ function (angular, _, $, config, kbn, moment) {
}
};
GraphiteDatasource.prototype.translateTime = function(date, rounding) {
GraphiteDatasource.prototype.translateTime = function(date, timezone, rounding) {
if (_.isString(date)) {
if (date === 'now') {
return 'now';
......@@ -104,7 +104,7 @@ function (angular, _, $, config, kbn, moment) {
}
}
if (dashboard.current.timezone === 'browser') {
if (timezone === 'browser') {
date = date.local();
}
......
......@@ -20,7 +20,7 @@
<body ng-cloak body-class>
<link rel="stylesheet" href="css/bootstrap.light.min.css" ng-if="dashboard.current.style === 'light'">
<link rel="stylesheet" href="css/bootstrap.light.min.css" ng-if="dashboard.style === 'light'">
<link rel="stylesheet" href="css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="css/font-awesome.min.css">
......@@ -28,15 +28,6 @@
<button type="button" class="close" ng-click="dashAlerts.clear(alert)" style="padding-right:50px">&times;</button>
<strong>{{alert.title}}</strong> <span ng-bind-html='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
</div>
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<span class="brand"><img src="img/small.png" bs-tooltip="'Grafana'" data-placement="bottom"> {{dashboard.current.title}}</span>
<ul class="nav pull-right" ng-controller='dashLoader' ng-init="init()" ng-include="'app/partials/dashLoader.html'">
</ul>
</div>
</div>
</div>
<div ng-view ng-class="{'dashboard-fullscreen': fullscreen}"></div>
......
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