diff --git a/src/ui/public/agg_table/agg_table.less b/src/ui/public/agg_table/agg_table.less index 382460e4cad3e..38c665ab00875 100644 --- a/src/ui/public/agg_table/agg_table.less +++ b/src/ui/public/agg_table/agg_table.less @@ -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; + } } } diff --git a/src/ui/public/directives/partials/table_cell_filter.html b/src/ui/public/directives/partials/table_cell_filter.html new file mode 100644 index 0000000000000..fbb30964c7367 --- /dev/null +++ b/src/ui/public/directives/partials/table_cell_filter.html @@ -0,0 +1,17 @@ + + + + + + + diff --git a/src/ui/public/directives/rows.js b/src/ui/public/directives/rows.js index 7909bf102e71f..83ecdf42d3fab 100644 --- a/src/ui/public/directives/rows.js +++ b/src/ui/public/directives/rows.js @@ -3,6 +3,7 @@ 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'; +import tableCellFilterHtml from './partials/table_cell_filter.html'; const module = uiModules.get('kibana'); module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private) { @@ -18,15 +19,15 @@ module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private if (_.isNumeric(contents)) $cell.addClass('numeric-value'); const createAggConfigResultCell = function (aggConfigResult) { - const $cell = $(document.createElement('td')); + 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); }; @@ -48,9 +49,9 @@ 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); } if (contents.attr) { @@ -58,9 +59,9 @@ module.directive('kbnRows', function ($compile, $rootScope, getAppState, Private } } else { if (contents === '') { - $cell.html(' '); + $cell.prepend(' '); } else { - $cell.html(contents); + $cell.prepend(contents); } } diff --git a/src/ui/public/doc_table/components/table_row.js b/src/ui/public/doc_table/components/table_row.js index 24dc6d0120fa0..283e1660a1019 100644 --- a/src/ui/public/doc_table/components/table_row.js +++ b/src/ui/public/doc_table/components/table_row.js @@ -9,6 +9,7 @@ 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'; +import FilterManagerProvider from 'ui/filter_manager'; const module = uiModules.get('app/discover'); @@ -24,9 +25,10 @@ const MIN_LINE_LENGTH = 20; * * ``` */ -module.directive('kbnTableRow', function ($compile) { +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', @@ -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) { const indexPattern = $scope.indexPattern; + $scope.flattenedRow = indexPattern.flattenHit(row); // We just create a string here because its faster. const 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 })); }); @@ -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); } @@ -160,4 +179,4 @@ module.directive('kbnTableRow', function ($compile) { } } }; -}); +}]); diff --git a/src/ui/public/doc_table/components/table_row/cell.html b/src/ui/public/doc_table/components/table_row/cell.html index 55f1e17f0cde5..ce8be42f6e3cf 100644 --- a/src/ui/public/doc_table/components/table_row/cell.html +++ b/src/ui/public/doc_table/components/table_row/cell.html @@ -10,4 +10,23 @@ %> > <%= formatted %> + + <% if (filterable) { %> + + + + <% } %> + diff --git a/src/ui/public/doc_table/doc_table.less b/src/ui/public/doc_table/doc_table.less index 4f7b42eb4ff7d..1bdaa5c171277 100644 --- a/src/ui/public/doc_table/doc_table.less +++ b/src/ui/public/doc_table/doc_table.less @@ -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; } @@ -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; + } +} diff --git a/src/ui/public/paginated_table/paginated_table.html b/src/ui/public/paginated_table/paginated_table.html index 0c2808a553132..a74a366b78592 100644 --- a/src/ui/public/paginated_table/paginated_table.html +++ b/src/ui/public/paginated_table/paginated_table.html @@ -22,7 +22,6 @@ 'fa-sort': paginatedTable.sort.columnIndex !== $index || paginatedTable.sort.direction === null }"> - diff --git a/src/ui/public/styles/base.less b/src/ui/public/styles/base.less index b8d520ba46d5a..1c28e5bd95f32 100644 --- a/src/ui/public/styles/base.less +++ b/src/ui/public/styles/base.less @@ -253,7 +253,6 @@ kbn-table, .kbn-table { visibility: visible; } } - } //== Generic Table @@ -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 { @@ -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; diff --git a/src/ui/public/styles/dark-theme.less b/src/ui/public/styles/dark-theme.less index 6800ec0a4a2cf..28139702163d0 100644 --- a/src/ui/public/styles/dark-theme.less +++ b/src/ui/public/styles/dark-theme.less @@ -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; + } } @@ -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; + } } } @@ -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; + } + } + } } +