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

[Discover] New field stats in Discover sidebar popover #139072

Merged
merged 122 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 116 commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
e6ea7a8
[UnifiedFieldList] Bootstrap a new unifiedFieldList plugin
jughosta Jul 13, 2022
4fe9db0
[UnifiedFieldList] Move backend API for field stats from Lens to Unif…
jughosta Jul 13, 2022
68405a5
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine Jul 13, 2022
d46c7a1
[Discover] Address CI checks
jughosta Jul 14, 2022
f74243b
[UnifiedFieldList] Move field stats UI from Lens to UnifiedFieldList …
jughosta Jul 14, 2022
cee3b40
Merge remote-tracking branch 'upstream/main' into 135886-field-stats
jughosta Jul 18, 2022
968454a
[Discover] Integrate FieldStats into Discover field popover
jughosta Jul 18, 2022
f14fe4c
[Discover] Show both views side to side
jughosta Jul 18, 2022
116098b
[Discover] Allow for some customization
jughosta Jul 18, 2022
3243220
[Discover] Allow for more customization
jughosta Jul 19, 2022
b7e77a3
[UnifiedFieldList] Remove temporary code
jughosta Jul 19, 2022
4bac591
[UnifiedFieldList] Extract styles
jughosta Jul 19, 2022
60a3ca9
Merge branch 'main' into 135886-field-stats
kibanamachine Jul 19, 2022
8048325
Merge remote-tracking branch 'upstream/main' into 135886-field-stats
jughosta Aug 2, 2022
c072ed9
[UnifiedFieldList] Fix after merge
jughosta Aug 3, 2022
5c5f4d2
[UnifiedFieldList] Extend i18n
jughosta Aug 3, 2022
67f0568
[UnifiedFieldList] Migrate stats API from server to public
jughosta Aug 3, 2022
3e09343
[UnifiedFieldList] Update types
jughosta Aug 4, 2022
ffb9520
[UnifiedFieldList] Update Lens tests
jughosta Aug 4, 2022
a53242d
[UnifiedFieldList] Update Lens tests
jughosta Aug 10, 2022
1c989a3
[UnifiedFieldList] Before merging
jughosta Aug 10, 2022
6d634e2
Merge remote-tracking branch 'upstream/main' into 135886-field-stats
jughosta Aug 10, 2022
e10f286
[UnifiedFieldList] After merging
jughosta Aug 10, 2022
1f8144a
[UnifiedFieldList] Refactor localization keys
jughosta Aug 11, 2022
5c9379b
[UnifiedFieldList] Update types
jughosta Aug 11, 2022
f6f8706
[UnifiedFieldList] Reintroduce server API for field stats and refacto…
jughosta Aug 11, 2022
e4dbbcd
[UnifiedFieldList] Update limits
jughosta Aug 11, 2022
6f5025b
Merge branch 'main' into 135886-field-stats
kibanamachine Aug 11, 2022
97f5f82
[UnifiedFieldList] Rename the component
jughosta Aug 11, 2022
0e5a2c9
[UnifiedFieldList] Improve types
jughosta Aug 11, 2022
c9e3edb
[UnifiedFieldList] Add AbortController
jughosta Aug 11, 2022
48bc2b8
[UnifiedFieldList] Render counts in PopoverFooter in Lens
jughosta Aug 11, 2022
0e78ac2
[UnifiedFieldList] Hide new stats from Discover for now
jughosta Aug 11, 2022
41baa7a
[UnifiedFieldList] Fix tests
jughosta Aug 12, 2022
937e8f7
[UnifiedFieldList] Rename to loadFieldStats
jughosta Aug 12, 2022
693959c
[UnifiedFieldList] Rearrange utils
jughosta Aug 12, 2022
ce26c85
[UnifiedFieldList] Fix types
jughosta Aug 12, 2022
ac72b8d
Merge remote-tracking branch 'upstream/main' into 135886-field-stats
jughosta Aug 12, 2022
e6b9a1c
[UnifiedFieldList] Fix references
jughosta Aug 12, 2022
51c852d
[UnifiedFieldList] Use emotion css
jughosta Aug 12, 2022
e81624d
[UnifiedFieldList] Increase limits
jughosta Aug 12, 2022
7a5f235
[UnifiedFieldList] Add first tests
jughosta Aug 15, 2022
9af3496
[UnifiedFieldList] Add more tests
jughosta Aug 15, 2022
5118ac5
Merge branch 'main' into 135886-field-stats
kibanamachine Aug 15, 2022
bcee335
Merge remote-tracking branch 'upstream/main' into 135886-field-stats
jughosta Aug 16, 2022
6cebb32
[UnifiedFieldList] Refactor interface to accept services object
jughosta Aug 16, 2022
c5df448
[UnifiedFieldList] Update types
jughosta Aug 16, 2022
3f90cad
[UnifiedFieldList] Add docs
jughosta Aug 16, 2022
3a318aa
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine Aug 16, 2022
1d5c2f9
[UnifiedFieldList] Add missing references
jughosta Aug 16, 2022
d5c72d0
Merge remote-tracking branch 'origin/135886-field-stats' into 135886-…
jughosta Aug 16, 2022
871016a
[UnifiedFieldList] Tmp
jughosta Aug 16, 2022
3f4ae6e
[UnifiedFieldList] Revert changes from Discover for now
jughosta Aug 16, 2022
dd178a1
Merge branch 'main' into 135886-field-stats
kibanamachine Aug 16, 2022
97797bd
Revert "[UnifiedFieldList] Revert changes from Discover for now"
jughosta Aug 16, 2022
8306e29
[Discover] Extract top values UI into a separate component. Update co…
jughosta Aug 17, 2022
f026663
[Discover] Extract bucket UI into a separate component. Update colors.
jughosta Aug 17, 2022
25a122b
[Discover] Update styling
jughosta Aug 17, 2022
e3b289e
[Discover] Fix empty values
jughosta Aug 17, 2022
486527c
[Discover] Allow to customize colors
jughosta Aug 17, 2022
835679c
[Discover] Add filter buttons
jughosta Aug 17, 2022
e844c66
[Discover] Rename props
jughosta Aug 17, 2022
94a1fcf
[Discover] Improve format
jughosta Aug 17, 2022
f6b05d5
[Discover] Add a switch in Settings. Move Visualize button into Popov…
jughosta Aug 23, 2022
6ae7fe8
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Aug 23, 2022
055bb1a
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Aug 23, 2022
a0d71c5
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Aug 23, 2022
875969d
[Discover] Fix props
jughosta Aug 23, 2022
7d25dc5
[Discover] Hide filter buttons for Other section
jughosta Aug 23, 2022
1f70f57
[Discover] Simplify default messages when analysis is not available
jughosta Aug 23, 2022
f64d36f
[Discover] Small update
jughosta Aug 24, 2022
da4dc19
[Discover] Remove translations
jughosta Aug 24, 2022
e3c2721
[Discover] Update some tests
jughosta Aug 24, 2022
49d4cb3
[Discover] Fallback to old Discover logic and show examples for non-a…
jughosta Aug 25, 2022
210d5be
[Discover] Exclude vector fields
jughosta Aug 25, 2022
15a7151
[Discover] Don't call details unless for legacy code
jughosta Aug 25, 2022
f41f12a
[Discover] Fix types
jughosta Aug 25, 2022
194e1f9
[Discover] Small update for stories
jughosta Aug 25, 2022
7baeb56
[Discover] Adapt tests
jughosta Aug 25, 2022
953409c
[Discover] Update tests
jughosta Aug 25, 2022
42ea0ed
[Discover] Update tests
jughosta Aug 26, 2022
86e6f86
[Discover] Update tests
jughosta Aug 26, 2022
d3fc87d
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Aug 29, 2022
cc0e700
[Discover] Update tests
jughosta Aug 29, 2022
499b9e3
[Discover] Update tests
jughosta Aug 30, 2022
dde211e
[Discover] Add tooltips. Update examples sample values. Update tests.
jughosta Aug 30, 2022
6ae21cd
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Aug 30, 2022
0cb63f7
[Discover] Close the popover when filter is pressed
jughosta Aug 30, 2022
e8d0650
[Discover] Add functional tests for non-aggregatable fields
jughosta Aug 31, 2022
4a43224
[Discover] Fix query
jughosta Aug 31, 2022
42324d8
[Discover] Add more tests
jughosta Aug 31, 2022
70088b2
[Discover] Add more tests
jughosta Aug 31, 2022
66a985d
[Discover] Add more tests
jughosta Aug 31, 2022
676f35f
[Discover] Add more tests
jughosta Aug 31, 2022
65c393b
[Discover] Fix time range for field stats
jughosta Sep 1, 2022
60c9da0
[Discover] Remove sort param from examples query
jughosta Sep 1, 2022
2524ffc
[Discover] Prevent reduntant requests
jughosta Sep 1, 2022
1a2c4f5
[Discover] Increase examples size
jughosta Sep 1, 2022
a69517b
[Discover] Add exist filter to Discover popover
jughosta Sep 1, 2022
8c3e4e6
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 1, 2022
8023cbf
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 1, 2022
adc7c34
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 5, 2022
2db92bf
[Discover] Update label
jughosta Sep 5, 2022
b16c2e6
[Discover] Update logic for picking a multifield
jughosta Sep 6, 2022
c037fe8
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 7, 2022
32bc2db
[Discover] Fix how percentage is calculated for Examples view (non-ag…
jughosta Sep 7, 2022
4b65020
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 7, 2022
466c1f5
Merge branch 'main' into 135886-field-stats-in-discover
flash1293 Sep 8, 2022
893216c
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 9, 2022
473ec1d
[Discover] Update copy and uncomment console error
jughosta Sep 9, 2022
8c35550
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 9, 2022
9da4332
[Discover] Add "no data" message and update field type check in examples
jughosta Sep 9, 2022
13c82df
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 12, 2022
f1fd147
Merge branch '135886-field-stats-in-discover' of github.com:jughosta/…
jughosta Sep 14, 2022
890acef
[Discover] Update type checks and no-data copy
jughosta Sep 14, 2022
0fec48d
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 14, 2022
10234a9
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 14, 2022
5151fa8
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 14, 2022
011ff80
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 14, 2022
2eca3c3
[Discover] Update copy
jughosta Sep 15, 2022
a401543
Merge remote-tracking branch 'upstream/main' into 135886-field-stats-…
jughosta Sep 15, 2022
b77a6d9
Merge branch 'main' into 135886-field-stats-in-discover
kibanamachine Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/management/advanced-options.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ the minimum and maximum values of a numeric field or a map of a geo field.
[[discover:showMultiFields]]`discover:showMultiFields`::
Controls the display of multi-fields in the expanded document view.

[[discover:showLegacyFieldTopValues]]`discover:showLegacyFieldTopValues`::
This setting will calculate Top Values for a field based only on the loaded records on Discover page.
To use the new and more accurate view, turn off this option.

[[discover-sort-defaultorder]]`discover:sort:defaultOrder`::
The default sort direction for time-based data views.

Expand Down
1 change: 1 addition & 0 deletions src/plugins/discover/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ export const TRUNCATE_MAX_HEIGHT = 'truncate:maxHeight';
export const ROW_HEIGHT_OPTION = 'discover:rowHeightOption';
export const SEARCH_EMBEDDABLE_TYPE = 'search';
export const HIDE_ANNOUNCEMENTS = 'hideAnnouncements';
export const SHOW_LEGACY_FIELD_TOP_VALUES = 'discover:showLegacyFieldTopValues';
export const ENABLE_SQL = 'discover:enableSql';
3 changes: 2 additions & 1 deletion src/plugins/discover/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"savedObjectsManagement",
"dataViewFieldEditor",
"dataViewEditor",
"expressions"
"expressions",
"unifiedFieldList"
],
"optionalPlugins": [
"home",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const services = {
getAbsoluteTime: () => {
return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' };
},
getTime: () => ({
from: 'now-7d',
to: 'now',
}),
},
},
savedQueries: { findSavedQueries: () => Promise.resolve({ queries: [] as SavedQuery[] }) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export function getDocumentsLayoutProps(dataView: DataView) {
language: 'kuery',
query: '',
},
filters: [],
},
} as unknown as DiscoverLayoutProps;
}
Expand All @@ -186,6 +187,7 @@ export const getPlainRecordLayoutProps = (dataView: DataView) => {
query: {
sql: 'SELECT * FROM "kibana_sample_data_ecommerce"',
},
filters: [],
},
} as unknown as DiscoverLayoutProps;
};
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ storiesOf('components/sidebar/DiscoverFieldDetails', module)
<DiscoverFieldDetails
field={field}
dataView={dataView}
details={{ buckets: [], error: 'An error occurred', exists: 1, total: 2, columns: [] }}
details={{ buckets: [], error: 'An error occurred', exists: 1, total: 2 }}
onAddFilter={() => {}}
/>
));
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,43 @@
* Side Public License, v 1.
*/

