Commit 56e82c0c by Rashid Khan

More small table performance improvements

parent a14ead5c
...@@ -8,26 +8,29 @@ ...@@ -8,26 +8,29 @@
</style> </style>
<div class="row-fluid"> <div class="row-fluid">
<div ng-class="{'span3':panel.field_list}" ng-if="panel.field_list"> <div bindonce ng-class="{'span3':panel.field_list}" ng-if="panel.field_list">
<div class="sidebar-nav"> <div class="sidebar-nav">
<strong>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></strong><p> <strong>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></strong><p>
<div class="small"> <div class="small">
<span class="link" ng-click="panel.all_fields = true;" ng-class="{strong:panel.all_fields}">All</span> / <span class="link" ng-click="panel.all_fields = true;" ng-class="{strong:panel.all_fields}">
<span class="link" ng-click="panel.all_fields = false;" ng-class="{strong:!panel.all_fields}">Current</span> All ({{fields.list.length}})</span><br>
<span class="link" ng-click="panel.all_fields = false;" ng-class="{strong:!panel.all_fields}">
Current ({{current_fields.length || 0}})</span>
</div> </div>
<div><input type="text" class="input-medium" placeholder="Type to filter..." ng-model="fieldFilter"></div> <div><input type="text" class="input-medium" placeholder="Type to filter..." ng-model="fieldFilter"></div>
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="panel.all_fields"> <ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="panel.all_fields">
<li ng-style="panel.style" ng-repeat="field in fields.list|filter:fieldFilter|orderBy:identity"> <li ng-style="panel.style" ng-repeat="field in fields.list|filter:fieldFilter|orderBy:identity">
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i> <i class="pointer" ng-class="{'icon-check': columns[field],'icon-check-empty': _.isUndefined(columns[field])}" ng-click="toggle_field(field)"></i>
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a> <a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: columns[field]}" bo-text="field"></a>
</li> </li>
</ul> </ul>
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="!panel.all_fields"> <ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="!panel.all_fields">
<li ng-style="panel.style" ng-repeat="field in current_fields|filter:fieldFilter|orderBy:identity"> <li ng-style="panel.style" ng-repeat="field in current_fields|filter:fieldFilter|orderBy:identity">
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i> <i class="pointer" ng-class="{'icon-check': columns[field],'icon-check-empty': _.isUndefined(columns[field])}" ng-click="toggle_field(field)"></i>
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a> <a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: columns[field]}" bo-text="field"></a>
</li> </li>
</ul> </ul>
...@@ -84,18 +87,18 @@ ...@@ -84,18 +87,18 @@
<th>Value</th> <th>Value</th>
</thead> </thead>
<tr ng-repeat="(key,value) in event.kibana._source track by $index" ng-class-odd="'odd'"> <tr ng-repeat="(key,value) in event.kibana._source track by $index" ng-class-odd="'odd'">
<td>{{key}}</td> <td bo-text="key"></td>
<td style="white-space:nowrap"> <td style="white-space:nowrap">
<i class='icon-search pointer' ng-click="build_search(key,value)" bs-tooltip="'Add filter to match this value'"></i> <i class='icon-search pointer' ng-click="build_search(key,value)" bs-tooltip="'Add filter to match this value'"></i>
<i class='icon-ban-circle pointer' ng-click="build_search(key,value,true)" bs-tooltip="'Add filter to NOT match this value'"></i> <i class='icon-ban-circle pointer' ng-click="build_search(key,value,true)" bs-tooltip="'Add filter to NOT match this value'"></i>
<i class="pointer icon-th" ng-click="toggle_field(key)" bs-tooltip="'Toggle table column'"></i> <i class="pointer icon-th" ng-click="toggle_field(key)" bs-tooltip="'Toggle table column'"></i>
</td> </td>
<!-- At some point we need to create a more efficient way of applying the filter pipeline --> <!-- At some point we need to create a more efficient way of applying the filter pipeline -->
<td style="white-space:pre-wrap" ng-bind-html-unsafe="value|noXml|urlLink|stringify"></td> <td style="white-space:pre-wrap" bo-html="value|noXml|urlLink|stringify"></td>
</tr> </tr>
</table> </table>
<pre style="white-space:pre-wrap" ng-bind-html="without_kibana(event)|tableJson:2" ng-switch-when="json"></pre> <pre style="white-space:pre-wrap" bo-html="without_kibana(event)|tableJson:2" ng-switch-when="json"></pre>
<pre ng-bind-html="without_kibana(event)|tableJson:1" ng-switch-when="raw"></pre> <pre bo-html="without_kibana(event)|tableJson:1" ng-switch-when="raw"></pre>
</td> </td>
</tr> </tr>
</tbody> </tbody>
......
...@@ -85,6 +85,11 @@ function (angular, app, _, kbn, moment) { ...@@ -85,6 +85,11 @@ function (angular, app, _, kbn, moment) {
_.defaults($scope.panel,_d); _.defaults($scope.panel,_d);
$scope.init = function () { $scope.init = function () {
$scope.columns = {};
_.each($scope.panel.fields,function(field) {
$scope.columns[field] = true;
});
$scope.Math = Math; $scope.Math = Math;
$scope.identity = angular.identity; $scope.identity = angular.identity;
$scope.$on('refresh',function(){$scope.get_data();}); $scope.$on('refresh',function(){$scope.get_data();});
...@@ -159,8 +164,10 @@ function (angular, app, _, kbn, moment) { ...@@ -159,8 +164,10 @@ function (angular, app, _, kbn, moment) {
$scope.toggle_field = function(field) { $scope.toggle_field = function(field) {
if (_.indexOf($scope.panel.fields,field) > -1) { if (_.indexOf($scope.panel.fields,field) > -1) {
$scope.panel.fields = _.without($scope.panel.fields,field); $scope.panel.fields = _.without($scope.panel.fields,field);
delete $scope.columns[field];
} else { } else {
$scope.panel.fields.push(field); $scope.panel.fields.push(field);
$scope.columns[field] = true;
} }
}; };
......
...@@ -14,20 +14,22 @@ function (angular, _, config) { ...@@ -14,20 +14,22 @@ function (angular, _, config) {
this.list = ['_type']; this.list = ['_type'];
this.mapping = {}; this.mapping = {};
this.fullMapping = {};
$rootScope.$watch(function(){return dashboard.indices;},function(n) { $rootScope.$watch(function(){return dashboard.indices;},function(n) {
if(!_.isUndefined(n) && n.length) { if(!_.isUndefined(n) && n.length) {
// Only get the mapping for indices we don't know it for // Only get the mapping for indices we don't know it for
var indices = _.difference(n,_.keys(self.mapping)); var indices = _.difference(n,_.keys(self.fullMapping));
// Only get the mapping if there are new indices // Only get the mapping if there are new indices
if(indices.length > 0) { if(indices.length > 0) {
self.map(indices).then(function(result) { self.map(indices).then(function(result) {
self.mapping = _.extend(self.mapping,result); self.fullMapping = _.extend(self.fullMapping,result);
self.list = mapFields(self.mapping); self.list = mapFields(self.fullMapping);
}); });
// Otherwise just use the cached mapping // Otherwise just use the cached mapping
} else { } else {
self.list = mapFields(_.pick(self.mapping,n)); // This is inefficient, should not need to reprocess?
self.list = mapFields(_.pick(self.fullMapping,n));
} }
} }
}); });
...@@ -57,12 +59,13 @@ function (angular, _, config) { ...@@ -57,12 +59,13 @@ function (angular, _, config) {
} }
}); });
// Flatten the mapping of each index into dot notated keys.
return request.then(function(p) { return request.then(function(p) {
var mapping = {}; var mapping = {};
_.each(p.data, function(v,k) { _.each(p.data, function(type,index) {
mapping[k] = {}; mapping[index] = {};
_.each(v, function (v,f) { _.each(type, function (fields,typename) {
mapping[k][f] = flatten(v); mapping[index][typename] = flatten(fields);
}); });
}); });
return mapping; return mapping;
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
.directive('bindonce', function() .directive('bindonce', function()
{ {
console.log('called');
var toBoolean = function(value) var toBoolean = function(value)
{ {
if (value && value.length !== 0) if (value && value.length !== 0)
......
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