Added column panel, refactored panel adding from rows to include panel specific parameters. Moved call to init function to template to avoid double init

This commit is contained in:
Rashid Khan 2013-03-05 09:54:29 -07:00
parent 30f036ad3e
commit 8e15414852
43 changed files with 205 additions and 67 deletions

View File

@ -1,6 +1,8 @@
/*
elasticsearch: URL to your elasticsearch server
kibana_index: The default ES index to use for storing Kibana specific object
such as stored dashboards
timeformat: Format for time in histograms (might go away)
modules: Panel modules to load. In the future these will be inferred
from your initial dashboard, though if you share dashboards you
@ -13,9 +15,11 @@ If you need to configure the default dashboard, please see dashboard.js
*/
var config = new Settings(
{
elasticsearch: 'http://localhost:9200',
elasticsearch: 'http://demo.kibana.org',
kibana_index: "kibana-int",
timeformat: 'mm/dd HH:MM:ss',
modules: ['histogram','map','pie','table','stringquery','sort',
'timepicker','text','fields','hits','dashcontrol'],
'timepicker','text','fields','hits','dashcontrol',
'column'],
}
);

View File

@ -65,6 +65,11 @@ angular.module('kibana.controllers', [])
$scope.global_alert = []
}
$scope.edit_path = function(type) {
if(type)
return 'panels/'+type+'/editor.html';
}
$scope.init();
})

View File

@ -2,4 +2,9 @@
/*global angular:true */
'use strict';
angular.module('kibana.filters', [])
angular.module('kibana.filters', [])
.filter('stringSort', function() {
return function(input) {
return input.sort();
}
});

33
panels/column/editor.html Normal file
View File

@ -0,0 +1,33 @@
<div ng-controller="column">
<div class="row-fluid">
<h4>Add Panel to Column</h4>
<select class="input-medium" ng-model="new_panel.type" ng-options="f for f in _.without(config.modules,'column')| stringSort" ng-change="reset_panel(new_panel.type);send_render();"></select>
<small>Select Type</small>
<div ng-show="!(_.isUndefined(new_panel.type))">
<div column-edit panel="new_panel" config="config" row="row" dashboards="dashboards" type="new_panel.type"></div>
<button ng-click="add_panel(new_panel); reset_panel();" class="btn btn-primary">Create Panel</button><br>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<h4>Panels</h4>
<table class="table table-condensed table-striped">
<thead>
<th>Title</th>
<th>Type</th>
<th>Height</th>
<th>Delete</th>
<th>Move</th>
</thead>
<tr ng-repeat="app in panel.panels">
<td>{{app.title}}</td>
<td>{{app.type}}</td>
<td><input type="text" class="input-small" ng-model="app.height"></input></td>
<td><i ng-click="panel.panels = _.without(panel.panels,app)" class="pointer icon-remove"></i></td>
<td><i ng-click="_.move(panel.panels,$index,$index-1)" ng-hide="$first" class="pointer icon-arrow-up"></i></td>
<td><i ng-click="_.move(panel.panels,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>
</tr>
</table>
</div>
</div>
</div>

17
panels/column/module.html Normal file
View File

@ -0,0 +1,17 @@
<kibana-panel ng-controller="column" ng-init="init();">
<!-- Panels -->
<div ng-repeat="(name, panel) in panel.panels" ng-hide="panel.height == '0px'" class="row-fluid panel" style="min-height:{{panel.height}}; position:relative">
<!-- Error Panel -->
<div class="row-fluid">
<div class="span12 alert alert-error panel-error" ng-hide="!panel.error">
<a class="close" ng-click="panel.error=false">&times;</a>
<i class="icon-exclamation-sign"></i> <strong>Oops!</strong> {{panel.error}}
</div>
</div>
<!-- Content Panel -->
<div class="row-fluid">
<div class="span12" style="margin-top:0px" ng-include="'panels/'+panel.type+'/module.html'"></div>
</div>
</div>
</kibana-panel>

76
panels/column/module.js Normal file
View File

