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] Add support for unmapped fields using the fields API #89074

Merged
merged 94 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from 86 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
a232550
Add search source to example plugin.
lukeelmers Oct 27, 2020
ba796e0
Add uiSetting for fields API.
lukeelmers Oct 27, 2020
9fbcc82
Update SearchSource to support fields API.
lukeelmers Oct 27, 2020
5afd264
[PoC] reading from the fields API in Discover
Nov 20, 2020
ac1e273
Add N fields as a default column
Nov 20, 2020
e6f2a22
Make fields column non-removeable
Nov 20, 2020
c420e96
Merge master
Nov 25, 2020
8ad5f99
Do not add 'fields' to state
Nov 25, 2020
64f0868
Remove fields from app state and read from source when needed
Nov 26, 2020
b843d33
Remove fields column if a new column is added
Nov 30, 2020
1a3196d
Add search source to example plugin.
lukeelmers Oct 27, 2020
0cf84e4
Add uiSetting for fields API.
lukeelmers Oct 27, 2020
ad23b7f
Update SearchSource to support fields API.
lukeelmers Oct 27, 2020
3681311
Improve error handling in search examples plugin.
lukeelmers Nov 16, 2020
5ac33bb
Add unit tests for legacy behavior.
lukeelmers Nov 20, 2020
9e6c89f
Remove uiSettings feature flag; add fieldsFromSource config.
lukeelmers Nov 20, 2020
d34ab66
Rewrite flatten() based on final API design.
lukeelmers Nov 20, 2020
4773949
Update example app based on final API design.
lukeelmers Nov 23, 2020
d272609
Update maps app to use legacy fieldsFromSource.
lukeelmers Nov 23, 2020
30c7c5f
Update Discover to use legacy fieldsFromSource.
lukeelmers Nov 23, 2020
24a5f9d
Rename source filters to field filters.
lukeelmers Nov 24, 2020
9c7a967
Address feedback.
lukeelmers Nov 30, 2020
5c124f8
Update generated docs.
lukeelmers Nov 30, 2020
79e59a8
Update maps functional test.
lukeelmers Nov 30, 2020
f7d304b
Formatting fields column similar to _source
Nov 30, 2020
4053bf1
Merge upstream
Dec 1, 2020
ee33143
Moving logic for using search API to updating search source
Dec 1, 2020
e3ace69
Fix small merge error
Dec 1, 2020
84136f6
Merge branch 'master' into feat/ssource-fields
kibanamachine Dec 1, 2020
804c5f8
Merge branch 'feat/ssource-fields' of https://github.com/lukeelmers/k…
Dec 2, 2020
29fe624
Move useSource switch to Discover section of advanced settings
Dec 2, 2020
900637b
Do not use fields and source at the same time
Dec 2, 2020
9fc9517
Remove unmapped fields switch
Dec 2, 2020
92253eb
Add basic support for grouping multifields
Dec 3, 2020
00d6c68
Merge master
Dec 3, 2020
5e6162c
Remove output.txt
Dec 3, 2020
e16cdcb
Fix some merge leftovers
Dec 3, 2020
5e0f998
Fix some merge leftovers
Dec 3, 2020
9791498
Merge branch 'master' into discover-ssource-fields
Dec 3, 2020
63e49d4
Fix merge errors
Dec 3, 2020
a80d44d
Fix typescript errors and update nested fields logic
Dec 4, 2020
60119b9
Add a unit test
Dec 4, 2020
8583723
Fixing field formats
Dec 4, 2020
e21e478
Merge master
Dec 4, 2020
5108654
Fix multifield selection logic
Dec 5, 2020
448bc7a
Request all fields from source
Dec 6, 2020
dc5f148
Fix eslint
Dec 6, 2020
f260376
Fix default columns when switching between _source and fields
Dec 6, 2020
a2273f7
Merge branch 'master' into discover-ssource-fields
Dec 6, 2020
c8c4f47
More unit tests
Dec 6, 2020
57319da
Update API changes
Dec 7, 2020
d07b676
Add unit test for discover field details footer
Dec 7, 2020
50f57ef
Remove unused file
Dec 7, 2020
6990015
Remove fields formatting from index pattern
Dec 8, 2020
0965f30
Remove unnecessary check
Dec 8, 2020
ab4edb4
Addressing design comments
Dec 8, 2020
be9b9f4
Merge branch 'master' into discover-ssource-fields
Dec 8, 2020
1a6c620
Fixing fields column display and renaming it to Document
Dec 9, 2020
95ea135
Adding more unit tests
Dec 9, 2020
fc12250
Adding a missing check for useNewFieldsAPI; minor fixes
Dec 10, 2020
eb309ee
Fixing typescript error
Dec 10, 2020
b7a79d6
Remove unnecessary console statement
Dec 10, 2020
2b63157
Add missing prop
Dec 10, 2020
0f65832
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 10, 2020
fad95e7
Fixing import order
Dec 11, 2020
d3d38ef
Merge branch 'master' into discover-ssource-fields
kibanamachine Dec 14, 2020
e374d6f
Adding functional test to test fields API
Dec 14, 2020
5efe636
[Functional test] Clean up in after
Dec 14, 2020
24ab2ae
Fixing context app
Dec 15, 2020
88e81f0
Addressing PR comments
Dec 16, 2020
711c757
Merge branch 'master' into discover-ssource-fields
Dec 16, 2020
aed98ee
Add support for unmapped fields
Dec 16, 2020
f8e2485
Merge master
Jan 21, 2021
a6aef4f
Add data migration
Jan 22, 2021
c41a1b3
Add toggle unmapped fields logic
Jan 23, 2021
1e3ef3c
Adding more unit tests
Jan 23, 2021
487da4b
Some cleanup
Jan 23, 2021
1dc16bd
More unit tests
Jan 23, 2021
929fba9
Fixing failing snapshot
Jan 24, 2021
275a916
Add tooltip next to unmapped switch
Jan 24, 2021
f3b025e
Add functional test for the feature
Jan 26, 2021
0f4aa58
Fixing a typo in a functional test
Jan 26, 2021
933891d
Merge branch 'master' into unmapped-fields
kibanamachine Jan 26, 2021
51badf7
Merge master
Jan 29, 2021
fb0f381
Refetch data when unmapped fields value changes
Jan 29, 2021
fda7725
Merge branch 'master' into unmapped-fields
kibanamachine Feb 1, 2021
c2de87d
Merge branch 'master' into unmapped-fields
Feb 2, 2021
6e12b58
Updating mapping
Feb 2, 2021
b51c0be
Support for fields API in search embeddable
Feb 2, 2021
abecb21
Addressing PR comments
Feb 2, 2021
d7b2fdf
Fix failing unit test
Feb 2, 2021
b16e3fd
Merge branch 'master' into unmapped-fields
kibanamachine Feb 2, 2021
0b8102b
Merge branch 'master' into unmapped-fields
kibanamachine Feb 3, 2021
64282c8
Updating the text
Feb 3, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ getAngularModule().directive('contextApp', function ContextApp() {

function ContextAppController($scope, Private) {
const { filterManager, indexPatterns, uiSettings, navigation } = getServices();
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
const queryParameterActions = getQueryParameterActions(filterManager, indexPatterns);
const queryActions = Private(QueryActionsProvider);
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
this.state = createInitialState(
parseInt(uiSettings.get(CONTEXT_STEP_SETTING), 10),
getFirstSortableField(this.indexPattern, uiSettings.get(CONTEXT_TIE_BREAKER_FIELDS_SETTING)),
useNewFieldsApi
);
this.state.useNewFieldsApi = useNewFieldsApi;
this.topNavMenu = navigation.ui.TopNavMenu;

this.actions = _.mapValues(
Expand Down
16 changes: 16 additions & 0 deletions src/plugins/discover/public/application/angular/discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,6 +748,21 @@ function discoverController($route, $scope, Promise) {
history.push('/');
};

const showUnmappedFieldsDefaultValue = $scope.useNewFieldsApi && !!$scope.opts.savedSearch.pre712;
let showUnmappedFields = showUnmappedFieldsDefaultValue;

const onChangeUnmappedFields = (value) => {
showUnmappedFields = value;
$scope.unmappedFieldsConfig.showUnmappedFields = value;
$scope.fetch();
};

$scope.unmappedFieldsConfig = {
showUnmappedFieldsDefaultValue,
showUnmappedFields,
onChangeUnmappedFields,
};

$scope.updateDataSource = () => {
const { indexPattern, searchSource, useNewFieldsApi } = $scope;
const { columns, sort } = $scope.state;
Expand All @@ -757,6 +772,7 @@ function discoverController($route, $scope, Promise) {
sort,
columns,
useNewFieldsApi,
showUnmappedFields,
});
return Promise.resolve();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
update-query="handleRefresh"
update-saved-query-id="updateSavedQueryId"
use-new-fields-api="useNewFieldsApi"
unmapped-fields-config="unmappedFieldsConfig"
>
</discover>
</discover-app>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* compliance with, at your election, the Elastic License or the Server Side
* Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import { IndexPattern } from '../../../../../kibana_services';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ export function createDiscoverDirective(reactDirective: any) {
['topNavMenu', { watchDepth: 'reference' }],
['updateQuery', { watchDepth: 'reference' }],
['updateSavedQueryId', { watchDepth: 'reference' }],
['unmappedFieldsConfig', { watchDepth: 'value' }],
]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export function Discover({
topNavMenu,
updateQuery,
updateSavedQueryId,
unmappedFieldsConfig,
}: DiscoverProps) {
const scrollableDesktop = useRef<HTMLDivElement>(null);
const collapseIcon = useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -139,6 +140,7 @@ export function Discover({
setIndexPattern={setIndexPattern}
isClosed={isSidebarClosed}
trackUiMetric={trackUiMetric}
unmappedFieldsConfig={unmappedFieldsConfig}
useNewFieldsApi={useNewFieldsApi}
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,22 @@ describe('DiscoverFieldSearch', () => {
popover = component.find(EuiPopover);
expect(popover.prop('isOpen')).toBe(false);
});

test('unmapped fields', () => {
const onChangeUnmappedFields = jest.fn();
const componentProps = {
...defaultProps,
showUnmappedFields: true,
useNewFieldsApi: false,
onChangeUnmappedFields,
};
const component = mountComponent(componentProps);
const btn = findTestSubject(component, 'toggleFieldFilterButton');
btn.simulate('click');
const unmappedFieldsSwitch = findTestSubject(component, 'unmappedFieldsSwitch');
act(() => {
unmappedFieldsSwitch.simulate('click');
});
expect(onChangeUnmappedFields).toHaveBeenCalledWith(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
EuiOutsideClickDetector,
EuiFilterButton,
EuiSpacer,
EuiIcon,
EuiToolTip,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

Expand All @@ -35,6 +37,7 @@ export interface State {
aggregatable: string;
type: string;
missing: boolean;
unmappedFields: boolean;
[index: string]: string | boolean;
}

Expand All @@ -53,13 +56,36 @@ export interface Props {
* types for the type filter
*/
types: string[];

/**
* use new fields api
*/
useNewFieldsApi?: boolean;

/**
* callback funtion to change the value of unmapped fields switch
* @param value new value to set
*/
onChangeUnmappedFields?: (value: boolean) => void;

/**
* should unmapped fields switch be rendered
*/
showUnmappedFields?: boolean;
}

/**
* Component is Discover's side bar to search of available fields
* Additionally there's a button displayed that allows the user to show/hide more filter fields
*/
export function DiscoverFieldSearch({ onChange, value, types }: Props) {
export function DiscoverFieldSearch({
onChange,
value,
types,
useNewFieldsApi,
showUnmappedFields,
onChangeUnmappedFields,
}: Props) {
const searchPlaceholder = i18n.translate('discover.fieldChooser.searchPlaceHolder', {
defaultMessage: 'Search field names',
});
Expand All @@ -85,6 +111,7 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
aggregatable: 'any',
type: 'any',
missing: true,
unmappedFields: !!showUnmappedFields,
});

if (typeof value !== 'string') {
Expand Down Expand Up @@ -154,6 +181,14 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
handleValueChange('missing', missingValue);
};

const handleUnmappedFieldsChange = (e: EuiSwitchEvent) => {
const unmappedFieldsValue = e.target.checked;
handleValueChange('unmappedFields', unmappedFieldsValue);
if (onChangeUnmappedFields) {
onChangeUnmappedFields(unmappedFieldsValue);
}
};

const buttonContent = (
<EuiFilterButton
aria-label={filterBtnAriaLabel}
Expand Down Expand Up @@ -226,6 +261,51 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
);
};

const footer = () => {
if (!showUnmappedFields && useNewFieldsApi) {
return null;
}
return (
<EuiPopoverFooter>
{showUnmappedFields ? (
<EuiFlexGroup>
<EuiFlexItem component="span">
<EuiSwitch
label={i18n.translate('discover.fieldChooser.filter.showUnmappedFields', {
defaultMessage: 'Show unmapped fields',
})}
checked={values.unmappedFields}
onChange={handleUnmappedFieldsChange}
data-test-subj="unmappedFieldsSwitch"
/>
</EuiFlexItem>
<EuiFlexItem component="span" grow={false}>
<EuiToolTip
position="right"
content={i18n.translate('discover.fieldChooser.filter.unmappedFieldsWarning', {
defaultMessage:
'Unmapped fields will soon be deprecated. We suggest keeping this switch off.',
Copy link
Member

Choose a reason for hiding this comment

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

dear @gchaps & @andreadelrio FYI just to have a look at layout and wording
Bildschirmfoto 2021-01-29 um 19 30 58

Copy link
Contributor

Choose a reason for hiding this comment

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

Typically, we use wording like this. (Also, I'm suggesting to remove the second line).

Unmapped fields are deprecated and will be removed in a future release.

If unmapped fields aren't yet deprecated, you can use this instead:

Unmapped fields will be deprecated and removed in a future release.

})}
>
<EuiIcon type="alert" />
</EuiToolTip>
</EuiFlexItem>
</EuiFlexGroup>
) : null}
{useNewFieldsApi ? null : (
<EuiSwitch
label={i18n.translate('discover.fieldChooser.filter.hideMissingFieldsLabel', {
defaultMessage: 'Hide missing fields',
})}
checked={values.missing}
onChange={handleMissingChange}
data-test-subj="missingSwitch"
/>
)}
</EuiPopoverFooter>
);
};

const selectionPanel = (
<div className="dscFieldSearch__formWrapper">
<EuiForm data-test-subj="filterSelectionPanel">
Expand Down Expand Up @@ -277,16 +357,7 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
})}
</EuiPopoverTitle>
{selectionPanel}
<EuiPopoverFooter>
<EuiSwitch
label={i18n.translate('discover.fieldChooser.filter.hideMissingFieldsLabel', {
defaultMessage: 'Hide missing fields',
})}
checked={values.missing}
onChange={handleMissingChange}
data-test-subj="missingSwitch"
/>
</EuiPopoverFooter>
{footer()}
</EuiPopover>
</EuiFilterGroup>
</EuiOutsideClickDetector>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,27 @@ export interface DiscoverSidebarProps {
* Shows index pattern and a button that displays the sidebar in a flyout
*/
useFlyout?: boolean;

/**
* an object containing properties for proper handling of unmapped fields in the UI
*/
unmappedFieldsConfig?: {
/**
* callback funtction to change the value of `showUnmappedFields` flag
Copy link
Member

Choose a reason for hiding this comment

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

typo: funtction -> function

* @param value new value to set
*/
onChangeUnmappedFields: (value: boolean) => void;
/**
* determines whether to display unmapped fields
* configurable through the switch in the UI
*/
showUnmappedFields: boolean;
/**
* determines if we should display an option to toggle showUnmappedFields value in the first place
* this value is not configurable through the UI
*/
showUnmappedFieldsDefaultValue: boolean;
};
}

export function DiscoverSidebar({
Expand All @@ -123,6 +144,7 @@ export function DiscoverSidebar({
trackUiMetric,
useNewFieldsApi = false,
useFlyout = false,
unmappedFieldsConfig,
}: DiscoverSidebarProps) {
const [fields, setFields] = useState<IndexPatternField[] | null>(null);

Expand All @@ -145,14 +167,30 @@ export function DiscoverSidebar({
);

const popularLimit = services.uiSettings.get(FIELDS_LIMIT_SETTING);

const {
selected: selectedFields,
popular: popularFields,
unpopular: unpopularFields,
} = useMemo(
() => groupFields(fields, columns, popularLimit, fieldCounts, fieldFilter, useNewFieldsApi),
[fields, columns, popularLimit, fieldCounts, fieldFilter, useNewFieldsApi]
() =>
groupFields(
fields,
columns,
popularLimit,
fieldCounts,
fieldFilter,
useNewFieldsApi,
!!unmappedFieldsConfig?.showUnmappedFields
),
[
fields,
columns,
popularLimit,
fieldCounts,
fieldFilter,
useNewFieldsApi,
unmappedFieldsConfig?.showUnmappedFields,
]
);

const fieldTypes = useMemo(() => {
Expand Down Expand Up @@ -239,6 +277,9 @@ export function DiscoverSidebar({
onChange={onChangeFieldSearch}
value={fieldFilter.name}
types={fieldTypes}
useNewFieldsApi={useNewFieldsApi}
onChangeUnmappedFields={unmappedFieldsConfig?.onChangeUnmappedFields}
showUnmappedFields={unmappedFieldsConfig?.showUnmappedFieldsDefaultValue}
/>
</form>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import realHits from 'fixtures/real_hits.js';
import stubbedLogstashFields from 'fixtures/logstash_fields';
import { mountWithIntl } from '@kbn/test/jest';
import React from 'react';
import { DiscoverSidebarProps } from './discover_sidebar';
import { DiscoverSidebar, DiscoverSidebarProps } from './discover_sidebar';
import { coreMock } from '../../../../../../core/public/mocks';
import { IndexPatternAttributes } from '../../../../../data/common';
import { getStubIndexPattern } from '../../../../../data/public/test_utils';
Expand Down Expand Up @@ -131,4 +131,16 @@ describe('discover responsive sidebar', function () {
findTestSubject(comp, 'plus-extension-gif').simulate('click');
expect(props.onAddFilter).toHaveBeenCalled();
});
it('renders sidebar with unmapped fields config', function () {
const unmappedFieldsConfig = {
onChangeUnmappedFields: jest.fn(),
showUnmappedFields: false,
showUnmappedFieldsDefaultValue: false,
};
const componentProps = { ...props, unmappedFieldsConfig };
const component = mountWithIntl(<DiscoverSidebarResponsive {...componentProps} />);
const discoverSidebar = component.find(DiscoverSidebar);
expect(discoverSidebar).toHaveLength(1);
expect(discoverSidebar.props().unmappedFieldsConfig).toEqual(unmappedFieldsConfig);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,27 @@ export interface DiscoverSidebarResponsiveProps {
* Read from the Fields API
*/
useNewFieldsApi?: boolean;

/**
* an object containing properties for proper handling of unmapped fields in the UI
*/
unmappedFieldsConfig?: {
/**
* callback function to change the value of `showUnmappedFields` flag
* @param value new value to set
*/
onChangeUnmappedFields: (value: boolean) => void;
/**
* determines whether to display unmapped fields
* configurable through the switch in the UI
*/
showUnmappedFields: boolean;
/**
* determines if we should display an option to toggle showUnmappedFields value in the first place
* this value is not configurable through the UI
*/
showUnmappedFieldsDefaultValue: boolean;
};
}

/**
Expand Down
Loading