import { act } from 'react-dom/test-utils';
import { EuiPopover, EuiProgress, EuiButtonIcon } from '@elastic/eui';
import { ReactWrapper } from 'enzyme';
import React from 'react';
import { findTestSubject } from '@elastic/eui/lib/test';
import { mountWithIntl } from '@kbn/test-jest-helpers';

import { DiscoverField } from './discover_field';
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
import { fieldFormatsServiceMock } from '@kbn/field-formats-plugin/public/mocks';
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
import { DiscoverField, DiscoverFieldProps } from './discover_field';
import { DataViewField } from '@kbn/data-views-plugin/public';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { stubDataView } from '@kbn/data-views-plugin/common/data_view.stub';

jest.mock('@kbn/unified-field-list-plugin/public/services/field_stats', () => ({
loadFieldStats: jest.fn().mockResolvedValue({
totalDocuments: 1624,
sampledDocuments: 1624,
sampledValues: 3248,
topValues: {
buckets: [
{
count: 2042,
key: 'osx',
},
{
count: 1206,
key: 'winx',
},
],
},
}),
}));

const dataServiceMock = dataPluginMock.createStartContract();

jest.mock('../../../../kibana_services', () => ({
getUiActions: jest.fn(() => {
return {
Expand All @@ -23,16 +51,18 @@ jest.mock('../../../../kibana_services', () => ({
}),
}));

function getComponent({
async function getComponent({
selected = false,
showDetails = false,
showFieldStats = false,
field,
onAddFilterExists = true,
showLegacyFieldTopValues = false,
}: {
selected?: boolean;
showDetails?: boolean;
showFieldStats?: boolean;
field?: DataViewField;
onAddFilterExists?: boolean;
showLegacyFieldTopValues?: boolean;
}) {
const finalField =
field ??
Expand All @@ -47,15 +77,20 @@ function getComponent({
readFromDocValues: true,
});

const props = {
const props: DiscoverFieldProps = {
dataView: stubDataView,
field: finalField,
getDetails: jest.fn(() => ({ buckets: [], error: '', exists: 1, total: 2, columns: [] })),
getDetails: jest.fn(() => ({ buckets: [], error: '', exists: 1, total: 2 })),
...(onAddFilterExists && { onAddFilter: jest.fn() }),
onAddField: jest.fn(),
onRemoveField: jest.fn(),
showDetails,
showFieldStats,
selected,
state: {
query: { query: '', language: 'lucene' },
filters: [],
},
contextualFields: [],
};
const services = {
history: () => ({
Expand All @@ -73,10 +108,32 @@ function getComponent({
if (key === 'fields:popularLimit') {
return 5;
}
if (key === 'discover:showLegacyFieldTopValues') {
return showLegacyFieldTopValues;
}
},
},
data: {
...dataServiceMock,
query: {
...dataServiceMock.query,
timefilter: {
...dataServiceMock.query.timefilter,
timefilter: {
...dataServiceMock.query.timefilter.timefilter,
getAbsoluteTime: () => ({
from: '2021-08-31T22:00:00.000Z',
to: '2022-09-01T09:16:29.553Z',
}),
},
},
},
},
dataViews: dataViewPluginMocks.createStartContract(),
fieldFormats: fieldFormatsServiceMock.createStartContract(),
charts: chartPluginMock.createSetupContract(),
};
const comp = mountWithIntl(
const comp = await mountWithIntl(
<KibanaContextProvider services={services}>
<DiscoverField {...props} />
</KibanaContextProvider>
Expand All @@ -85,22 +142,26 @@ function getComponent({
}

describe('discover sidebar field', function () {
it('should allow selecting fields', function () {
const { comp, props } = getComponent({});
it('should allow selecting fields', async function () {
const { comp, props } = await getComponent({});
findTestSubject(comp, 'fieldToggle-bytes').simulate('click');
expect(props.onAddField).toHaveBeenCalledWith('bytes');
});
it('should allow deselecting fields', function () {
const { comp, props } = getComponent({ selected: true });
it('should allow deselecting fields', async function () {
const { comp, props } = await getComponent({ selected: true });
findTestSubject(comp, 'fieldToggle-bytes').simulate('click');
expect(props.onRemoveField).toHaveBeenCalledWith('bytes');
});
it('should trigger getDetails', function () {
const { comp, props } = getComponent({ selected: true });
it('should trigger getDetails', async function () {
const { comp, props } = await getComponent({
selected: true,
showFieldStats: true,
showLegacyFieldTopValues: true,
});
findTestSubject(comp, 'field-bytes-showDetails').simulate('click');
expect(props.getDetails).toHaveBeenCalledWith(props.field);
});
it('should not allow clicking on _source', function () {
it('should not allow clicking on _source', async function () {
const field = new DataViewField({
name: '_source',
type: '_source',
Expand All @@ -109,14 +170,15 @@ describe('discover sidebar field', function () {
aggregatable: true,
readFromDocValues: true,
});
const { comp, props } = getComponent({
const { comp, props } = await getComponent({
selected: true,
field,
showLegacyFieldTopValues: true,
});
findTestSubject(comp, 'field-_source-showDetails').simulate('click');
expect(props.getDetails).not.toHaveBeenCalled();
});
it('displays warning for conflicting fields', function () {
it('displays warning for conflicting fields', async function () {
const field = new DataViewField({
name: 'troubled_field',
type: 'conflict',
Expand All @@ -125,23 +187,26 @@ describe('discover sidebar field', function () {
aggregatable: true,
readFromDocValues: false,
});
const { comp } = getComponent({
const { comp } = await getComponent({
selected: true,
field,
});
const dscField = findTestSubject(comp, 'field-troubled_field-showDetails');
expect(dscField.find('.kbnFieldButton__infoIcon').length).toEqual(1);
});
it('should not execute getDetails when rendered, since it can be expensive', function () {
const { props } = getComponent({});
expect(props.getDetails.mock.calls.length).toEqual(0);
it('should not execute getDetails when rendered, since it can be expensive', async function () {
const { props } = await getComponent({});
expect(props.getDetails).toHaveBeenCalledTimes(0);
});
it('should execute getDetails when show details is requested', function () {
const { props, comp } = getComponent({});
it('should execute getDetails when show details is requested', async function () {
const { props, comp } = await getComponent({
showFieldStats: true,
showLegacyFieldTopValues: true,
});
findTestSubject(comp, 'field-bytes-showDetails').simulate('click');
expect(props.getDetails.mock.calls.length).toEqual(1);
expect(props.getDetails).toHaveBeenCalledTimes(1);
});
it('should not return the popover if onAddFilter is not provided', function () {
it('should not return the popover if onAddFilter is not provided', async function () {
const field = new DataViewField({
name: '_source',
type: '_source',
Expand All @@ -150,12 +215,45 @@ describe('discover sidebar field', function () {
aggregatable: true,
readFromDocValues: true,
});
const { comp } = getComponent({
const { comp } = await getComponent({
selected: true,
field,
onAddFilterExists: false,
});
const popover = findTestSubject(comp, 'discoverFieldListPanelPopover');
expect(popover.length).toBe(0);
});
it('should request field stats', async function () {
const field = new DataViewField({
name: 'machine.os.raw',
type: 'string',
esTypes: ['keyword'],
aggregatable: true,
searchable: true,
});
let comp: ReactWrapper;

await act(async () => {
const result = await getComponent({ showFieldStats: true, field, onAddFilterExists: true });
comp = result.comp;
await comp.update();
});

await act(async () => {
const fieldItem = findTestSubject(comp, 'field-machine.os.raw-showDetails');
await fieldItem.simulate('click');
await comp.update();
});

await comp!.update();

expect(comp!.find(EuiPopover).prop('isOpen')).toBe(true);
expect(findTestSubject(comp!, 'dscFieldStats-title').text()).toBe('Top values');
expect(findTestSubject(comp!, 'dscFieldStats-topValues-bucket')).toHaveLength(2);
expect(
findTestSubject(comp!, 'dscFieldStats-topValues-formattedFieldValue').first().text()
).toBe('osx');
expect(comp!.find(EuiProgress)).toHaveLength(2);
expect(findTestSubject(comp!, 'dscFieldStats-topValues').find(EuiButtonIcon)).toHaveLength(4);
});
});
Loading