From 65e59bfe9f49a300f30a6c2d0b9b875f618fc321 Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Thu, 26 Mar 2015 16:27:11 -0700 Subject: [PATCH 1/9] Add ability to select column from detail row in doc table. Store sort/columns on dashboard --- .../components/table_row/details.html | 2 +- .../components/doc_viewer/doc_viewer.html | 13 ++- .../components/doc_viewer/doc_viewer.js | 6 ++ .../index_patterns/_index_pattern.js | 4 +- src/kibana/directives/field_name.js | 4 +- .../dashboard/components/panel/lib/search.js | 3 + .../dashboard/components/panel/panel.html | 4 +- .../field_chooser/field_chooser.html | 3 +- .../components/field_chooser/field_chooser.js | 50 ++++++++++- .../plugins/discover/controllers/discover.js | 88 +------------------ src/kibana/plugins/discover/index.html | 5 +- src/kibana/utils/_mixins_chainable.js | 2 +- 12 files changed, 81 insertions(+), 103 deletions(-) diff --git a/src/kibana/components/doc_table/components/table_row/details.html b/src/kibana/components/doc_table/components/table_row/details.html index e8be1219c5d095..d83d868dbefeb1 100644 --- a/src/kibana/components/doc_table/components/table_row/details.html +++ b/src/kibana/components/doc_table/components/table_row/details.html @@ -2,5 +2,5 @@ Link to /{{row._index}}/{{row._type}}/{{row._id | uriescape}} - + \ No newline at end of file diff --git a/src/kibana/components/doc_viewer/doc_viewer.html b/src/kibana/components/doc_viewer/doc_viewer.html index b196bfe01b868a..d09ea203676190 100644 --- a/src/kibana/components/doc_viewer/doc_viewer.html +++ b/src/kibana/components/doc_viewer/doc_viewer.html @@ -15,13 +15,22 @@ - - + + + + + diff --git a/src/kibana/components/doc_viewer/doc_viewer.js b/src/kibana/components/doc_viewer/doc_viewer.js index fdd65b759b9a88..94d9aef7091f82 100644 --- a/src/kibana/components/doc_viewer/doc_viewer.js +++ b/src/kibana/components/doc_viewer/doc_viewer.js @@ -15,6 +15,7 @@ define(function (require) { hit: '=', indexPattern: '=', filter: '=?', + columns: '=?' }, link: function ($scope, $el, attr) { // If a field isn't in the mapping, use this @@ -34,6 +35,11 @@ define(function (require) { }); $scope.fields = _.keys($scope.flattened).sort(); + $scope.toggleColumn = function (fieldName) { + _.toggleInOut($scope.columns, fieldName); + console.log($scope.columns); + }; + $scope.showArrayInObjectsWarning = function (row, field) { var value = $scope.flattened[field]; return _.isArray(value) && typeof value[0] === 'object'; diff --git a/src/kibana/components/index_patterns/_index_pattern.js b/src/kibana/components/index_patterns/_index_pattern.js index dfda4e9867fd7d..c54f1bbdf70f93 100644 --- a/src/kibana/components/index_patterns/_index_pattern.js +++ b/src/kibana/components/index_patterns/_index_pattern.js @@ -104,7 +104,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 () { @@ -113,7 +113,7 @@ define(function (require) { } }, sortable: { - value: field.indexed && type.sortable + value: field.indexed && type && type.sortable }, scripted: { // enumerable properties end up in the JSON diff --git a/src/kibana/directives/field_name.js b/src/kibana/directives/field_name.js index 8b7eb52254bf4f..387434de3862d8 100644 --- a/src/kibana/directives/field_name.js +++ b/src/kibana/directives/field_name.js @@ -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); diff --git a/src/kibana/plugins/dashboard/components/panel/lib/search.js b/src/kibana/plugins/dashboard/components/panel/lib/search.js index 5d54d5ce1d59d7..57b4aa1c3207ef 100644 --- a/src/kibana/plugins/dashboard/components/panel/lib/search.js +++ b/src/kibana/plugins/dashboard/components/panel/lib/search.js @@ -3,6 +3,9 @@ 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; + return { savedObj: savedSearch, panel: panel, diff --git a/src/kibana/plugins/dashboard/components/panel/panel.html b/src/kibana/plugins/dashboard/components/panel/panel.html index 636b9f51836ca7..c16d6c9e3dec1e 100644 --- a/src/kibana/plugins/dashboard/components/panel/panel.html +++ b/src/kibana/plugins/dashboard/components/panel/panel.html @@ -21,8 +21,8 @@ diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html index d89e99c7fb31f3..706eeb7b55907d 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html @@ -25,7 +25,8 @@
Selected Fields
diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js index a9102e7098940c..a2b807e56c2b5c 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js @@ -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'); @@ -16,8 +17,7 @@ define(function (require) { return { restrict: 'E', scope: { - fields: '=', - toggle: '=', + columns: '=', data: '=', state: '=', indexPattern: '=', @@ -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 @@ -87,6 +90,10 @@ define(function (require) { filter.active = filter.getActive(); }); + $scope.toggle = function (fieldName) { + _.toggleInOut($scope.columns, fieldName); + }; + var calculateFields = function (newFields) { // Find the top N most popular fields $scope.popularFields = _(newFields) @@ -110,8 +117,45 @@ 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) { + if (oldColumns.length === 1 && oldColumns[0] === '_source' && columns.length > 1) { + _.pull(columns, '_source'); + } + + if (columns.length === 0) columns.push('_source'); + + _.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(d.$$_flattened); + }).flatten().unique().sort().value(); + _.each($scope.fields, function (field) { + field.inData = _.contains(currentFields, field.name) ? true : false; if (field.details) { $scope.details(field, true); } diff --git a/src/kibana/plugins/discover/controllers/discover.js b/src/kibana/plugins/discover/controllers/discover.js index a03aabfd6b86f5..0b22a8ffb15110 100644 --- a/src/kibana/plugins/discover/controllers/discover.js +++ b/src/kibana/plugins/discover/controllers/discover.js @@ -134,44 +134,6 @@ define(function (require) { $scope.failuresShown = showTotal; }; - // stores the complete list of fields - $scope.fields = _($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($state.columns, field.name); - clone.rowCount = $scope.rows ? $scope.rows.fieldCounts[field.name] : 0; - fields.push(clone); - }, []) - .value(); - - refreshColumns(); - - // listen for changes, and relisten everytime something happens - $scope.$listen($state, 'fetch_with_changes', updateFields); - $scope.$listen($state, 'reset_with_changes', updateFields); - function updateFields(changes) { - var newColumns = _.contains(changes, 'columns'); - var newIndex = _.contains(changes, 'index'); - var otherChanges = _.pull(changes, 'index', 'columns'); - - if (newIndex) { - // we will be reloading, don't need to juggle state - return; - } - - if (newColumns) { - $scope.fields.forEach(function (field) { - field.display = _.contains($state.columns, field.name); - }); - refreshColumns(); - } - - if (otherChanges.length) $scope.fetch(); - } - $scope.updateDataSource() .then(function () { $scope.$listen(timefilter, 'update', function () { @@ -290,10 +252,6 @@ define(function (require) { $scope.updateTime(); - if (_.isEmpty($state.columns)) { - refreshColumns(); - } - $scope.updateDataSource() .then(setupVisualization) .then(function () { @@ -398,11 +356,6 @@ define(function (require) { hit.$$_formatted = _.mapValues(hit.$$_flattened, formatAndCount); }); - // apply the field counts to the field list - // We could do this in the field_chooser but it would us to iterate the array again - $scope.fields.forEach(function (field) { - field.rowCount = counts[field.name] || 0; - }); })); segmented.on('mergedSegment', function (merged) { @@ -461,51 +414,14 @@ define(function (require) { filterManager.add(field, values, operation, $state.index); }; - $scope.toggleField = function (name) { - var field = _.find($scope.fields, { name: name }); - - // If we can't find the field in the mapping, ensure it isn't in the column list and abort - if (!field) { - $state.columns = _.without($state.columns, name); - return; - } - - // toggle the display property - field.display = !field.display; - - if ($state.columns.length === 1 && $state.columns[0] === '_source') { - $state.columns = _.toggleInOut($state.columns, name); - $state.columns = _.toggleInOut($state.columns, '_source'); - _.find($scope.fields, {name: '_source'}).display = false; - } else { - $state.columns = _.toggleInOut($state.columns, name); - } - - refreshColumns(); + $scope.toggleField = function (fieldName) { + _.toggleInOut($state.columns, fieldName); }; $scope.toTop = function () { $window.scrollTo(0, 0); }; - function refreshColumns() { - // Get all displayed field names; - var fields = _($scope.fields).filter('display').pluck('name').value(); - - // Make sure there are no columns added that aren't in the displayed field list. - $state.columns = _.intersection($state.columns, fields); - - // If no columns remain, use _source - if (!$state.columns.length) { - $scope.toggleField('_source'); - return; - } - - if (init.complete) { - $state.save(); - } - } - // TODO: Move to utility class var addSlashes = function (str) { if (!_.isString(str)) return str; diff --git a/src/kibana/plugins/discover/index.html b/src/kibana/plugins/discover/index.html index 1ee99121b38898..d70a41888474b5 100644 --- a/src/kibana/plugins/discover/index.html +++ b/src/kibana/plugins/discover/index.html @@ -47,8 +47,7 @@
diff --git a/src/kibana/utils/_mixins_chainable.js b/src/kibana/utils/_mixins_chainable.js index b3b8ceb4277e73..40aed3212e9774 100644 --- a/src/kibana/utils/_mixins_chainable.js +++ b/src/kibana/utils/_mixins_chainable.js @@ -65,7 +65,7 @@ define(function (require) { */ toggleInOut: function (arr, value) { if (_.contains(arr, value)) { - arr = _.without(arr, value); + arr.splice(arr.indexOf(value), 1); } else { arr.push(value); } From 285d7b2c797b1c707ef85398dacefe8074b21cfd Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Fri, 3 Apr 2015 16:13:13 -0700 Subject: [PATCH 2/9] Move _source logic to doc_table --- src/kibana/components/doc_table/doc_table.js | 9 +++++++++ src/kibana/components/doc_viewer/doc_viewer.js | 1 - .../discover/components/field_chooser/field_chooser.js | 6 ------ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/kibana/components/doc_table/doc_table.js b/src/kibana/components/doc_table/doc_table.js index b1454f371e661b..97f0d56e3fec02 100644 --- a/src/kibana/components/doc_table/doc_table.js +++ b/src/kibana/components/doc_table/doc_table.js @@ -55,6 +55,15 @@ define(function (require) { $scope.limit += 50; }; + $scope.$watchCollection('columns', function (columns, oldColumns) { + if (oldColumns.length === 1 && oldColumns[0] === '_source' && columns.length > 1) { + _.pull(columns, '_source'); + } + + if (columns.length === 0) columns.push('_source'); + }); + + $scope.$watch('searchSource', prereq(function (searchSource) { if (!$scope.searchSource) return; diff --git a/src/kibana/components/doc_viewer/doc_viewer.js b/src/kibana/components/doc_viewer/doc_viewer.js index 94d9aef7091f82..ddc612f45bc226 100644 --- a/src/kibana/components/doc_viewer/doc_viewer.js +++ b/src/kibana/components/doc_viewer/doc_viewer.js @@ -37,7 +37,6 @@ define(function (require) { $scope.toggleColumn = function (fieldName) { _.toggleInOut($scope.columns, fieldName); - console.log($scope.columns); }; $scope.showArrayInObjectsWarning = function (row, field) { diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js index a2b807e56c2b5c..95bed8e1613bd6 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js @@ -136,12 +136,6 @@ define(function (require) { }); $scope.$watchCollection('columns', function (columns, oldColumns) { - if (oldColumns.length === 1 && oldColumns[0] === '_source' && columns.length > 1) { - _.pull(columns, '_source'); - } - - if (columns.length === 0) columns.push('_source'); - _.each($scope.fields, function (field) { field.display = _.contains(columns, field.name) ? true : false; }); From 6d62154654f5b7cad030729e7d5f5414598642eb Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Fri, 3 Apr 2015 17:38:23 -0700 Subject: [PATCH 3/9] Fix button shifting with tooltip --- src/kibana/components/doc_viewer/doc_viewer.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kibana/components/doc_viewer/doc_viewer.html b/src/kibana/components/doc_viewer/doc_viewer.html index d09ea203676190..a674f81eaf7b92 100644 --- a/src/kibana/components/doc_viewer/doc_viewer.html +++ b/src/kibana/components/doc_viewer/doc_viewer.html @@ -17,9 +17,11 @@ @@ -29,6 +31,7 @@ From ed6460a8f12ac6f3889f0b1a3e99251ce6cb3046 Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Mon, 6 Apr 2015 12:53:19 -0700 Subject: [PATCH 4/9] Save state when columns or panel change --- .../plugins/dashboard/components/panel/lib/search.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/kibana/plugins/dashboard/components/panel/lib/search.js b/src/kibana/plugins/dashboard/components/panel/lib/search.js index 57b4aa1c3207ef..d5a147c187e66e 100644 --- a/src/kibana/plugins/dashboard/components/panel/lib/search.js +++ b/src/kibana/plugins/dashboard/components/panel/lib/search.js @@ -6,6 +6,14 @@ define(function (require) { 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, From f1687acaf9931a087bf774771ce351fddd063c3d Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Tue, 7 Apr 2015 13:48:22 -0700 Subject: [PATCH 5/9] Add remove button to table header --- .../doc_table/components/table_header.html | 9 +++---- .../doc_table/components/table_header.js | 11 ++++++++- src/kibana/components/doc_table/doc_table.js | 6 ++--- .../field_chooser/field_chooser.html | 6 ++--- .../components/field_chooser/field_chooser.js | 5 ++-- .../plugins/discover/controllers/discover.js | 23 ++++-------------- test/unit/fixtures/hits.js | 20 ++++++++-------- test/unit/fixtures/logstash_fields.js | 7 +++--- .../apps/discover/directives/field_chooser.js | 24 ++++++++++--------- .../specs/components/doc_table/doc_table.js | 2 +- 10 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/kibana/components/doc_table/components/table_header.html b/src/kibana/components/doc_table/components/table_header.html index 9a0c1e036ec541..0e43596bec8c2f 100644 --- a/src/kibana/components/doc_table/components/table_header.html +++ b/src/kibana/components/doc_table/components/table_header.html @@ -3,11 +3,12 @@ Time - - {{name | shortDots}} + + {{name | shortDots}} - - + + + \ No newline at end of file diff --git a/src/kibana/components/doc_table/components/table_header.js b/src/kibana/components/doc_table/components/table_header.js index c4611e6c1cda1b..3b73ca129001c9 100644 --- a/src/kibana/components/doc_table/components/table_header.js +++ b/src/kibana/components/doc_table/components/table_header.js @@ -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'); + 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; @@ -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; diff --git a/src/kibana/components/doc_table/doc_table.js b/src/kibana/components/doc_table/doc_table.js index 97f0d56e3fec02..e7e9e28f558cdc 100644 --- a/src/kibana/components/doc_table/doc_table.js +++ b/src/kibana/components/doc_table/doc_table.js @@ -56,11 +56,11 @@ define(function (require) { }; $scope.$watchCollection('columns', function (columns, oldColumns) { - if (oldColumns.length === 1 && oldColumns[0] === '_source' && columns.length > 1) { - _.pull(columns, '_source'); + if (oldColumns.length === 1 && oldColumns[0] === '_source' && $scope.columns.length > 1) { + _.pull($scope.columns, '_source'); } - if (columns.length === 0) columns.push('_source'); + if ($scope.columns.length === 0) $scope.columns.push('_source'); }); diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html index 706eeb7b55907d..07a06d7df1eebc 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html @@ -31,7 +31,7 @@
Selected Fields
diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js index 350061f4bc7d41..4f625463db731c 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js @@ -91,6 +91,7 @@ define(function (require) { }); $scope.toggle = function (fieldName) { + $scope.increaseFieldCounter(fieldName); _.toggleInOut($scope.columns, fieldName); }; @@ -156,8 +157,8 @@ define(function (require) { }); }); - $scope.increaseFieldCounter = function (field) { - $scope.indexPattern.popularizeField(field.name, 1); + $scope.increaseFieldCounter = function (fieldName) { + $scope.indexPattern.popularizeField(fieldName, 1); }; $scope.runAgg = function (field) { diff --git a/src/kibana/plugins/discover/controllers/discover.js b/src/kibana/plugins/discover/controllers/discover.js index 0636e33f6d85ea..13994cda8c06d1 100644 --- a/src/kibana/plugins/discover/controllers/discover.js +++ b/src/kibana/plugins/discover/controllers/discover.js @@ -111,6 +111,10 @@ define(function (require) { $state.index = $scope.indexPattern.id; $state.sort = getSort.array($state.sort, $scope.indexPattern); + $scope.$watchCollection('state.columns', function (columns) { + $state.save(); + }); + var metaFields = config.get('metaFields'); filterManager.init($state); @@ -397,25 +401,12 @@ define(function (require) { .set('filter', $state.filters || []); }); - // This is a hacky optimization for comparing the contents of a large array to a short one. - function arrayToKeys(array, value) { - var obj = {}; - _.each(array, function (key) { - obj[key] = value || true; - }); - return obj; - } - // TODO: On array fields, negating does not negate the combination, rather all terms $scope.filterQuery = function (field, values, operation) { $scope.indexPattern.popularizeField(field, 1); filterManager.add(field, values, operation, $state.index); }; - $scope.toggleField = function (fieldName) { - _.toggleInOut($state.columns, fieldName); - }; - $scope.toTop = function () { $window.scrollTo(0, 0); }; @@ -430,12 +421,6 @@ define(function (require) { return str; }; - // TODO: Move to utility class - // https://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - var regexEscape = function (str) { - return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - }; - var loadingVis; var setupVisualization = function () { // If we're not setting anything up we need to return an empty promise diff --git a/test/unit/fixtures/hits.js b/test/unit/fixtures/hits.js index 61fef38a06817e..b368d2ab1e3c21 100644 --- a/test/unit/fixtures/hits.js +++ b/test/unit/fixtures/hits.js @@ -1,16 +1,16 @@ define(function (require) { var _ = require('lodash'); return _.map([ - {_source: {timestamp: 0, bytes: 10, request: 'foo'}}, - {_source: {timestamp: 1, bytes: 20, request: 'bar'}}, - {_source: {timestamp: 2, bytes: 30, request: 'bar'}}, - {_source: {timestamp: 3, bytes: 30, request: 'baz'}}, - {_source: {timestamp: 4, bytes: 30, request: 'baz'}}, - {_source: {timestamp: 5, bytes: 30, request: 'baz'}}, - {_source: {timestamp: 6, bytes: 40.1415926535, request: 'bat'}}, - {_source: {timestamp: 7, bytes: 40.1415926535, request: 'bat'}}, - {_source: {timestamp: 8, bytes: 40.1415926535, request: 'bat'}}, - {_source: {timestamp: 9, bytes: 40.1415926535, request: 'bat'}}, + {_source: {'@timestamp': 0, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 10, request: 'foo'}}, + {_source: {'@timestamp': 1, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 20, request: 'bar'}}, + {_source: {'@timestamp': 2, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 30, request: 'bar'}}, + {_source: {'@timestamp': 3, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 30, request: 'baz'}}, + {_source: {'@timestamp': 4, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 30, request: 'baz'}}, + {_source: {'@timestamp': 5, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 30, request: 'baz'}}, + {_source: {'@timestamp': 6, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 40.141592, request: 'bat'}}, + {_source: {'@timestamp': 7, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 40.141592, request: 'bat'}}, + {_source: {'@timestamp': 8, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 40.141592, request: 'bat'}}, + {_source: {'@timestamp': 9, ssl: true, ip: '192.168.0.1', extension: 'php', 'machine.os': 'Linux', bytes: 40.141592, request: 'bat'}}, ], function (p, i) { return _.merge({}, p, { _score: 1, diff --git a/test/unit/fixtures/logstash_fields.js b/test/unit/fixtures/logstash_fields.js index 17dacf06205759..b7b0479a738fa4 100644 --- a/test/unit/fixtures/logstash_fields.js +++ b/test/unit/fixtures/logstash_fields.js @@ -16,9 +16,10 @@ define(function (require) { { name: 'geo.src', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, { name: '_type', type: 'string', indexed: true, analyzed: true, sortable: true, filterable: true }, { name: '_id', type: 'string', indexed: false, analyzed: false, sortable: false, filterable: true}, - { name: 'custom_user_field', type: 'conflict', indexed: false, analyzed: false }, - { name: 'script string', type: 'string', scripted: true, script: '\'i am a string\'', lang: 'expression'}, - { name: 'script number', type: 'number', scripted: true, script: '1234', lang: 'expression'}, + { name: '_source', type: 'string', indexed: false, analyzed: false, sortable: false, filterable: false}, + { name: 'custom_user_field', type: 'conflict', indexed: false, analyzed: false, sortable: false, filterable: true }, + { name: 'script string', type: 'string', scripted: true, script: '\'i am a string\'', lang: 'expression'}, + { name: 'script number', type: 'number', scripted: true, script: '1234', lang: 'expression'}, ].map(function (field) { field.count = field.count || 0; field.scripted = field.scripted || false; diff --git a/test/unit/specs/apps/discover/directives/field_chooser.js b/test/unit/specs/apps/discover/directives/field_chooser.js index 3b6238fda43294..50b4b57b321ef2 100644 --- a/test/unit/specs/apps/discover/directives/field_chooser.js +++ b/test/unit/specs/apps/discover/directives/field_chooser.js @@ -12,12 +12,17 @@ define(function (require) { // Sets up the directive, take an element, and a list of properties to attach to the parent scope. var init = function ($elem, props) { - inject(function ($rootScope, $compile, _config_) { + inject(function ($rootScope, $compile, $timeout, _config_) { config = _config_; $parentScope = $rootScope; _.assign($parentScope, props); $compile($elem)($parentScope); - $elem.scope().$digest(); + + // Required for test to run solo. Sigh + $timeout(function () { + $elem.scope().$digest(); + }, 0); + $scope = $elem.isolateScope(); }); }; @@ -30,7 +35,7 @@ define(function (require) { describe('discover field chooser directives', function () { var $elem = angular.element( ' Date: Tue, 7 Apr 2015 15:07:53 -0700 Subject: [PATCH 6/9] Update tests --- .../components/field_chooser/field_chooser.js | 2 +- .../specs/apps/discover/directives/field_chooser.js | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js index 4f625463db731c..144c856be9e0e2 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.js +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.js @@ -146,7 +146,7 @@ define(function (require) { // Get all fields current in data set var currentFields = _.chain($scope.data).map(function (d) { - return _.keys(d.$$_flattened); + return _.keys($scope.indexPattern.flattenHit(d)); }).flatten().unique().sort().value(); _.each($scope.fields, function (field) { diff --git a/test/unit/specs/apps/discover/directives/field_chooser.js b/test/unit/specs/apps/discover/directives/field_chooser.js index 50b4b57b321ef2..ea7e82f87c611f 100644 --- a/test/unit/specs/apps/discover/directives/field_chooser.js +++ b/test/unit/specs/apps/discover/directives/field_chooser.js @@ -118,32 +118,35 @@ define(function (require) { }); it('should not show the popular fields if there are not any', function (done) { + // Re-init destroy(); + + _.each(indexPattern.fields, function (field) { field.count = 0;}); // Reset the popular fields init($elem, { columns: [], toggle: sinon.spy(), data: require('fixtures/hits'), filter: sinon.spy(), - indexPattern: indexPattern.fields + indexPattern: indexPattern }); var section = getSections($elem); - // Remove the popular fields + $scope.$digest(); expect(section.popular.hasClass('ng-hide')).to.be(true); expect(section.popular.find('li:not(.sidebar-list-header)').length).to.be(0); done(); }); - it('should move the field into selected when setting field.display', function (done) { + it('should move the field into selected when it is added to the columns array', function (done) { var section = getSections($elem); - indexPattern.fields.byName.bytes.display = true; + $scope.columns.push('bytes'); $scope.$digest(); expect(section.selected.text()).to.contain('bytes'); expect(section.popular.text()).to.not.contain('bytes'); - indexPattern.fields.byName.ip.display = true; + $scope.columns.push('ip'); $scope.$digest(); expect(section.selected.text()).to.contain('ip\n'); expect(section.unpopular.text()).to.not.contain('ip\n'); From 542638f45f609942caa3df8e2a20edbb122969a5 Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Tue, 7 Apr 2015 15:09:14 -0700 Subject: [PATCH 7/9] Remove debug --- .../plugins/discover/components/field_chooser/field_chooser.html | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html index 07a06d7df1eebc..6cf4725d62ec0d 100644 --- a/src/kibana/plugins/discover/components/field_chooser/field_chooser.html +++ b/src/kibana/plugins/discover/components/field_chooser/field_chooser.html @@ -26,7 +26,6 @@
Selected Fields
    - Beer
From a4f9bbd263a646ecefd9cf38ec90dd9a94122ff2 Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Wed, 8 Apr 2015 14:10:13 -0700 Subject: [PATCH 8/9] Add bugfix watcher for cases when initial column set is undefined or empty --- src/kibana/components/doc_table/doc_table.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/kibana/components/doc_table/doc_table.js b/src/kibana/components/doc_table/doc_table.js index e7e9e28f558cdc..7d6d2fe438cef4 100644 --- a/src/kibana/components/doc_table/doc_table.js +++ b/src/kibana/components/doc_table/doc_table.js @@ -55,6 +55,11 @@ 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) $scope.columns.push('_source'); + }); + $scope.$watchCollection('columns', function (columns, oldColumns) { if (oldColumns.length === 1 && oldColumns[0] === '_source' && $scope.columns.length > 1) { _.pull($scope.columns, '_source'); From 7c0e1992e1c777e567d63136dbaaa2a9933142b9 Mon Sep 17 00:00:00 2001 From: Rashid Khan Date: Thu, 9 Apr 2015 14:18:27 -0700 Subject: [PATCH 9/9] Fix potential back button breaker --- src/kibana/components/doc_table/doc_table.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/kibana/components/doc_table/doc_table.js b/src/kibana/components/doc_table/doc_table.js index 7d6d2fe438cef4..d2c04a69d24fc4 100644 --- a/src/kibana/components/doc_table/doc_table.js +++ b/src/kibana/components/doc_table/doc_table.js @@ -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, @@ -57,7 +57,11 @@ define(function (require) { // 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) $scope.columns.push('_source'); + if (columns.length !== 0) return; + + var $state = getAppState(); + $scope.columns.push('_source'); + if ($state) $state.replace(); }); $scope.$watchCollection('columns', function (columns, oldColumns) {