Commit e0c8d94c by Rashid Khan

Merge pull request #285 from rashidkpc/master

Upgraded font awesome, added collapsable field selector to table panel and deprecated fields panel
parents f8de0c76 f5072b26
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -27,8 +27,8 @@
],
"list": {
"0": {
"from": "2013-07-15T16:50:45.363Z",
"to": "2013-07-15T17:50:45.363Z",
"from": "2013-07-27T21:35:50.822Z",
"to": "2013-07-27T22:35:50.823Z",
"field": "@timestamp",
"type": "time",
"mandate": "must",
......@@ -51,7 +51,6 @@
"collapsable": true,
"panels": [
{
"loading": false,
"error": "",
"span": 5,
"editable": true,
......@@ -59,7 +58,6 @@
"default"
],
"type": "timepicker",
"status": "Stable",
"mode": "relative",
"time_options": [
"5m",
......@@ -80,10 +78,10 @@
"interval": 30,
"min": 3
},
"filter_id": 0
"filter_id": 0,
"status": "Stable"
},
{
"loading": false,
"error": false,
"span": 3,
"editable": true,
......@@ -91,7 +89,6 @@
"default"
],
"type": "dashcontrol",
"status": "Stable",
"save": {
"gist": false,
"elasticsearch": true,
......@@ -106,7 +103,8 @@
"hide_control": false,
"elasticsearch_size": 20,
"temp": true,
"temp_ttl": "30d"
"temp_ttl": "30d",
"ttl_enable": true
}
]
},
......@@ -118,7 +116,6 @@
"collapsable": true,
"panels": [
{
"loading": false,
"error": false,
"span": 12,
"editable": true,
......@@ -126,11 +123,11 @@
"default"
],
"type": "query",
"status": "Experimental",
"label": "Search",
"query": "*",
"history": [],
"remember": 10
"remember": 10,
"pinned": true,
"query": "*"
}
]
},
......@@ -142,15 +139,13 @@
"collapsable": true,
"panels": [
{
"loading": false,
"error": false,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "filtering",
"status": "Experimental"
"type": "filtering"
}
]
},
......@@ -162,20 +157,12 @@
"collapsable": true,
"panels": [
{
"loading": false,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "histogram",
"status": "Stable",
"query": [
{
"query": "*",
"label": "Query"
}
],
"mode": "count",
"time_field": "@timestamp",
"value_field": null,
......@@ -195,7 +182,13 @@
"x-axis": true,
"y-axis": true,
"percentage": false,
"interactive": true
"interactive": true,
"queries": {
"mode": "all",
"ids": [
0
]
}
}
]
},
......@@ -207,35 +200,13 @@
"collapsable": true,
"panels": [
{
"loading": false,
"error": false,
"span": 2,
"editable": true,
"group": [
"default"
],
"type": "fields",
"status": "Beta",
"style": {},
"arrange": "vertical",
"micropanel_position": "right",
"sort": [
"@timestamp",
"desc"
],
"query": "*"
},
{
"loading": false,
"error": false,
"span": 10,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "table",
"status": "Stable",
"query": "*",
"size": 100,
"pages": 5,
"offset": 0,
......@@ -255,7 +226,15 @@
"sortable": true,
"header": true,
"paging": true,
"spyable": true
"spyable": true,
"queries": {
"mode": "all",
"ids": [
0
]
},
"field_list": true,
"status": "Stable"
}
]
}
......@@ -266,4 +245,4 @@
"pattern": "[logstash-]YYYY.MM.DD",
"default": "logstash-*"
}
}
}
\ No newline at end of file
......@@ -131,7 +131,6 @@ angular.module('kibana.controllers', [])
$scope.reset_panel = function() {
$scope.panel = {
loading : false,
error : false,
span : 3,
editable: true,
......
......@@ -7,7 +7,7 @@ angular.module('kibana.directives', [])
return {
restrict: 'E',
link: function(scope, elem, attrs) {
var template = '<img src="common/img/load.gif" class="panel-loading" ng-show="panel.loading == true">'+
var template = '<img src="common/img/load.gif" class="panel-loading" ng-show="panelMeta.loading == true">'+
' <span class="editlink panelextra pointer" style="right:15px;top:0px" ' +
'bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
'<span class="small">{{panel.type}}</span> <i class="icon-cog pointer"></i> '+
......
......@@ -96,7 +96,7 @@ angular.module('kibana.bettermap', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = 0;
......@@ -174,7 +174,7 @@ angular.module('kibana.bettermap', [])
var map, markers, layerGroup, mcg;
function render_panel() {
scope.panel.loading = false;
scope.panelMeta.loading = false;
var scripts = $LAB.script("panels/bettermap/lib/leaflet.js").wait()
.script("panels/bettermap/lib/plugins.js");
......
......@@ -57,7 +57,7 @@ angular.module('kibana.derivequeries', [])
return;
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
var request = $scope.ejs.Request().indices(dashboard.indices);
// Terms mode
......@@ -78,7 +78,7 @@ angular.module('kibana.derivequeries', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
var suffix,
data = [];
if ($scope.panel.query === '' || $scope.panel.mode === 'terms only') {
......
<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>
<a data-unique="1" bs-popover="'panels/fields/micropanel.html'" data-placement="{{panel.micropanel_position}}" ng-click="toggle_micropanel(field)" ng-class="{label: _.indexOf(active,field)>-1}">{{field}}</a>
</li>
</ul>
<h4>The 'fields' panel is deprecated.</h4> The table panel now integrates a field selector.
</kibana-panel>
\ No newline at end of file
......@@ -3,7 +3,7 @@
/*
## Fields
## Fields (DEPRECATED)
### Parameters
......@@ -25,10 +25,9 @@ angular.module('kibana.fields', [])
.controller('fields', function($scope, eventBus, $timeout, dashboard, filterSrv) {
$scope.panelMeta = {
status : "Deprecating Soon",
description : "Allows for enabling and disabling of fields in the table panel as well as a "+
"micro anaylsis panel for analyzing the events in the table panel. This panel will soon be"+
"combined with the table panel"
status : "Deprecated",
description : "You should not use this table, it does not work anymore. The table panel now"+
"integrates a field selector. This module will soon be removed."
};
......
......@@ -98,7 +98,7 @@ angular.module('kibana.histogram', [])
kbn.calculate_interval(_range.from,_range.to,$scope.panel.resolution,0)/1000);
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
var _segment = _.isUndefined(segment) ? 0 : segment;
var request = $scope.ejs.Request().indices(dashboard.indices[_segment]);
......@@ -133,7 +133,7 @@ angular.module('kibana.histogram', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = 0;
$scope.data = [];
......
......@@ -54,7 +54,7 @@ angular.module('kibana.hits', [])
$scope.get_data = function(segment,query_id) {
delete $scope.panel.error;
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
// Make sure we have everything for the request to complete
if(dashboard.indices.length === 0) {
......@@ -85,7 +85,7 @@ angular.module('kibana.hits', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = 0;
$scope.data = [];
......
......@@ -55,7 +55,7 @@ angular.module('kibana.map', [])
if(dashboard.indices.length === 0) {
return;
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
var request;
......@@ -86,7 +86,7 @@ angular.module('kibana.map', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
$scope.hits = results.hits.total;
$scope.data = {};
_.each(results.facets.map.terms, function(v) {
......
......@@ -87,7 +87,7 @@ angular.module('kibana.pie', [])
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
var request = $scope.ejs.Request().indices(dashboard.indices);
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
......@@ -119,7 +119,7 @@ angular.module('kibana.pie', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
$scope.hits = results.hits.total;
$scope.data = [];
var k = 0;
......@@ -143,7 +143,7 @@ angular.module('kibana.pie', [])
results = request.doSearch();
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
var complete = results.hits.total;
var remaining = $scope.panel.query.goal - complete;
$scope.data = [
......
<a class="close" ng-click="dismiss()" href="">×</a>
<h4>
Micro Analysis of {{micropanel.field}}
<i class="pointer icon-search" ng-click="fieldExists(micropanel.field,'must');dismiss();"></i>
<i class="pointer icon-ban-circle" ng-click="fieldExists(micropanel.field,'mustNot');dismiss();"></i>
<br><small>{{micropanel.count}} events in the table set</small>
</h4>
<table style="width:480px" class='table table-bordered table-striped table-condensed'>
<thead>
<th>{{micropanel.field}}</th>
<th>Action</th>
<th>Count</th>
</thead>
<tbody>
<tr ng-repeat='field in micropanel.values'>
<td>{{{true: "__blank__",false:field[0]}[field[0] == ""]}}</td>
<td>
<i class="pointer icon-search" ng-click="build_search(micropanel.field,field[0]);dismiss();"></i>
<i class="pointer icon-ban-circle" ng-click="build_search(micropanel.field,field[0],true);dismiss();"></i>
</td>
<td>{{field[1]}}</td>
</tr>
</tbody>
</table>
<span ng-repeat='(field,count) in micropanel.related'><a ng-click="toggle_field(field)">{{field}}</a> ({{Math.round((count / micropanel.count) * 100)}}%), </span>
\ No newline at end of file
<kibana-panel ng-controller='table' ng-init='init()'>
<style>
.table-doc-table {
margin-left: 0px !important;
overflow-y: auto;
overflow-x: auto;
}
</style>
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
</span>
<div style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:auto">
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset1" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span8" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
</div>
</div>
<div class="small" ng-show="panel.fields.length == 0">No columns configured. You may want to add a <strong>fields panel</strong>, or click the edit button in the top right of this panel to add some columns</div>
<table class="table-hover table table-condensed" ng-style="panel.style">
<thead ng-show="panel.header">
<th style="white-space:nowrap" ng-repeat="field in panel.fields">
<i ng-show="!$first" class="pointer link icon-caret-left" ng-click="_.move(panel.fields,$index,$index-1)"></i>
<div class="row-fluid">
<div ng-class="{'span3':panel.field_list}" ng-show="panel.field_list">
<div class="sidebar-nav">
<h5>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'" ng-show="panel.field_list"></i></h5>
<ul class="unstyled" style="height:{{row.height}};overflow-y:auto;overflow-x:hidden;">
<li ng-style="panel.style" ng-repeat="field in all_fields" >
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
<a data-unique="1" bs-popover="'panels/table/micropanel.html'" data-placement="right" ng-click="toggle_micropanel(field)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
</li>
</ul>
<span class="pointer" ng-click="set_sort(field)" ng-show='panel.sortable'>
{{field}}
<i ng-show='field == panel.sort[0]' class="pointer link" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
</span>
<span ng-show='!panel.sortable'>{{field}}</span>
<i ng-show="!$last" class="pointer link icon-caret-right" ng-click="_.move(panel.fields,$index,$index+1)"></i>
</th>
</thead>
<tbody ng-repeat="row in data | slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
<tr ng-click="toggle_details(row)" class="pointer">
<td ng-repeat="field in panel.fields" ng-bind-html-unsafe="(row.highlight[field]||row._source[field]) | highlight"></td>
</tr>
<tr ng-show="row.kibana.details">
<td colspan=1000>
<table class='table table-bordered table-condensed'>
<thead>
<th>Field</th>
<th>Action</th>
<th>Value</th>
</thead>
<tr ng-repeat="(key,value) in row.kibana.details._source" ng-class-odd="'odd'">
<td>{{key}}</td>
<td>
<i class='icon-search pointer' ng-click="build_search(key,value)"></i>
<i class='icon-ban-circle pointer' ng-click="build_search(key,value,true)"></i>
</td>
<td>{{value}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset3" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span4" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div style="{{panel.overflow}}:{{panel.height || row.height}};" ng-class="{'span9':panel.field_list,'span12':!panel.field_list}" class="table-doc-table">
<i class="pull-left icon-chevron-sign-right pointer" ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Show field list'" ng-show="!panel.field_list"></i>
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset1" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span8" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
</div>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
<div class="small" ng-show="panel.fields.length == 0">No columns configured. You may want to add a <strong>fields panel</strong>, or click the edit button in the top right of this panel to add some columns</div>
<table class="table-hover table table-condensed" ng-style="panel.style">
<thead ng-show="panel.header">
<th style="white-space:nowrap" ng-repeat="field in panel.fields">
<i ng-show="!$first" class="pointer link icon-caret-left" ng-click="_.move(panel.fields,$index,$index-1)"></i>
<span class="pointer" ng-click="set_sort(field)" ng-show='panel.sortable'>
{{field}}
<i ng-show='field == panel.sort[0]' class="pointer link" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
</span>
<span ng-show='!panel.sortable'>{{field}}</span>
<i ng-show="!$last" class="pointer link icon-caret-right" ng-click="_.move(panel.fields,$index,$index+1)"></i>
</th>
</thead>
<tbody ng-repeat="row in data | slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
<tr ng-click="toggle_details(row)" class="pointer">
<td ng-repeat="field in panel.fields" ng-bind-html-unsafe="(row.highlight[field]||row._source[field]) | highlight"></td>
</tr>
<tr ng-show="row.kibana.details">
<td colspan=1000>
<table class='table table-bordered table-condensed'>
<thead>
<th>Field</th>
<th>Action</th>
<th>Value</th>
</thead>
<tr ng-repeat="(key,value) in row.kibana.details._source" ng-class-odd="'odd'">
<td>{{key}}</td>
<td>
<i class='icon-search pointer' ng-click="build_search(key,value)"></i>
<i class='icon-ban-circle pointer' ng-click="build_search(key,value,true)"></i>
</td>
<td>{{value}}</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset3" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span4" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
</div>
</div>
</div>
</div>
......
......@@ -53,26 +53,28 @@ angular.module('kibana.table', [])
highlight : [],
sortable: true,
header : true,
paging : true,
spyable: true
paging : true,
field_list: true,
spyable : true
};
_.defaults($scope.panel,_d);
$scope.init = function () {
$scope.set_listeners($scope.panel.group);
$scope.Math = Math;
$scope.$on('refresh',function(){$scope.get_data();});
$scope.get_data();
};
$scope.set_listeners = function(group) {
$scope.$on('refresh',function(){$scope.get_data();});
eventBus.register($scope,'sort', function(event,sort){
$scope.panel.sort = _.clone(sort);
$scope.get_data();
});
eventBus.register($scope,'selected_fields', function(event, fields) {
$scope.panel.fields = _.clone(fields);
});
$scope.toggle_micropanel = function(field) {
var docs = _.pluck($scope.data,'_source');
$scope.micropanel = {
field: field,
values : kbn.top_field_values(docs,field,10),
related : kbn.get_related_fields(docs,field),
count: _.countBy(docs,function(doc){return _.contains(_.keys(doc),field);})['true']
};
};
$scope.set_sort = function(field) {
......@@ -90,7 +92,6 @@ angular.module('kibana.table', [])
} else {
$scope.panel.fields.push(field);
}
broadcast_results();
};
$scope.toggle_highlight = function(field) {
......@@ -124,6 +125,11 @@ angular.module('kibana.table', [])
dashboard.refresh();
};
$scope.fieldExists = function(field,mandate) {
filterSrv.set({type:'exists',field:field,mandate:mandate});
dashboard.refresh();
};
$scope.get_data = function(segment,query_id) {
$scope.panel.error = false;
......@@ -132,7 +138,7 @@ angular.module('kibana.table', [])
return;
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
$scope.panel.queries.ids = querySrv.idsByMode($scope.panel.queries);
......@@ -166,7 +172,7 @@ angular.module('kibana.table', [])
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = 0;
......@@ -210,7 +216,6 @@ angular.module('kibana.table', [])
// This breaks, use $scope.data for this
$scope.all_fields = kbn.get_all_fields(_.pluck($scope.data,'_source'));
broadcast_results();
// If we're not sorting in reverse chrono order, query every index for
// size*pages results
......@@ -242,23 +247,6 @@ angular.module('kibana.table', [])
};
};
// Broadcast a list of all fields. Note that receivers of field array
// events should be able to receive from multiple sources, merge, dedupe
// and sort on the fly if needed.
function broadcast_results() {
eventBus.broadcast($scope.$id,$scope.panel.group,"fields", {
all : $scope.all_fields,
sort : $scope.panel.sort,
active: $scope.panel.fields
});
eventBus.broadcast($scope.$id,$scope.panel.group,"table_documents",
{
query: querySrv.list[querySrv.ids[0]].query,
docs : _.pluck($scope.data,'_source'),
index: $scope.index
});
}
$scope.set_refresh = function (state) {
$scope.refresh = state;
};
......
......@@ -64,7 +64,7 @@ angular.module('kibana.terms', [])
return;
}
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
var request,
results,
boolQuery;
......@@ -97,7 +97,7 @@ angular.module('kibana.terms', [])
// Populate scope when we have results
results.then(function(results) {
var k = 0;
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
$scope.hits = results.hits.total;
$scope.data = [];
_.each(results.facets.terms.terms, function(v) {
......
......@@ -47,7 +47,7 @@ angular.module('kibana.trends', [])
$scope.get_data = function(segment,query_id) {
delete $scope.panel.error;
$scope.panel.loading = true;
$scope.panelMeta.loading = true;
// Make sure we have everything for the request to complete
if(dashboard.indices.length === 0) {
......@@ -138,7 +138,7 @@ angular.module('kibana.trends', [])
// Populate scope when we have results
var process_results = function(results,_segment,query_id) {
results.then(function(results) {
$scope.panel.loading = false;
$scope.panelMeta.loading = false;
if(_segment === 0) {
$scope.hits = {};
$scope.data = [];
......
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