@ -0,0 +1,76 @@
angular.module('kibana.column', [])
.controller('column', function($scope, $rootScope) {
// Set and populate defaults
var _d = {
panels : [
]
}
_.defaults($scope.panel,_d);
$scope.init = function(){
$scope.reset_panel();
}
$scope.toggle_row = function(panel) {
panel.collapse = panel.collapse ? false : true;
if (!panel.collapse) {
$timeout(function() {
$scope.send_render();
});
}
}
$scope.send_render = function() {
$scope.$broadcast('render');
}
$scope.add_panel = function(panel) {
$scope.panel.panels.push(panel);
}
$scope.reset_panel = function(type) {
$scope.new_panel = {
loading: false,
error: false,
sizeable: false,
span: 12,
height: "150px",
editable: true,
group: ['default'],
type: type,
};
};
})
.directive('columnEdit', function($compile,$timeout) {
return {
scope : {
new_panel:"=panel",
row:"=",
config:"=",
dashboards:"=",
type:"=type"
},
link: function(scope, elem, attrs, ctrl) {
scope.$on('render', function () {
// Make sure the digest has completed and populated the attributes
$timeout(function() {
// Create a reference to the new_panel as panel so that the existing
// editors work with our isolate scope
scope.panel = scope.new_panel
var template = '<div ng-include src="\'panels/column/panelgeneral.html\'"></div>'
if(!(_.isUndefined(scope.type)) && scope.type != "")
template = template+'<div ng-include src="\'panels/'+scope.type+'/editor.html\'"></div>';
//var new_elem = $compile(angular.element(template))(scope))
elem.html($compile(angular.element(template))(scope));
})
})
}
}
}).filter('withoutColumn', function() {
return function() {
return _.without(config.modules,'column');
};
});

View File

@ -0,0 +1,14 @@
<div class="row-fluid">
<div class="span4">
<label class="small">Title</label><input type="text" class="input-medium" ng-model='panel.title'></input>
</div>
<div class="span4">
<label class="small">Group(s) (comma seperated)</label><input array-join type="text" class="input-medium" ng-model='panel.group'></input>
</div>
<div class="span2">
<label class="small">Height</label> <input type="text" class="input-mini" ng-model='panel.height'></input>
</div>
<div class="span1">
<label class="small"> Editable </label><input type="checkbox" ng-model="panel.editable" ng-checked="panel.editable">
</div>
</div>

View File

@ -1,4 +1,4 @@
<div>
<div ng-controller="dashcontrol">
<h5>Allow saving to</h5>
<div class="row-fluid">
<div class="span2">

View File

@ -1,4 +1,4 @@
<kibana-panel ng-controller='dashcontrol'>
<kibana-panel ng-controller='dashcontrol' ng-init="init()">
<label class='small'>Dashboard Control</label>
<button class='btn' ng-show="panel.load.gist || panel.load.elasticsearch || panel.load.local" data-placement="bottom" data-unique="1" ng-click="elasticsearch_dblist(elasticsearch.query)" bs-popover="'panels/dashcontrol/load.html'"><i class='icon-folder-open'></i> <i class='icon-caret-down'></i></button>
<button class='btn' ng-show="panel.save.gist || panel.save.elasticsearch || panel.save.local || panel.save.default" data-placement="bottom" data-unique="1" bs-popover="'panels/dashcontrol/save.html'"><i class='icon-save'></i> <i class='icon-caret-down'></i></button>

View File

@ -245,9 +245,6 @@ angular.module('kibana.dashcontrol', [])
return false
}
$scope.init();
})
.directive('dashUpload', function(timer, eventBus){
return {

View File

@ -1,4 +1,4 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller="fields">
<div class="span3"><h6>Popup Position</h6>
<select class="input-small" ng-model="panel.micropanel_position" ng-options="f for f in ['top','right','bottom','left']" ng-change="reload_list();"></select></span>
</div>

View File

@ -1,4 +1,4 @@
<kibana-panel ng-controller='fields'>
<kibana-panel ng-controller='fields' ng-init="init()">
<ul class="unstyled" style="height:{{row.height}};overflow-y:auto;overflow-x:hidden;" ng-class="{'inline': panel.arrange == 'horizontal'}">
<li ng-style="panel.style" ng-repeat="field in fields" >
<i class="pointer" ng-class="{'icon-check': _.indexOf(active,field)>-1,'icon-check-empty': _.indexOf(active,field)<0}" ng-click="toggle_field(field)"></i>

View File

@ -64,5 +64,4 @@ angular.module('kibana.fields', [])
return _.indexOf($scope.active,field) > -1 ? ['label','label-info'] : '';
}
$scope.init();
})

