Merge pull request #2039 from w33ble/paginated-fields

Paginated indexed fields list
This commit is contained in:
Rashid Khan 2014-12-01 10:07:51 -07:00
commit d5d1d5c804
8 changed files with 132 additions and 82 deletions

View file

@ -12,6 +12,7 @@
ng-click="paginatedTable.sortColumn(col)"
class="{{ col.class }}">
<span bo-text="col.title"></span>
<kbn-info ng-if="col.info" info="{{ col.info }}" placement="top"></kbn-info>
<i
class="fa"
ng-class="{

View file

@ -54,7 +54,9 @@ define(function (require) {
} else {
// use generic sort handler
self.sort.getter = function (row) {
return row[index];
var value = row[index];
if (value.value) return value.value;
return value;
};
}
};

View file

@ -3,7 +3,7 @@ define(function (require) {
var _ = require('lodash');
var module = require('modules').get('kibana');
module.directive('kbnRows', function ($parse) {
module.directive('kbnRows', function () {
return {
restrict: 'A',
link: function ($scope, $el, attr) {
@ -14,11 +14,16 @@ define(function (require) {
// access to it here. This may become a problem with the switch to BigNumber
if (_.isNumeric(contents)) $cell.addClass('numeric-value');
if (contents === '') {
$cell.html('&nbsp;');
if (_.isObject(contents)) {
$cell.html($(contents.markup));
} else {
$cell.text(contents);
if (contents === '') {
$cell.html('&nbsp;');
} else {
$cell.text(contents);
}
}
$tr.append($cell);
}

View file

@ -53,60 +53,15 @@
</li>
</ul>
<div ng-show="state.tab == 'fields'">
<paginate list="indexPattern.fields|orderBy:table.by:table.reverse" per-page="20">
<table class="table">
<thead>
<th ng-click="setFieldSort('name')">name <i ng-class="sortClass('name')"></i></th>
<th ng-click="setFieldSort('type')">type <i ng-class="sortClass('type')"></i></th>
<th ng-click="setFieldSort('analyzed')">
analyzed <kbn-info info="Analyzed fields may require extra memory to visualize" placement="top"></kbn-info>
<i ng-class="sortClass('analyzed')"></i>
</th>
<th ng-click="setFieldSort('indexed')">
indexed <kbn-info info="Fields that are not indexed are unavailable for search" placement="top"></kbn-info>
<i ng-class="sortClass('indexed')"></i>
</th>
<th ng-click="setFieldSort('count')">
popularity <kbn-info info="A gauge of how often this field is used" placement="top"></kbn-info>
<i ng-class="sortClass('count')"></i>
</th>
</thead>
<tr class="field-settings"
ng-repeat="field in page">
<td>
<span bo-text="field.displayName"></span>
&nbsp;
<span
bo-if="indexPattern.timeFieldName === field.name"
tooltip="This field represents the time that events occured"
class="label label-default">
<i class="fa fa-clock-o"></i>
</span>
</td>
<td>
<span bo-text="field.type"></span>
<i
bo-if="field.type == 'conflict'"
tooltip="The type of this field changes across indices. It is unavailable for many analysis functions"
class="fa fa-warning text-color-warning"></i>
</td>
<td><span bo-text="field.analyzed ? 'yes' : 'no'"></span></td>
<td><span bo-text="field.indexed ? 'yes' : 'no'"></span></td>
<td>
<span bo-text="field.count"></span>
<span class="field-popularize">
<span ng-click="indexPattern.popularizeField(field.name, 1)" class="label label-default"><i class="fa fa-plus"></i></span>
<span ng-click="indexPattern.popularizeField(field.name, -1)" class="label label-default"><i class="fa fa-minus"></i></span>
</span>
</td>
</tr>
</table>
</paginate>
<div ng-show="state.tab == 'fields'" class="fields">
<paginated-table
columns="fieldColumns"
rows="fieldRows"
per-page="perPage">
</paginated-table>
</div>
<div ng-show="state.tab == 'scriptedFields'">
<div ng-show="state.tab == 'scriptedFields'" class="scripted-fields">
No scripted fields defined
</div>

View file

@ -1,5 +1,6 @@
define(function (require) {
var _ = require('lodash');
require('components/paginated_table/paginated_table');
require('routes')
.when('/settings/indices/:id', {
@ -13,9 +14,13 @@ define(function (require) {
});
require('modules').get('apps/settings')
.controller('settingsIndicesEdit', function ($scope, $location, $route, config, courier, Notifier, Private, AppState) {
.controller('settingsIndicesEdit', function ($scope, $location, $route, $compile,
config, courier, Notifier, Private, AppState) {
var rowScopes = []; // track row scopes, so they can be destroyed as needed
var notify = new Notifier();
var $state = $scope.state = new AppState();
var popularityHtml = require('text!plugins/settings/sections/indices/_popularity.html');
var refreshKibanaIndex = Private(require('plugins/settings/sections/indices/_refresh_kibana_index'));
$scope.indexPattern = $route.current.locals.indexPattern;
@ -23,13 +28,50 @@ define(function (require) {
$scope.fieldTypes = Private(require('plugins/settings/sections/indices/_field_types'));
$scope.table = {
by: 'name',
reverse: false,
page: 0,
max: 35
$scope.fieldColumns = [{
title: 'name'
}, {
title: 'type'
}, {
title: 'analyzed',
info: 'Analyzed fields may require extra memory to visualize'
}, {
title: 'indexed',
info: 'Fields that are not indexed are unavailable for search'
}, {
title: 'popularity',
info: 'A gauge of how often this field is used',
}];
$scope.showPopularityControls = function (field) {
$scope.popularityHoverState = (field) ? field : null;
};
$scope.$watchCollection('indexPattern.fields', function () {
_.invoke(rowScopes, '$destroy');
$scope.fieldRows = $scope.indexPattern.fields.map(function (field) {
var childScope = $scope.$new();
rowScopes.push(childScope);
childScope.field = field;
// update the active field via object comparison
if (_.isEqual(field, $scope.popularityHoverState)) {
$scope.showPopularityControls(field);
}
return [field.name, field.type, field.analyzed, field.indexed,
{
markup: $compile(popularityHtml)(childScope),
value: field.count
}
];
});
});
$scope.perPage = 25;
$scope.changeTab = function (obj) {
$state.tab = obj.index;
$state.save();
@ -65,24 +107,6 @@ define(function (require) {
config.set('defaultIndex', $scope.indexPattern.id);
};
$scope.setFieldSort = function (by) {
if ($scope.table.by === by) {
$scope.table.reverse = !$scope.table.reverse;
} else {
$scope.table.by = by;
}
};
$scope.sortClass = function (column) {
if ($scope.table.by !== column) return;
return $scope.table.reverse ? ['fa', 'fa-sort-asc'] : ['fa', 'fa-sort-desc'];
};
$scope.tablePages = function () {
if (!$scope.indexPattern.fields) return 0;
return Math.ceil($scope.indexPattern.fields.length / $scope.table.max);
};
$scope.setIndexPatternsTimeField = function (field) {
if (field.type !== 'date') {
notify.error('That field is a ' + field.type + ' not a date.');

View file

@ -0,0 +1,9 @@
<div ng-mouseover="showPopularityControls(field)" ng-mouseout="showPopularityControls(false)">
<span>{{ field.count }}</span>
<span class="field-popularize" ng-show="popularityHoverState == field">
<span ng-click="indexPattern.popularizeField(field.name, 1)"
class="label label-default"><i class="fa fa-plus"></i></span>
<span ng-click="indexPattern.popularizeField(field.name, -1)"
class="label label-default"><i class="fa fa-minus"></i></span>
</span>
</div>'

View file

@ -129,6 +129,13 @@ kbn-settings-objects-view {
}
}
kbn-settings-indices .fields {
& th:first-child,
& td:first-child {
width: 35%;
}
}
.kbn-settings-indices-create {
.time-and-pattern > div {}
}

View file

@ -181,5 +181,52 @@ define(function (require) {
expect(sortHandler.getCall(0).args[0]).to.be(columnIndex);
});
});
describe('object rows', function () {
var cols;
var rows;
var paginatedTable;
beforeEach(function () {
cols = [{
title: 'object test'
}];
rows = [
['aaaa'],
[{
markup: '<h1>I am HTML in a row</h1>',
value: 'zzzz'
}],
['bbbb']
];
renderTable(cols, rows);
paginatedTable = $el.isolateScope().paginatedTable;
});
it('should append object markup', function () {
var tableRows = $el.find('tbody tr');
expect(tableRows.eq(0).find('h1').size()).to.be(0);
expect(tableRows.eq(1).find('h1').size()).to.be(1);
expect(tableRows.eq(2).find('h1').size()).to.be(0);
});
it('should sort using object value', function () {
paginatedTable.sortColumn(cols[0]);
$scope.$digest();
var tableRows = $el.find('tbody tr');
expect(tableRows.eq(0).find('h1').size()).to.be(0);
expect(tableRows.eq(1).find('h1').size()).to.be(0);
// html row should be the last row
expect(tableRows.eq(2).find('h1').size()).to.be(1);
paginatedTable.sortColumn(cols[0]);
$scope.$digest();
tableRows = $el.find('tbody tr');
// html row should be the first row
expect(tableRows.eq(0).find('h1').size()).to.be(1);
expect(tableRows.eq(1).find('h1').size()).to.be(0);
expect(tableRows.eq(2).find('h1').size()).to.be(0);
});
});
});
});
});