Skip to content

Commit

Permalink
Move ui/value_suggestions ⇒ NP data plugin (#45762)
Browse files Browse the repository at this point in the history
* Bind search bar

* create prewired data components

* Pass NP data plugin to shim plugin, to access autocomplete
Pass storage and autocomplete to createSearchBar method
Add appName and autocomplete to IDataPluginServices
QueryBarInput to consume autocomplete and appName from context
QueryBarTopRow to consume appName from context
Remove appName from SearchBar
Added AutocompletePublicPluginSetup and AutocompletePublicPluginStart types

* Use KibanaContextProvider in vis editor and graph

* Use KibanaContextProvider in maps

* Use prewirted SearchBar in TopNavMenu

* Use KibanaContextProbider in Lens

* Fix appName usage in query bar input

* fixed query bar top row appName

* update tests

* fixed bind search bar bug

* mock SearchBar

* Removed unnecessary mocks

* Delete unused mock

* Fixed exporting of data plugin types

* Updated maps snapshot

* Fixed some TS issues

* Fixed jest tests

* Context adjustments in TSVB

* componentWillMount

* Code review fixes

* Pass dataTestSubj to query bar input

* Graph data

* - Pass NP data plugin to KibanaReactContext
- Move value_suggestions to NP

* - Pass NP data plugin to KibanaReactContext
- Move value_suggestions to NP

* ts fixes

* Added karma getSuggestions fake

* Refactored kuery autocomplete tests to jest

* Filter bar context for directives

* updated snapshot

* fix diffs

* fixed lens test
  • Loading branch information
Liza Katz authored Oct 6, 2019
1 parent 2389fe8 commit 0c001e4
Show file tree
Hide file tree
Showing 35 changed files with 318 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ import {
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import classNames from 'classnames';
import React, { useState } from 'react';
import { UiSettingsClientContract } from 'src/core/public';
import { CoreStart } from 'src/core/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { IndexPattern } from '../../index_patterns';
import { FilterEditor } from './filter_editor';
import { FilterItem } from './filter_item';
import { FilterOptions } from './filter_options';
import { useKibana } from '../../../../../../plugins/kibana_react/public';
import { useKibana, KibanaContextProvider } from '../../../../../../plugins/kibana_react/public';

interface Props {
filters: Filter[];
Expand All @@ -45,18 +46,45 @@ interface Props {
indexPatterns: IndexPattern[];
intl: InjectedIntl;

// Only for directives!
uiSettings?: UiSettingsClientContract;
// TODO: Only for filter-bar directive!
uiSettings?: CoreStart['uiSettings'];
docLinks?: CoreStart['docLinks'];
pluginDataStart?: DataPublicPluginStart;
}

function FilterBarUI(props: Props) {
const [isAddFilterPopoverOpen, setIsAddFilterPopoverOpen] = useState(false);
const kibana = useKibana();
let { uiSettings } = kibana.services;

if (!uiSettings) {
// Only for directives!
uiSettings = props.uiSettings;
const uiSettings = kibana.services.uiSettings || props.uiSettings;
if (!uiSettings) return null;

function hasContext() {
return Boolean(kibana.services.uiSettings);
}

function wrapInContextIfMissing(content: JSX.Element) {
// TODO: Relevant only as long as directives are used!
if (!hasContext()) {
if (props.docLinks && props.uiSettings && props.pluginDataStart) {
return (
<KibanaContextProvider
services={{
uiSettings: props.uiSettings,
docLinks: props.docLinks,
data: props.pluginDataStart,
}}
>
{content}
</KibanaContextProvider>
);
} else {
throw new Error(
'Rending filter bar requires providing sufficient context: uiSettings, docLinks and NP data plugin'
);
}
}
return content;
}

function onFiltersUpdated(filters: Filter[]) {
Expand Down Expand Up @@ -100,7 +128,7 @@ function FilterBarUI(props: Props) {
</EuiButtonEmpty>
);

return (
return wrapInContextIfMissing(
<EuiFlexItem grow={false}>
<EuiPopover
id="addFilterPopover"
Expand All @@ -120,7 +148,6 @@ function FilterBarUI(props: Props) {
onSubmit={onAdd}
onCancel={() => setIsAddFilterPopoverOpen(false)}
key={JSON.stringify(newFilter)}
uiSettings={uiSettings!}
/>
</div>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
import { get } from 'lodash';
import React, { Component } from 'react';
import { UiSettingsClientContract } from 'src/core/public';
import { Field, IndexPattern } from '../../../index_patterns';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import {
Expand All @@ -62,7 +61,6 @@ interface Props {
onSubmit: (filter: Filter) => void;
onCancel: () => void;
intl: InjectedIntl;
uiSettings: UiSettingsClientContract;
}

interface State {
Expand Down Expand Up @@ -343,7 +341,6 @@ class FilterEditorUI extends Component<Props, State> {
value={this.state.params}
onChange={this.onParamsChange}
data-test-subj="phraseValueInput"
uiSettings={this.props.uiSettings}
/>
);
case 'phrases':
Expand All @@ -353,7 +350,6 @@ class FilterEditorUI extends Component<Props, State> {
field={this.state.selectedField}
values={this.state.params}
onChange={this.onParamsChange}
uiSettings={this.props.uiSettings}
/>
);
case 'range':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@
*/

import { Component } from 'react';
import { getSuggestions } from 'ui/value_suggestions';
import { UiSettingsClientContract } from 'src/core/public';
import { Field, IndexPattern } from '../../../index_patterns';
import {
withKibana,
KibanaReactContextValue,
} from '../../../../../../../plugins/kibana_react/public';
import { IDataPluginServices } from '../../../types';

export interface PhraseSuggestorProps {
kibana: KibanaReactContextValue<IDataPluginServices>;
indexPattern: IndexPattern;
field?: Field;
uiSettings: UiSettingsClientContract;
}

export interface PhraseSuggestorState {
Expand All @@ -38,10 +41,11 @@ export interface PhraseSuggestorState {
* aggregatable), we pull out the common logic for requesting suggestions into this component
* which both of them extend.
*/
export class PhraseSuggestor<T extends PhraseSuggestorProps> extends Component<
export class PhraseSuggestorUI<T extends PhraseSuggestorProps> extends Component<
T,
PhraseSuggestorState
> {
private services = this.props.kibana.services;
public state: PhraseSuggestorState = {
suggestions: [],
isLoading: false,
Expand All @@ -52,7 +56,7 @@ export class PhraseSuggestor<T extends PhraseSuggestorProps> extends Component<
}

protected isSuggestingValues() {
const shouldSuggestValues = this.props.uiSettings.get('filterEditor:suggestValues');
const shouldSuggestValues = this.services.uiSettings.get('filterEditor:suggestValues');
const { field } = this.props;
return shouldSuggestValues && field && field.aggregatable && field.type === 'string';
}
Expand All @@ -67,7 +71,9 @@ export class PhraseSuggestor<T extends PhraseSuggestorProps> extends Component<
return;
}
this.setState({ isLoading: true });
const suggestions = await getSuggestions(indexPattern.title, field, value);
const suggestions = await this.services.data.getSuggestions(indexPattern.title, field, value);
this.setState({ suggestions, isLoading: false });
}
}

export const PhraseSuggestor = withKibana(PhraseSuggestorUI);
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
import { uniq } from 'lodash';
import React from 'react';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor';
import { PhraseSuggestorUI, PhraseSuggestorProps } from './phrase_suggestor';
import { ValueInputType } from './value_input_type';
import { withKibana } from '../../../../../../../plugins/kibana_react/public';

interface Props extends PhraseSuggestorProps {
value?: string;
onChange: (value: string | number | boolean) => void;
intl: InjectedIntl;
}

class PhraseValueInputUI extends PhraseSuggestor<Props> {
class PhraseValueInputUI extends PhraseSuggestorUI<Props> {
public render() {
return (
<EuiFormRow
Expand Down Expand Up @@ -87,4 +88,4 @@ function StringComboBox(props: GenericComboBoxProps<string>) {
return GenericComboBox(props);
}

export const PhraseValueInput = injectI18n(PhraseValueInputUI);
export const PhraseValueInput = injectI18n(withKibana(PhraseValueInputUI));
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ import { InjectedIntl, injectI18n } from '@kbn/i18n/react';
import { uniq } from 'lodash';
import React from 'react';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import { PhraseSuggestor, PhraseSuggestorProps } from './phrase_suggestor';
import { PhraseSuggestorUI, PhraseSuggestorProps } from './phrase_suggestor';
import { withKibana } from '../../../../../../../plugins/kibana_react/public';

interface Props extends PhraseSuggestorProps {
values?: string[];
onChange: (values: string[]) => void;
intl: InjectedIntl;
}

class PhrasesValuesInputUI extends PhraseSuggestor<Props> {
class PhrasesValuesInputUI extends PhraseSuggestorUI<Props> {
public render() {
const { suggestions } = this.state;
const { values, intl, onChange } = this.props;
Expand Down Expand Up @@ -64,4 +65,4 @@ function StringComboBox(props: GenericComboBoxProps<string>) {
return GenericComboBox(props);
}

export const PhrasesValuesInput = injectI18n(PhrasesValuesInputUI);
export const PhrasesValuesInput = injectI18n(withKibana(PhrasesValuesInputUI));
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ class FilterItemUI extends Component<Props, State> {
indexPatterns={this.props.indexPatterns}
onSubmit={this.onSubmit}
onCancel={this.closePopover}
uiSettings={this.props.uiSettings}
/>
</div>
),
Expand Down
2 changes: 1 addition & 1 deletion src/legacy/core_plugins/data/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ export class DataPlugin
public start(core: CoreStart, { __LEGACY, data }: DataPluginStartDependencies) {
const SearchBar = createSearchBar({
core,
data,
store: __LEGACY.storage,
timefilter: this.setupApi.timefilter,
filterManager: this.setupApi.filter.filterManager,
autocomplete: data.autocomplete,
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ export class QueryBarInputUI extends Component<Props, State> {
const queryString = this.getQueryString();

const recentSearchSuggestions = this.getRecentSearchSuggestions(queryString);
const autocompleteProvider = this.services.data.autocomplete.getProvider(language);

const autocompleteProvider = this.services.autocomplete.getProvider(language);
if (
!autocompleteProvider ||
!Array.isArray(this.state.indexPatterns) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import React from 'react';
import { Filter } from '@kbn/es-query';
import { CoreStart } from 'src/core/public';
import { AutocompletePublicPluginStart } from 'src/plugins/data/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { Storage } from '../../../types';
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
import { TimefilterSetup } from '../../../timefilter';
Expand All @@ -29,10 +29,10 @@ import { SearchBarOwnProps } from '.';

interface StatefulSearchBarDeps {
core: CoreStart;
data: DataPublicPluginStart;
store: Storage;
timefilter: TimefilterSetup;
filterManager: FilterManager;
autocomplete: AutocompletePublicPluginStart;
}

export type StatetfulSearchBarProps = SearchBarOwnProps & {
Expand All @@ -59,7 +59,7 @@ export function createSearchBar({
store,
timefilter,
filterManager,
autocomplete,
data,
}: StatefulSearchBarDeps) {
// App name should come from the core application service.
// Until it's available, we'll ask the user to provide it for the pre-wired component.
Expand All @@ -71,7 +71,7 @@ export function createSearchBar({
<KibanaContextProvider
services={{
appName: props.appName,
autocomplete,
data,
store,
...core,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export interface SearchBarOwnProps {
showFilterBar?: boolean;
showDatePicker?: boolean;
showAutoRefreshOnly?: boolean;
onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void;
// Query bar - should be in SearchBarInjectedDeps
query?: Query;
// Show when user has privileges to save
Expand Down
13 changes: 8 additions & 5 deletions src/legacy/core_plugins/data/public/shim/legacy_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { Filter } from '@kbn/es-query';

// @ts-ignore
import { uiModules } from 'ui/modules';
import { npSetup, npStart } from 'ui/new_platform';
import { npStart } from 'ui/new_platform';
import { FilterBar, ApplyFiltersPopover } from '../filter';
import template from './apply_filter_directive.html';

Expand All @@ -49,14 +49,16 @@ export const initLegacyModule = once((): void => {
}

child.setAttribute('ui-settings', 'uiSettings');
child.setAttribute('http', 'http');
child.setAttribute('doc-links', 'docLinks');
child.setAttribute('plugin-data-start', 'pluginDataStart');

// Append helper directive
elem.append(child);

const linkFn = ($scope: any) => {
$scope.uiSettings = npSetup.core.uiSettings;
$scope.http = npSetup.core.http;
$scope.uiSettings = npStart.core.uiSettings;
$scope.docLinks = npStart.core.docLinks;
$scope.pluginDataStart = npStart.plugins.data;
};

return linkFn;
Expand All @@ -66,11 +68,12 @@ export const initLegacyModule = once((): void => {
.directive('filterBarHelper', (reactDirective: any) => {
return reactDirective(wrapInI18nContext(FilterBar), [
['uiSettings', { watchDepth: 'reference' }],
['http', { watchDepth: 'reference' }],
['docLinks', { watchDepth: 'reference' }],
['onFiltersUpdated', { watchDepth: 'reference' }],
['indexPatterns', { watchDepth: 'collection' }],
['filters', { watchDepth: 'collection' }],
['className', { watchDepth: 'reference' }],
['pluginDataStart', { watchDepth: 'reference' }],
]);
})
.directive('applyFiltersPopoverComponent', (reactDirective: any) =>
Expand Down
4 changes: 2 additions & 2 deletions src/legacy/core_plugins/data/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import { UiSettingsClientContract, CoreStart } from 'src/core/public';
import { AutocompletePublicPluginStart } from 'src/plugins/data/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';

export interface Storage {
get: (key: string) => any;
Expand All @@ -34,5 +34,5 @@ export interface IDataPluginServices extends Partial<CoreStart> {
notifications: CoreStart['notifications'];
http: CoreStart['http'];
store: Storage;
autocomplete: AutocompletePublicPluginStart;
data: DataPublicPluginStart;
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export class VisEditor extends Component {
services={{
appName: APP_NAME,
store: localStorage,
autocomplete: npStart.plugins.data.autocomplete,
data: npStart.plugins.data,
...npStart.core,
}}
>
Expand Down
4 changes: 3 additions & 1 deletion src/legacy/ui/public/new_platform/new_platform.karma_mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ export const npStart = {
registerRenderer: sinon.fake(),
registerType: sinon.fake(),
},
data: {},
data: {
getSuggestions: sinon.fake(),
},
inspector: {
isAvailable: () => false,
open: () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function FilterRow({
services={{
appName: 'filtersAgg',
store: localStorage,
autocomplete: npStart.plugins.data.autocomplete,
data: npStart.plugins.data,
...npStart.core,
}}
>
Expand Down
1 change: 1 addition & 0 deletions src/plugins/data/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const createSetupContract = (): Setup => {
const createStartContract = (): Start => {
const startContract: Start = {
autocomplete: autocompleteMock as Start['autocomplete'],
getSuggestions: jest.fn(),
};
return startContract;
};
Expand Down
Loading

0 comments on commit 0c001e4

Please sign in to comment.