View File

@ -1,4 +1,4 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller='histogram'>
<div class="span3">
<form style="margin-bottom: 0px">
<h6>Label</h6>

View File

@ -1,3 +1,3 @@
<kibana-panel ng-controller='histogram' style="height:{{row.height}}">
<div histogram params="{{panel}}" style="height:{{row.height}};position:relative"></div>
<kibana-panel ng-controller='histogram' ng-init="init()" style="height:{{row.height}}">
<div histogram params="{{panel}}" style="height:{{panel.height}};position:relative"></div>
</kibana-panel>

View File

@ -7,6 +7,7 @@ angular.module('kibana.histogram', [])
interval: secondsToHms(calculate_interval($scope.from,$scope.to,40,0)/1000),
show : ['bars','y-axis','x-axis','legend'],
fill : 3,
height : $scope.panel.height || $scope.row.height,
timezone: 'browser', // browser, utc or a standard timezone
group : "default",
}
@ -128,9 +129,6 @@ angular.module('kibana.histogram', [])
$scope.get_data();
}
// Ready, init
$scope.init();
})
.directive('histogram', function() {
return {
@ -173,7 +171,7 @@ angular.module('kibana.histogram', [])
// Populate element. Note that jvectormap appends, does not replace.
scripts.wait(function(){
// Populate element
$.plot(elem, scope.data, {
try { $.plot(elem, scope.data, {
legend: {
show: show.legend,
position: "nw",
@ -206,6 +204,9 @@ angular.module('kibana.histogram', [])
hoverable: true,
}
})
} catch(e) {
console.log(e)
}
})
function tt(x, y, contents) {

View File

@ -1,4 +1,4 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller="hits">
<div class="span11">
The hits panel shows a simple count of how many records match your filtered query. If multiple queries are sent from a single panel the <strong>first query will be displayed</strong>
</div>

View File

@ -1,3 +1,3 @@
<kibana-panel ng-controller='hits'>
<kibana-panel ng-controller='hits' ng-init="init()">
<p ng-style="panel.style">{{hits}}</p>
</kibana-panel>

View File

@ -56,6 +56,4 @@ angular.module('kibana.hits', [])
$scope.get_data();
}
$scope.init();
})

View File

@ -1,10 +1,16 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller="map">
<div class="span11">
The map panel uses 2 letter country or US state codes to plot concentrations on a map. Darker terroritories mean more records matched that area. If multiple queries are sent from a single panel the <strong>first query will be displayed</strong>
</div>
</div>
<div class="row-fluid">
<div class="span3">
<form>
<h6>Field</h6>
<input type="text" class="input-small" ng-model="panel.field">
</form>
</div>
<div class="span6">
<form class="input-append">
<h6>Query</h6>
@ -12,13 +18,6 @@
<button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
</form>
</div>
<div class="span4">
<form class="input-append">
<h6>Field</h6>
<input type="text" class="input-small" ng-model="panel.field">
<button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
</form>
</div>
<div class="span1"><h6>Map</h6>
<select ng-change="$emit('render')" class="input-small" ng-model="panel.map" ng-options="f for f in ['world','europe','usa']"></select>
</div>

View File

@ -1,3 +1,3 @@
<kibana-panel ng-controller='map'>
<div map params="{{panel}}" style="height:{{row.height}}"></div>
<kibana-panel ng-controller='map' ng-init="init()">
<div map params="{{panel}}" style="height:{{panel.height}}"></div>
</kibana-panel>

View File

@ -8,6 +8,7 @@ angular.module('kibana.map', [])
colors : ['#C8EEFF', '#0071A4'],
size : 100,
exclude : [],
height : $scope.panel.height || $scope.row.height,
group : "default",
}
_.defaults($scope.panel,_d)
@ -63,8 +64,6 @@ angular.module('kibana.map', [])
$scope.get_data();
}
$scope.init()
})
.directive('map', function() {
return {

View File

@ -1,4 +1,4 @@
<div class="row-fluid" ng-switch="panel.mode">
<div class="row-fluid" ng-switch="panel.mode" ng-controller="pie">
<div ng-switch-when="terms">
<div class="row-fluid">
<div class="span4">

View File

@ -1,3 +1,3 @@
<kibana-panel ng-controller='pie'>
<div pie params="{{panel}}" style="height:{{row.height}};position:relative"></div>
<kibana-panel ng-controller='pie' ng-init="init()">
<div pie params="{{panel}}" style="height:{{panel.height}};position:relative"></div>
</kibana-panel>

View File

@ -4,6 +4,7 @@ angular.module('kibana.pie', [])
// Set and populate defaults
var _d = {
query : { field:"_all", query:"*", goal: 1},
height : $scope.panel.height || $scope.row.height,
size : 10,
exclude : [],
donut : false,
@ -178,10 +179,7 @@ angular.module('kibana.pie', [])
$scope.panel.index = _.isUndefined(time.index) ? $scope.panel.index : time.index
$scope.get_data();
}
// Ready, init
$scope.init()
})
.directive('pie', function() {
return {

View File

@ -1,4 +1,4 @@
<kibana-panel ng-controller='sort' style="white-space: nowrap;">
<kibana-panel ng-controller='sort' ng-init="init()" style="white-space: nowrap;">
<label><small>{{panel.label}}</small></label>
<select style="width:85%" ng-model="panel.sort[0]" ng-change="set_sort()" ng-options="f for f in fields"></select>
<i ng-click="toggle_sort()" class="pointer" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>

View File

@ -25,6 +25,4 @@ angular.module('kibana.sort', [])
$scope.panel.sort[1] = $scope.panel.sort[1] == 'asc' ? 'desc' : 'asc';
$scope.set_sort();
}
$scope.init();
})

View File

@ -1,4 +1,4 @@
<div>
<div ng-controller="stringquery">
<div class="row-fluid">
<div class="span3">
<label class="small">Mulit Query</label><input type="checkbox" ng-change="set_multi(panel.multi) "ng-model="panel.multi" ng-checked="panel.multi">

View File

@ -1,4 +1,4 @@
<kibana-panel ng-controller='stringquery'>
<kibana-panel ng-controller='stringquery' ng-init="init()">
<div ng-show="!panel.multi">
<form>
<table class="form-horizontal">

View File

@ -58,5 +58,4 @@ angular.module('kibana.stringquery', [])
$scope.panel.query.splice(index,1);
}
$scope.init();
});

