Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add columns from doc table #3526

Merged
merged 11 commits into from
Apr 9, 2015
9 changes: 5 additions & 4 deletions src/kibana/components/doc_table/components/table_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
<span ng-click="sort(indexPattern.timeFieldName)" tooltip="Sort by time">Time <i ng-class="headerClass(indexPattern.timeFieldName)"></i></span>
</th>
<th ng-repeat="name in columns">
<span ng-click="sort(name)" class="table-header-name" tooltip="{{tooltip(name)}}">
{{name | shortDots}} <i ng-class="headerClass(name)"></i>
<span class="table-header-name">
{{name | shortDots}} <i ng-class="headerClass(name)" ng-click="sort(name)" tooltip="{{tooltip(name)}}" tooltip-append-to-body="1"></i>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the click out to the sort icon and away from the entire header. There were enough icons up there that it was getting confusing.

</span>
<span class="table-header-move">
<i ng-click="moveLeft(name)" class="fa fa-angle-double-left" ng-show="!$first" tooltip="Move column to the left"></i>
<i ng-click="moveRight(name)" class="fa fa-angle-double-right" ng-show="!$last" tooltip="Move column to the right"></i>
<i ng-click="toggleColumn(name)" ng-show="canRemove(name)" class="fa fa-remove" tooltip="Remove column" tooltip-append-to-body="1"></i>
<i ng-click="moveLeft(name)" class="fa fa-angle-double-left" ng-show="!$first" tooltip="Move column to the left" tooltip-append-to-body="1"></i>
<i ng-click="moveRight(name)" class="fa fa-angle-double-right" ng-show="!$last" tooltip="Move column to the right" tooltip-append-to-body="1"></i>
</span>
</th>
11 changes: 10 additions & 1 deletion src/kibana/components/doc_table/components/table_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ define(function (require) {

var sortableField = function (field) {
if (!$scope.indexPattern) return;
return $scope.indexPattern.fields.byName[field].sortable;
var sortable = _.deepGet($scope.indexPattern.fields.byName[field], 'sortable');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was spazzing out when adding fields without a mapping.

return sortable;
};

$scope.tooltip = function (column) {
if (!sortableField(column)) return ''; else return 'Sort by ' + shortDotsFilter(column);
};

$scope.canRemove = function (name) {
return (name !== '_source' || $scope.columns.length !== 1);
};

$scope.headerClass = function (column) {
if (!sortableField(column)) return;

Expand All @@ -49,6 +54,10 @@ define(function (require) {
_.move($scope.columns, index, ++index);
};

$scope.toggleColumn = function (fieldName) {
_.toggleInOut($scope.columns, fieldName);
};

$scope.sort = function (column) {
if (!column || !sortableField(column)) return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
<a class="pull-right" ng-href="#/doc/{{indexPattern.id}}/{{row._index}}/{{row._type}}/?id={{row._id | uriescape}}">
<small>Link to /{{row._index}}/{{row._type}}/{{row._id | uriescape}}</small></i>
</a>
<doc-viewer hit="row" filter="filter" index-pattern="indexPattern"></doc-viewer>
<doc-viewer hit="row" filter="filter" columns="columns" index-pattern="indexPattern"></doc-viewer>
</td>
20 changes: 19 additions & 1 deletion src/kibana/components/doc_table/doc_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ define(function (require) {
require('components/doc_table/components/table_row');

require('modules').get('kibana')
.directive('docTable', function (config, Notifier) {
.directive('docTable', function (config, Notifier, getAppState) {
return {
restrict: 'E',
template: html,
Expand Down Expand Up @@ -55,6 +55,24 @@ define(function (require) {
$scope.limit += 50;
};

// This exists to fix the problem of an empty initial column list not playing nice with watchCollection.
$scope.$watch('columns', function (columns) {
if (columns.length !== 0) return;

var $state = getAppState();
$scope.columns.push('_source');
if ($state) $state.replace();
});

$scope.$watchCollection('columns', function (columns, oldColumns) {
if (oldColumns.length === 1 && oldColumns[0] === '_source' && $scope.columns.length > 1) {
_.pull($scope.columns, '_source');
}

if ($scope.columns.length === 0) $scope.columns.push('_source');
});


$scope.$watch('searchSource', prereq(function (searchSource) {
if (!$scope.searchSource) return;

Expand Down
16 changes: 14 additions & 2 deletions src/kibana/components/doc_viewer/doc_viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,25 @@
</td>
<td width="1%" class="doc-viewer-buttons" ng-if="filter">
<span bo-if="mapping[field].filterable">
<i ng-click="filter(mapping[field], flattened[field], '+')" class="fa fa-search-plus"></i>
<i ng-click="filter(mapping[field], flattened[field],'-')" class="fa fa-search-minus"></i>
<i ng-click="filter(mapping[field], flattened[field], '+')"
tooltip="Filter for value"
tooltip-append-to-body="1"
class="fa fa-search-plus"></i>
<i ng-click="filter(mapping[field], flattened[field],'-')"
tooltip="Filter out value"
tooltip-append-to-body="1"
class="fa fa-search-minus"></i>
</span>
<span bo-if="!mapping[field].filterable" tooltip="Unindexed fields can not be searched">
<i class="fa fa-search-plus text-muted"></i>
<i class="fa fa-search-minus text-muted"></i>
</span>
<span bo-if="columns">
<i ng-click="toggleColumn(field)"
tooltip="Toggle column in table"
tooltip-append-to-body="1"
class="fa fa-columns"></i>
</span>
</td>

<td>
Expand Down
5 changes: 5 additions & 0 deletions src/kibana/components/doc_viewer/doc_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ define(function (require) {
hit: '=',
indexPattern: '=',
filter: '=?',
columns: '=?'
},
link: function ($scope, $el, attr) {
// If a field isn't in the mapping, use this
Expand All @@ -37,6 +38,10 @@ define(function (require) {
});
$scope.fields = _.keys($scope.flattened).sort();

$scope.toggleColumn = function (fieldName) {
_.toggleInOut($scope.columns, fieldName);
};

$scope.showArrayInObjectsWarning = function (row, field) {
var value = $scope.flattened[field];
return _.isArray(value) && typeof value[0] === 'object';
Expand Down
4 changes: 2 additions & 2 deletions src/kibana/components/index_patterns/_index_pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ define(function (require) {
}
},
filterable: {
value: field.name === '_id' || ((field.indexed && type.filterable) || field.scripted)
value: field.name === '_id' || ((field.indexed && type && type.filterable) || field.scripted)
},
format: {
get: function () {
Expand All @@ -112,7 +112,7 @@ define(function (require) {
}
},
sortable: {
value: field.indexed && type.sortable
value: field.indexed && type && type.sortable
},
scripted: {
// enumerable properties end up in the JSON
Expand Down
4 changes: 2 additions & 2 deletions src/kibana/directives/field_name.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ define(function (require) {
'field',
'fieldName',
'fieldType',
'field.rowCount'
'field.inData'
], function () {

var type = $scope.field ? $scope.field.type : $scope.fieldType;
var name = $scope.field ? $scope.field.name : $scope.fieldName;
var results = $scope.field ? !$scope.field.rowCount && !$scope.field.scripted : false;
var results = $scope.field ? !$scope.field.inData && !$scope.field.scripted : false;
var scripted = $scope.field ? $scope.field.scripted : false;

var displayName = $filter('shortDots')(name);
Expand Down
11 changes: 11 additions & 0 deletions src/kibana/plugins/dashboard/components/panel/lib/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ define(function (require) {
return function (panel, $scope) { // Function parameters here
return savedSearches.get(panel.id)
.then(function (savedSearch) {
panel.columns = panel.columns || savedSearch.columns;
panel.sort = panel.sort || savedSearch.sort;

$scope.$watchCollection('panel.columns', function () {
$scope.state.save();
});

$scope.$watchCollection('panel.sort', function () {
$scope.state.save();
});

return {
savedObj: savedSearch,
panel: panel,
Expand Down
4 changes: 2 additions & 2 deletions src/kibana/plugins/dashboard/components/panel/panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

<doc-table ng-switch-when="search"
search-source="savedObj.searchSource"
sorting="savedObj.sort"
columns="savedObj.columns"
sorting="panel.sort"
columns="panel.columns"
class="panel-content"
filter="filter">
</doc-table>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ <h5>Selected Fields</h5>
</div>
<ul
bindonce class="list-unstyled discover-selected-fields" >
<discover-field ng-repeat="field in fields|filter:{display:true}">
<discover-field ng-repeat="field in fields.raw|filter:{display:true}">
</discover-field>
</ul>

<div class="sidebar-list-header sidebar-item">
<h5>Fields
<h5>Available Fields
<i
ng-class="{ 'fa-chevron-right': !showFields, 'fa-chevron-down': showFields }"
ng-click="showFields = !showFields"
Expand Down Expand Up @@ -105,9 +105,9 @@ <h5>Fields
</div>

<ul bindonce
ng-show="(fields | filter:filter.popularity).length > 0"
ng-show="(popularFields | filter:filter.isFieldFiltered).length > 0"
class="list-unstyled sidebar-well discover-popular-fields" ng-class="{ 'hidden-sm': !showFields, 'hidden-xs': !showFields }">
<li class="sidebar-item sidebar-list-header"><h6>Popular fields</h6></li>
<li class="sidebar-item sidebar-list-header"><h6>Popular</h6></li>
<discover-field ng-repeat="field in popularFields | filter:filter.isFieldFiltered">
</discover-field>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ define(function (require) {
var rison = require('utils/rison');
var qs = require('utils/query_string');
var fieldCalculator = require('plugins/discover/components/field_chooser/lib/field_calculator');
var IndexedArray = require('utils/indexed_array/index');


require('directives/css_truncate');
Expand All @@ -16,8 +17,7 @@ define(function (require) {
return {
restrict: 'E',
scope: {
fields: '=',
toggle: '=',
columns: '=',
data: '=',
state: '=',
indexPattern: '=',
Expand Down Expand Up @@ -55,11 +55,14 @@ define(function (require) {
reset: function () {
filter.vals = _.clone(filter.defaults);
},
isFieldSelected: function (field) {
return field.display;
},
isFieldFiltered: function (field) {
var matchFilter = (filter.vals.type == null || field.type === filter.vals.type);
var isAnalyzed = (filter.vals.analyzed == null || field.analyzed === filter.vals.analyzed);
var isIndexed = (filter.vals.indexed == null || field.indexed === filter.vals.indexed);
var rowsScritpedOrMissing = (!filter.vals.missing || field.scripted || field.rowCount > 0);
var rowsScritpedOrMissing = (!filter.vals.missing || field.scripted || field.inData);
var matchName = (!filter.vals.name || field.name.indexOf(filter.vals.name) !== -1);

return !field.display
Expand Down Expand Up @@ -87,6 +90,11 @@ define(function (require) {
filter.active = filter.getActive();
});

$scope.toggle = function (fieldName) {
$scope.increaseFieldCounter(fieldName);
_.toggleInOut($scope.columns, fieldName);
};

var calculateFields = function (newFields) {
// Find the top N most popular fields
$scope.popularFields = _(newFields)
Expand All @@ -110,16 +118,47 @@ define(function (require) {
};

$scope.$watch('fields', calculateFields);

$scope.$watch('indexPattern', function (indexPattern) {
$scope.fields = new IndexedArray ({
index: ['name'],
initialSet: _($scope.indexPattern.fields)
.sortBy('name')
.transform(function (fields, field) {
// clone the field with Object.create so that its getters
// and non-enumerable props are preserved
var clone = Object.create(field);
clone.display = _.contains($scope.columns, field.name);
fields.push(clone);
}, [])
.value()
});

});

$scope.$watchCollection('columns', function (columns, oldColumns) {
_.each($scope.fields, function (field) {
field.display = _.contains(columns, field.name) ? true : false;
});
});

$scope.$watch('data', function () {

// Get all fields current in data set
var currentFields = _.chain($scope.data).map(function (d) {
return _.keys($scope.indexPattern.flattenHit(d));
}).flatten().unique().sort().value();

_.each($scope.fields, function (field) {
field.inData = _.contains(currentFields, field.name) ? true : false;
if (field.details) {
$scope.details(field, true);
}
});
});

$scope.increaseFieldCounter = function (field) {
$scope.indexPattern.popularizeField(field.name, 1);
$scope.increaseFieldCounter = function (fieldName) {
$scope.indexPattern.popularizeField(fieldName, 1);
};

$scope.runAgg = function (field) {
Expand Down
Loading