Skip to content

Commit

Permalink
Click to filter values in Discover doc table and Visualize data table (
Browse files Browse the repository at this point in the history
…#9989) (#10123)

Adds + and - icons on hover in the doc table and data table, allowing users to drill down with more options and fewer clicks. Previously in the doc table a user had to expand the row in order to filter on a document value. In the data table a user could filter simply by clicking a cell, but there was no way to create a negative filter. This commit brings feature parity between the data table and doc table.
  • Loading branch information
Bargs committed Jan 31, 2017
1 parent 89d2b38 commit 0685d42
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 35 deletions.
6 changes: 3 additions & 3 deletions src/ui/public/agg_table/agg_table.less
Expand Up @@ -17,10 +17,10 @@ kbn-agg-table-group {

tr:hover td {
background-color: @table-row-hover-bg;
}

.cell-hover:hover {
background-color: @table-cell-hover-hover-bg;
.table-cell-filter {
background-color: @table-row-hover-bg;
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions src/ui/public/directives/partials/table_cell_filter.html
@@ -0,0 +1,17 @@
<td>
<span class="table-cell-filter">
<span
ng-click="clickHandler($event, false)"
class="fa fa-search-plus"
tooltip="Filter for value"
tooltip-append-to-body="1"
></span>

<span
ng-click="clickHandler($event, true)"
class="fa fa-search-minus"
tooltip="Filter out value"
tooltip-append-to-body="1"
></span>
</span>
</td>
25 changes: 13 additions & 12 deletions src/ui/public/directives/rows.js
Expand Up @@ -3,7 +3,8 @@ import _ from 'lodash';
import AggConfigResult from 'ui/vis/agg_config_result';
import FilterBarFilterBarClickHandlerProvider from 'ui/filter_bar/filter_bar_click_handler';
import uiModules from 'ui/modules';
let module = uiModules.get('kibana');
import tableCellFilterHtml from './partials/table_cell_filter.html';
const module = uiModules.get('kibana');

module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private) {
let filterBarClickHandler = Private(FilterBarFilterBarClickHandlerProvider);
Expand All @@ -17,16 +18,16 @@ module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private
// access to it here. This may become a problem with the switch to BigNumber
if (_.isNumeric(contents)) $cell.addClass('numeric-value');

let createAggConfigResultCell = function (aggConfigResult) {
let $cell = $(document.createElement('td'));
let $state = getAppState();
let clickHandler = filterBarClickHandler($state);
const createAggConfigResultCell = function (aggConfigResult) {
const $cell = $(tableCellFilterHtml);

const $state = getAppState();
const clickHandler = filterBarClickHandler($state);
$cell.scope = $scope.$new();
$cell.addClass('cell-hover');
$cell.attr('ng-click', 'clickHandler($event)');
$cell.scope.clickHandler = function (event) {
$cell.scope.clickHandler = function (event, negate) {
if ($(event.target).is('a')) return; // Don't add filter if a link was clicked
clickHandler({ point: { aggConfigResult: aggConfigResult } });
clickHandler({ point: { aggConfigResult: aggConfigResult }, negate });
};
return $compile($cell)($cell.scope);
};
Expand All @@ -48,15 +49,15 @@ module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private
}

if (contents.scope) {
$cell = $compile($cell.html(contents.markup))(contents.scope);
$cell = $compile($cell.prepend(contents.markup))(contents.scope);
} else {
$cell.html(contents.markup);
$cell.prepend(contents.markup);
}
} else {
if (contents === '') {
$cell.html('&nbsp;');
$cell.prepend('&nbsp;');
} else {
$cell.html(contents);
$cell.prepend(contents);
}
}

Expand Down
37 changes: 28 additions & 9 deletions src/ui/public/doc_table/components/table_row.js
Expand Up @@ -9,7 +9,8 @@ import noWhiteSpace from 'ui/utils/no_white_space';
import openRowHtml from 'ui/doc_table/components/table_row/open.html';
import detailsHtml from 'ui/doc_table/components/table_row/details.html';
import uiModules from 'ui/modules';
let module = uiModules.get('app/discover');
import FilterManagerProvider from 'ui/filter_manager';
const module = uiModules.get('app/discover');



Expand All @@ -24,9 +25,10 @@ let MIN_LINE_LENGTH = 20;
* <tr ng-repeat="row in rows" kbn-table-row="row"></tr>
* ```
*/
module.directive('kbnTableRow', function ($compile) {
let cellTemplate = _.template(noWhiteSpace(require('ui/doc_table/components/table_row/cell.html')));
let truncateByHeightTemplate = _.template(noWhiteSpace(require('ui/partials/truncate_by_height.html')));
module.directive('kbnTableRow', ['$compile', 'Private', function ($compile, Private) {
const cellTemplate = _.template(noWhiteSpace(require('ui/doc_table/components/table_row/cell.html')));
const truncateByHeightTemplate = _.template(noWhiteSpace(require('ui/partials/truncate_by_height.html')));
const filterManager = Private(FilterManagerProvider);

return {
restrict: 'A',
Expand Down Expand Up @@ -83,27 +85,44 @@ module.directive('kbnTableRow', function ($compile) {
createSummaryRow($scope.row, $scope.row._id);
});

$scope.inlineFilter = function inlineFilter($event, type) {
const column = $($event.target).data().column;
const field = $scope.indexPattern.fields.byName[column];
$scope.indexPattern.popularizeField(field, 1);
filterManager.add(field, $scope.flattenedRow[column], type, $scope.indexPattern.id);
};

// create a tr element that lists the value for each *column*
function createSummaryRow(row) {
let indexPattern = $scope.indexPattern;
const indexPattern = $scope.indexPattern;
$scope.flattenedRow = indexPattern.flattenHit(row);

// We just create a string here because its faster.
let newHtmls = [
openRowHtml
];

const mapping = indexPattern.fields.byName;
if (indexPattern.timeFieldName) {
newHtmls.push(cellTemplate({
timefield: true,
formatted: _displayField(row, indexPattern.timeFieldName)
formatted: _displayField(row, indexPattern.timeFieldName),
filterable: mapping[indexPattern.timeFieldName].filterable,
column: indexPattern.timeFieldName
}));
}

$scope.columns.forEach(function (column) {
const isFilterable = $scope.flattenedRow[column] !== undefined
&& mapping[column]
&& mapping[column].filterable;

newHtmls.push(cellTemplate({
timefield: false,
sourcefield: (column === '_source'),
formatted: _displayField(row, column, true)
formatted: _displayField(row, column, true),
filterable: isFilterable,
column
}));
});

Expand All @@ -128,7 +147,7 @@ module.directive('kbnTableRow', function ($compile) {
// rebuild cells since we modified the children
$cells = $el.children();

if (i === 0 && !reuse) {
if (!reuse) {
$toggleScope = $scope.$new();
$compile($target)($toggleScope);
}
Expand Down Expand Up @@ -160,4 +179,4 @@ module.directive('kbnTableRow', function ($compile) {
}
}
};
});
}]);
19 changes: 19 additions & 0 deletions src/ui/public/doc_table/components/table_row/cell.html
Expand Up @@ -10,4 +10,23 @@
%>
<td <%= attributes %>>
<%= formatted %>
<span class="table-cell-filter">
<% if (filterable) { %>
<span
ng-click="inlineFilter($event, '+')"
class="fa fa-search-plus docTableRowFilterIcon"
data-column="<%- column %>"
tooltip="Filter for value"
tooltip-append-to-body="1"
></span>

<span
ng-click="inlineFilter($event, '-')"
class="fa fa-search-minus docTableRowFilterIcon"
data-column="<%- column %>"
tooltip="Filter out value"
tooltip-append-to-body="1"
></span>
<% } %>
</span>
</td>
33 changes: 33 additions & 0 deletions src/ui/public/doc_table/doc_table.less
Expand Up @@ -18,6 +18,26 @@ doc-table {
word-break: break-word;
}

.discover-table-row {
td {
position: relative;

.table-cell-filter {
position: absolute;
background-color: @panel-bg;
white-space: nowrap;
right: 0;
display: none;
}

&:hover {
.table-cell-filter {
display: inline;
}
}
}
}

.loading {
opacity: @loading-opacity;
}
Expand All @@ -31,3 +51,16 @@ doc-table {
opacity: @loading-opacity;
}
}

/**
* 1. Align icon with text in cell.
*/
.docTableRowFilterIcon {
font-size: 14px;
line-height: 1; /* 1 */
display: inline;

& + & {
margin-left: 5px;
}
}
1 change: 0 additions & 1 deletion src/ui/public/paginated_table/paginated_table.html
Expand Up @@ -22,7 +22,6 @@
'fa-sort': paginatedTable.sort.columnIndex !== $index || paginatedTable.sort.direction === null
}">
</i>
<i aria-label="Click on a cell to filter" ng-if="col.filterable" class="fa fa-search" ng-click="$event.stopPropagation()" tooltip="Click on a cell to filter"></i>
</th>
</tr>
</thead>
Expand Down
16 changes: 13 additions & 3 deletions src/ui/public/styles/base.less
Expand Up @@ -253,7 +253,6 @@ kbn-table, .kbn-table {
visibility: visible;
}
}

}

//== Generic Table
Expand Down Expand Up @@ -491,6 +490,16 @@ style-compile {

.cell-hover {
background-color: @table-cell-hover-bg;
position: relative;

.table-cell-filter {
position: absolute;
background-color: @table-cell-hover-bg;
white-space: nowrap;
right: 0;
top: 5px;
display: none;
}
}

.cell-hover-show {
Expand All @@ -499,8 +508,9 @@ style-compile {
}

.cell-hover:hover {
background-color: @table-cell-hover-hover-bg;
cursor: cell;
.table-cell-filter {
display: inline;
}

.cell-hover-show {
visibility: visible;
Expand Down
26 changes: 19 additions & 7 deletions src/ui/public/styles/dark-theme.less
Expand Up @@ -255,9 +255,10 @@

.cell-hover {
background-color: @table-cell-hover-bg;
}
.cell-hover:hover {
background-color: @table-cell-hover-hover-bg;

.table-cell-filter {
background-color: @table-cell-hover-bg;
}
}


Expand All @@ -271,10 +272,10 @@
.agg-table-paginated {
tr:hover td {
background-color: @table-row-hover-bg;
}

.cell-hover:hover {
background-color: @table-cell-hover-hover-bg;
.table-cell-filter {
background-color: @table-row-hover-bg;
}
}
}

Expand Down Expand Up @@ -581,4 +582,15 @@
background-color: @config-bg;
color: @dark-button-font;
}


// /src/ui/public/doc_table/doc_table.less
.discover-table-row {
td {
.table-cell-filter {
background-color: @panel-bg;
}
}
}
}

0 comments on commit 0685d42

Please sign in to comment.