View File

@ -1,4 +1,4 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller="table">
<div class="span12">
<form class="input-append">
<h5>Query</h5>

View File

@ -1,5 +1,5 @@
<kibana-panel ng-controller='table'>
<div style="height:{{row.height}};overflow-y:auto;overflow-x:auto">
<kibana-panel ng-controller='table' ng-init='init()'>
<div style="height:{{panel.height}};overflow-y:auto;overflow-x:auto">
<div class="row-fluid">
<div class="span1 offset3" style="text-align:right">
<i ng-click="panel.offset = 0;get_data();" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>

View File

@ -6,6 +6,7 @@ angular.module('kibana.table', [])
query : "*",
size : 100,
offset : 0,
height : $scope.panel.height || $scope.row.height,
sort : ['@timestamp','desc'],
group : "default",
style : {},
@ -137,6 +138,4 @@ angular.module('kibana.table', [])
$scope.get_data();
}
$scope.init();
});

View File

@ -1,4 +1,4 @@
<div>
<div ng-controller="text">
<label class="small">Font Size</label> <select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
<label class=small>Content</label>
<textarea ng-model="panel.content" rows="6" style="width:95%"></textarea>

View File

@ -1,3 +1,3 @@
<kibana-panel ng-controller='text'>
<kibana-panel ng-controller='text' ng-init="init()">
<p ng-show='!panel.allowhtml' ng-style="panel.style" ng-bind-html-unsafe="panel.content | striphtml | newlines"></p>
</kibana-panel>

View File

@ -11,7 +11,7 @@ angular.module('kibana.text', [])
$scope.init = function() {
}
$scope.init();
})
.filter('newlines', function(){
return function (input) {

View File

@ -1,4 +1,4 @@
<div class="row-fluid">
<div class="row-fluid" ng-controller="timepicker">
<div class="span3">
<h6>Default Mode</h6>
<select style="width:85%" ng-model="panel.mode" ng-options="f for f in ['relative','absolute','since']"></select>

View File

@ -1,4 +1,4 @@
<kibana-panel ng-controller='timepicker' style="white-space: nowrap;">
<kibana-panel ng-controller='timepicker' ng-init="init()" style="white-space: nowrap;">
<div class="row-fluid" ng-switch="panel.mode">
<div ng-switch-when="absolute">
<div class="span5">

View File

@ -271,7 +271,4 @@ angular.module('kibana.timepicker', [])
}
}
// Great, every function is ready, init.
$scope.init();
})

View File

@ -1,7 +1,7 @@
<div class="row-fluid container" style="margin-top:50px">
<!-- Rows -->
<div ng-controller="dashcontrol"></div>
<div ng-controller="dashcontrol" ng-init="init()"></div>
<div class="row-fluid" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboards.rows">
<div class="span12">
<div class="row-fluid row-header" style="padding:0px;margin:0px;height:0px">

View File

@ -9,9 +9,9 @@
<h4 style="text-transform: capitalize;">{{panel.type}} <small> panel settings</small></h4>
<div ng-include src="'panels/'+panel.type+'/editor.html'">No additional settings are available for this type of panel.</div>
<div ng-include src="edit_path(panel.type)">No additional settings are available for this type of panel.</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" ng-click="dismiss();$broadcast('render')">Close</button>
<button type="button" class="btn btn-success" ng-click="dismiss();send_render()">Close</button>
</div>

View File

@ -5,7 +5,7 @@
<div class="span4">
<label class="small">Group(s) (comma seperated)</label><input array-join type="text" class="input-medium" ng-model='panel.group'></input>
</div>
<div class="span2">
<div class="span2" ng-hide="panel.sizeable == false">
<label class="small">Span</label> <select class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
</div>
<div class="span1">

View File

@ -17,12 +17,12 @@
</div>
<div class="row-fluid">
<h4>New Panel</h4>
<select class="input-medium" ng-model="panel.type" ng-options="f for f in config.modules"></select>
<select class="input-medium" ng-model="panel.type" ng-options="f for f in config.modules|stringSort"></select>
<small>Select Type</small>
<div ng-show="!(_.isUndefined(panel.type))">
<div ng-include src="'partials/panelgeneral.html'"></div>
<!--<div ng-include src="'panels/'+panel.type+'/editor.html'"></div>-->
<div ng-include src="edit_path(panel.type)"></div>
<button ng-click="add_panel(row,panel); reset_panel();" class="btn btn-primary">Create Panel</button><br>
</div>
</div>
@ -40,7 +40,7 @@
<tr ng-repeat="panel in row.panels">
<td>{{panel.title}}</td>
<td>{{panel.type}}</td>
<td><select class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select></td>
<td><select ng-hide="panel.sizeable == false" class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select></td>
<td><i ng-click="row.panels = _.without(row.panels,panel)" class="pointer icon-remove"></i></td>
<td><i ng-click="_.move(row.panels,$index,$index-1)" ng-hide="$first" class="pointer icon-arrow-up"></i></td>
<td><i ng-click="_.move(row.panels,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>