[data.ui] Lazy load UI components in data plugin. (#78889)

This commit is contained in:
Luke Elmers 2020-10-06 07:23:58 -06:00 committed by GitHub
parent 09101b2f15
commit 8ec5ce6861
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 398 additions and 426 deletions

View file

@ -8,7 +8,7 @@
```typescript
esFilters: {
FilterLabel: typeof FilterLabel;
FilterLabel: (props: import("./ui/filter_bar/filter_editor/lib/filter_label").FilterLabelProps) => JSX.Element;
FILTERS: typeof FILTERS;
FilterStateStore: typeof FilterStateStore;
buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter;

View file

@ -1,13 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [FilterBar](./kibana-plugin-plugins-data-public.filterbar.md)
## FilterBar variable
<b>Signature:</b>
```typescript
FilterBar: React.ComponentClass<Pick<Props, "className" | "filters" | "indexPatterns" | "onFiltersUpdated">, any> & {
WrappedComponent: React.ComponentType<Props & ReactIntl.InjectedIntlProps>;
}
```

View file

@ -1,20 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [(constructor)](./kibana-plugin-plugins-data-public.indexpatternselect._constructor_.md)
## IndexPatternSelect.(constructor)
Constructs a new instance of the `IndexPatternSelect` class
<b>Signature:</b>
```typescript
constructor(props: IndexPatternSelectProps);
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| props | <code>IndexPatternSelectProps</code> | |

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [componentDidMount](./kibana-plugin-plugins-data-public.indexpatternselect.componentdidmount.md)
## IndexPatternSelect.componentDidMount() method
<b>Signature:</b>
```typescript
componentDidMount(): void;
```
<b>Returns:</b>
`void`

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [componentWillUnmount](./kibana-plugin-plugins-data-public.indexpatternselect.componentwillunmount.md)
## IndexPatternSelect.componentWillUnmount() method
<b>Signature:</b>
```typescript
componentWillUnmount(): void;
```
<b>Returns:</b>
`void`

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [debouncedFetch](./kibana-plugin-plugins-data-public.indexpatternselect.debouncedfetch.md)
## IndexPatternSelect.debouncedFetch property
<b>Signature:</b>
```typescript
debouncedFetch: ((searchValue: string) => Promise<void>) & _.Cancelable;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [fetchOptions](./kibana-plugin-plugins-data-public.indexpatternselect.fetchoptions.md)
## IndexPatternSelect.fetchOptions property
<b>Signature:</b>
```typescript
fetchOptions: (searchValue?: string) => void;
```

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [fetchSelectedIndexPattern](./kibana-plugin-plugins-data-public.indexpatternselect.fetchselectedindexpattern.md)
## IndexPatternSelect.fetchSelectedIndexPattern property
<b>Signature:</b>
```typescript
fetchSelectedIndexPattern: (indexPatternId: string) => Promise<void>;
```

View file

@ -1,37 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md)
## IndexPatternSelect class
<b>Signature:</b>
```typescript
export declare class IndexPatternSelect extends Component<IndexPatternSelectProps>
```
## Constructors
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(props)](./kibana-plugin-plugins-data-public.indexpatternselect._constructor_.md) | | Constructs a new instance of the <code>IndexPatternSelect</code> class |
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [debouncedFetch](./kibana-plugin-plugins-data-public.indexpatternselect.debouncedfetch.md) | | <code>((searchValue: string) =&gt; Promise&lt;void&gt;) &amp; _.Cancelable</code> | |
| [fetchOptions](./kibana-plugin-plugins-data-public.indexpatternselect.fetchoptions.md) | | <code>(searchValue?: string) =&gt; void</code> | |
| [fetchSelectedIndexPattern](./kibana-plugin-plugins-data-public.indexpatternselect.fetchselectedindexpattern.md) | | <code>(indexPatternId: string) =&gt; Promise&lt;void&gt;</code> | |
| [onChange](./kibana-plugin-plugins-data-public.indexpatternselect.onchange.md) | | <code>(selectedOptions: any) =&gt; void</code> | |
| [state](./kibana-plugin-plugins-data-public.indexpatternselect.state.md) | | <code>IndexPatternSelectState</code> | |
## Methods
| Method | Modifiers | Description |
| --- | --- | --- |
| [componentDidMount()](./kibana-plugin-plugins-data-public.indexpatternselect.componentdidmount.md) | | |
| [componentWillUnmount()](./kibana-plugin-plugins-data-public.indexpatternselect.componentwillunmount.md) | | |
| [render()](./kibana-plugin-plugins-data-public.indexpatternselect.render.md) | | |
| [UNSAFE\_componentWillReceiveProps(nextProps)](./kibana-plugin-plugins-data-public.indexpatternselect.unsafe_componentwillreceiveprops.md) | | |

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [onChange](./kibana-plugin-plugins-data-public.indexpatternselect.onchange.md)
## IndexPatternSelect.onChange property
<b>Signature:</b>
```typescript
onChange: (selectedOptions: any) => void;
```

View file

@ -1,15 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [render](./kibana-plugin-plugins-data-public.indexpatternselect.render.md)
## IndexPatternSelect.render() method
<b>Signature:</b>
```typescript
render(): JSX.Element;
```
<b>Returns:</b>
`JSX.Element`

View file

@ -1,11 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [state](./kibana-plugin-plugins-data-public.indexpatternselect.state.md)
## IndexPatternSelect.state property
<b>Signature:</b>
```typescript
state: IndexPatternSelectState;
```

View file

@ -1,22 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) &gt; [UNSAFE\_componentWillReceiveProps](./kibana-plugin-plugins-data-public.indexpatternselect.unsafe_componentwillreceiveprops.md)
## IndexPatternSelect.UNSAFE\_componentWillReceiveProps() method
<b>Signature:</b>
```typescript
UNSAFE_componentWillReceiveProps(nextProps: IndexPatternSelectProps): void;
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| nextProps | <code>IndexPatternSelectProps</code> | |
<b>Returns:</b>
`void`

View file

@ -0,0 +1,16 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [IndexPatternSelectProps](./kibana-plugin-plugins-data-public.indexpatternselectprops.md)
## IndexPatternSelectProps type
<b>Signature:</b>
```typescript
export declare type IndexPatternSelectProps = Required<Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions'>, 'onChange' | 'placeholder'> & {
indexPatternId: string;
fieldTypes?: string[];
onNoIndexPatterns?: () => void;
savedObjectsClient: SavedObjectsClientContract;
};
```

View file

@ -16,7 +16,6 @@
| [FilterManager](./kibana-plugin-plugins-data-public.filtermanager.md) | |
| [IndexPattern](./kibana-plugin-plugins-data-public.indexpattern.md) | |
| [IndexPatternField](./kibana-plugin-plugins-data-public.indexpatternfield.md) | |
| [IndexPatternSelect](./kibana-plugin-plugins-data-public.indexpatternselect.md) | |
| [IndexPatternsService](./kibana-plugin-plugins-data-public.indexpatternsservice.md) | |
| [OptionedParamType](./kibana-plugin-plugins-data-public.optionedparamtype.md) | |
| [PainlessError](./kibana-plugin-plugins-data-public.painlesserror.md) | |
@ -113,7 +112,6 @@
| [extractSearchSourceReferences](./kibana-plugin-plugins-data-public.extractsearchsourcereferences.md) | |
| [fieldFormats](./kibana-plugin-plugins-data-public.fieldformats.md) | |
| [fieldList](./kibana-plugin-plugins-data-public.fieldlist.md) | |
| [FilterBar](./kibana-plugin-plugins-data-public.filterbar.md) | |
| [getKbnTypeNames](./kibana-plugin-plugins-data-public.getkbntypenames.md) | Get the esTypes known by all kbnFieldTypes {<!-- -->Array<string>} |
| [indexPatterns](./kibana-plugin-plugins-data-public.indexpatterns.md) | |
| [injectSearchSourceReferences](./kibana-plugin-plugins-data-public.injectsearchsourcereferences.md) | |
@ -160,6 +158,7 @@
| [IMetricAggType](./kibana-plugin-plugins-data-public.imetricaggtype.md) | |
| [IndexPatternAggRestrictions](./kibana-plugin-plugins-data-public.indexpatternaggrestrictions.md) | |
| [IndexPatternsContract](./kibana-plugin-plugins-data-public.indexpatternscontract.md) | |
| [IndexPatternSelectProps](./kibana-plugin-plugins-data-public.indexpatternselectprops.md) | |
| [InputTimeRange](./kibana-plugin-plugins-data-public.inputtimerange.md) | |
| [ISearch](./kibana-plugin-plugins-data-public.isearch.md) | |
| [ISearchGeneric](./kibana-plugin-plugins-data-public.isearchgeneric.md) | |

View file

@ -7,5 +7,5 @@
<b>Signature:</b>
```typescript
QueryStringInput: React.FC<QueryStringInputProps>
QueryStringInput: (props: QueryStringInputProps) => JSX.Element
```

View file

@ -53,7 +53,6 @@ import {
import {
DataPublicPluginStart,
IndexPatternSelect,
IndexPattern,
IndexPatternField,
isCompleteResponse,
@ -92,6 +91,7 @@ export const SearchExamplesApp = ({
navigation,
data,
}: SearchExamplesAppDeps) => {
const { IndexPatternSelect } = data.ui;
const [getCool, setGetCool] = useState<boolean>(false);
const [timeTook, setTimeTook] = useState<number | undefined>();
const [indexPattern, setIndexPattern] = useState<IndexPattern | null>();

View file

@ -50,7 +50,7 @@ import {
COMPARE_ALL_OPTIONS,
} from '../common';
import { FilterLabel } from './ui/filter_bar';
import { FilterLabel } from './ui';
import {
generateFilters,
@ -421,10 +421,9 @@ export {
SearchBar,
SearchBarProps,
StatefulSearchBarProps,
FilterBar,
IndexPatternSelectProps,
QueryStringInput,
QueryStringInputProps,
IndexPatternSelect,
} from './ui';
/**

View file

@ -5,7 +5,6 @@
```ts
import { $Values } from '@kbn/utility-types';
import _ from 'lodash';
import { Action } from 'history';
import { ApiResponse } from '@elastic/elasticsearch';
import { ApiResponse as ApiResponse_2 } from '@elastic/elasticsearch/lib/Transport';
@ -13,7 +12,6 @@ import { ApplicationStart } from 'kibana/public';
import { Assign } from '@kbn/utility-types';
import { BehaviorSubject } from 'rxjs';
import Boom from 'boom';
import { Component } from 'react';
import { CoreSetup } from 'src/core/public';
import { CoreSetup as CoreSetup_2 } from 'kibana/public';
import { CoreStart } from 'kibana/public';
@ -65,7 +63,7 @@ import { RequestStatistics } from 'src/plugins/inspector/common';
import { Required } from '@kbn/utility-types';
import * as Rx from 'rxjs';
import { SavedObject } from 'src/core/server';
import { SavedObject as SavedObject_3 } from 'src/core/public';
import { SavedObject as SavedObject_2 } from 'src/core/public';
import { SavedObjectReference as SavedObjectReference_2 } from 'src/core/types';
import { SavedObjectsClientContract } from 'src/core/public';
import { Search } from '@elastic/elasticsearch/api/requestParams';
@ -447,8 +445,6 @@ export interface DataPublicPluginStartActions {
//
// @public
export interface DataPublicPluginStartUi {
// Warning: (ae-forgotten-export) The symbol "IndexPatternSelectProps" needs to be exported by the entry point index.d.ts
//
// (undocumented)
IndexPatternSelect: React.ComponentType<IndexPatternSelectProps>;
// (undocumented)
@ -547,7 +543,7 @@ export type EsdslExpressionFunctionDefinition = ExpressionFunctionDefinition<typ
//
// @public (undocumented)
export const esFilters: {
FilterLabel: typeof FilterLabel;
FilterLabel: (props: import("./ui/filter_bar/filter_editor/lib/filter_label").FilterLabelProps) => JSX.Element;
FILTERS: typeof FILTERS;
FilterStateStore: typeof FilterStateStore;
buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter;
@ -805,14 +801,6 @@ export type Filter = {
query?: any;
};
// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts
// Warning: (ae-missing-release-tag) "FilterBar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const FilterBar: React.ComponentClass<Pick<Props_2, "className" | "filters" | "indexPatterns" | "onFiltersUpdated">, any> & {
WrappedComponent: React.ComponentType<Props_2 & ReactIntl.InjectedIntlProps>;
};
// Warning: (ae-missing-release-tag) "FilterManager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
@ -1299,32 +1287,15 @@ export const indexPatterns: {
// @public (undocumented)
export type IndexPatternsContract = PublicMethodsOf<IndexPatternsService>;
// Warning: (ae-missing-release-tag) "IndexPatternSelect" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-missing-release-tag) "IndexPatternSelectProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export class IndexPatternSelect extends Component<IndexPatternSelectProps> {
constructor(props: IndexPatternSelectProps);
// (undocumented)
componentDidMount(): void;
// (undocumented)
componentWillUnmount(): void;
// (undocumented)
debouncedFetch: ((searchValue: string) => Promise<void>) & _.Cancelable;
// (undocumented)
fetchOptions: (searchValue?: string) => void;
// (undocumented)
fetchSelectedIndexPattern: (indexPatternId: string) => Promise<void>;
// (undocumented)
onChange: (selectedOptions: any) => void;
// (undocumented)
render(): JSX.Element;
// Warning: (ae-forgotten-export) The symbol "IndexPatternSelectState" needs to be exported by the entry point index.d.ts
//
// (undocumented)
state: IndexPatternSelectState;
// (undocumented)
UNSAFE_componentWillReceiveProps(nextProps: IndexPatternSelectProps): void;
}
export type IndexPatternSelectProps = Required<Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions'>, 'onChange' | 'placeholder'> & {
indexPatternId: string;
fieldTypes?: string[];
onNoIndexPatterns?: () => void;
savedObjectsClient: SavedObjectsClientContract;
};
// Warning: (ae-missing-release-tag) "IndexPatternSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@ -1740,7 +1711,7 @@ export interface QueryStateChange extends QueryStateChangePartial {
// Warning: (ae-missing-release-tag) "QueryStringInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const QueryStringInput: React.FC<QueryStringInputProps>;
export const QueryStringInput: (props: QueryStringInputProps) => JSX.Element;
// Warning: (ae-missing-release-tag) "QueryStringInputProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
@ -2315,7 +2286,6 @@ export const UI_SETTINGS: {
// src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts:70:5 - (ae-forgotten-export) The symbol "FormatFieldFn" needs to be exported by the entry point index.d.ts
// src/plugins/data/common/search/aggs/types.ts:98:51 - (ae-forgotten-export) The symbol "AggTypesRegistryStart" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/field_formats/field_formats_service.ts:67:3 - (ae-forgotten-export) The symbol "FormatFactory" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FilterLabel" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "FILTERS" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "getDisplayValueFromFilter" needs to be exported by the entry point index.d.ts
// src/plugins/data/public/index.ts:66:23 - (ae-forgotten-export) The symbol "generateFilters" needs to be exported by the entry point index.d.ts

View file

@ -21,17 +21,16 @@ import { Subscription } from 'rxjs';
import { IUiSettingsClient } from 'src/core/public';
import { ExpressionsServiceSetup } from 'src/plugins/expressions/common';
import { FieldFormatsStart } from '../../field_formats';
import { getForceNow } from '../../query/timefilter/lib/get_force_now';
import { calculateBounds, TimeRange } from '../../../common';
import {
aggsRequiredUiSettings,
AggsCommonStartDependencies,
AggsCommonService,
AggConfigs,
AggTypesDependencies,
calculateBounds,
TimeRange,
} from '../../../common';
import { FieldFormatsStart } from '../../field_formats';
import { getForceNow } from '../../query/timefilter/lib/get_force_now';
} from '../../../common/search/aggs';
import { AggsSetup, AggsStart } from './types';
/**

View file

@ -21,7 +21,7 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
import { SearchResponse } from 'elasticsearch';
import { ShardFailureOpenModalButton } from '../../ui';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
import { toMountPoint } from '../../../../kibana_react/public';
import { getNotifications } from '../../services';
import { SearchRequest } from '..';

View file

@ -27,9 +27,8 @@ import { FieldFormatsSetup, FieldFormatsStart } from './field_formats';
import { createFiltersFromRangeSelectAction, createFiltersFromValueClickAction } from './actions';
import { ISearchSetup, ISearchStart, SearchEnhancements } from './search';
import { QuerySetup, QueryStart } from './query';
import { IndexPatternSelectProps } from './ui/index_pattern_select';
import { IndexPatternsContract } from './index_patterns';
import { StatefulSearchBarProps } from './ui/search_bar/create_search_bar';
import { IndexPatternSelectProps, StatefulSearchBarProps } from './ui';
import { UsageCollectionSetup } from '../../usage_collection/public';
export interface DataPublicPluginEnhancements {

View file

@ -46,7 +46,9 @@ interface State {
isFilterSelected: boolean[];
}
export class ApplyFiltersPopoverContent extends Component<Props, State> {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default class ApplyFiltersPopoverContent extends Component<Props, State> {
public static defaultProps = {
filters: [],
};

View file

@ -18,12 +18,20 @@
*/
import React from 'react';
import { ApplyFiltersPopoverContent } from './apply_filter_popover_content';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import { IIndexPattern, Filter } from '../..';
type CancelFnType = () => void;
type SubmitFnType = (filters: Filter[]) => void;
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazyApplyFiltersPopoverContent = React.lazy(() => import('./apply_filter_popover_content'));
export const applyFiltersPopover = (
filters: Filter[],
indexPatterns: IIndexPattern[],
@ -31,11 +39,13 @@ export const applyFiltersPopover = (
onSubmit: SubmitFnType
) => {
return (
<ApplyFiltersPopoverContent
indexPatterns={indexPatterns}
filters={filters}
onCancel={onCancel}
onSubmit={onSubmit}
/>
<React.Suspense fallback={<Fallback />}>
<LazyApplyFiltersPopoverContent
indexPatterns={indexPatterns}
filters={filters}
onCancel={onCancel}
onSubmit={onSubmit}
/>
</React.Suspense>
);
};

View file

@ -18,12 +18,10 @@
*/
import React from 'react';
import { FilterLabel } from './filter_label';
import { render, cleanup } from '@testing-library/react/pure';
import FilterLabel from './filter_label';
import { render } from '@testing-library/react';
import { phraseFilter } from '../../../../stubs';
afterEach(cleanup);
test('alias', () => {
const filter = {
...phraseFilter,

View file

@ -24,13 +24,16 @@ import { existsOperator, isOneOfOperator } from './filter_operators';
import { Filter, FILTERS } from '../../../../../common';
import type { FilterLabelStatus } from '../../filter_item';
interface Props {
// @internal
export interface FilterLabelProps {
filter: Filter;
valueLabel?: string;
filterLabelStatus?: FilterLabelStatus;
}
export function FilterLabel({ filter, valueLabel, filterLabelStatus }: Props) {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default function FilterLabel({ filter, valueLabel, filterLabelStatus }: FilterLabelProps) {
const prefixText = filter.meta.negate
? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', {
defaultMessage: 'NOT ',

View file

@ -20,7 +20,7 @@
import { EuiBadge, useInnerText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { FC } from 'react';
import { FilterLabel } from '../filter_editor/lib/filter_label';
import { FilterLabel } from '../';
import { Filter, isFilterPinned } from '../../../../common';
import type { FilterLabelStatus } from '../filter_item';

View file

@ -17,5 +17,19 @@
* under the License.
*/
export { ShardFailureRequest } from './shard_failure_types';
export { ShardFailureOpenModalButton } from './shard_failure_open_modal_button';
import React from 'react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import type { FilterLabelProps } from './filter_editor/lib/filter_label';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazyFilterLabel = React.lazy(() => import('./filter_editor/lib/filter_label'));
export const FilterLabel = (props: FilterLabelProps) => (
<React.Suspense fallback={<Fallback />}>
<LazyFilterLabel {...props} />
</React.Suspense>
);

View file

@ -17,17 +17,8 @@
* under the License.
*/
export { SuggestionsComponent } from './typeahead';
export { IndexPatternSelect } from './index_pattern_select';
export { FilterBar } from './filter_bar';
export { QueryStringInput, QueryStringInputProps } from './query_string_input/query_string_input';
export { IndexPatternSelectProps } from './index_pattern_select';
export { FilterLabel } from './filter_bar';
export { QueryStringInput, QueryStringInputProps } from './query_string_input';
export { SearchBar, SearchBarProps, StatefulSearchBarProps } from './search_bar';
// @internal
export { ShardFailureOpenModalButton, ShardFailureRequest } from './shard_failure_modal';
// @internal
export { SavedQueryManagementComponent } from './saved_query_management';
// @internal
export { SaveQueryForm, SavedQueryMeta } from './saved_query_form';
export { SuggestionsComponent } from './typeahead';

View file

@ -17,4 +17,15 @@
* under the License.
*/
export * from './index_pattern_select';
import _ from 'lodash';
import React from 'react';
import { SavedObjectsClientContract } from 'src/core/public';
import { IndexPatternSelect, IndexPatternSelectProps } from './';
// Takes in stateful runtime dependencies and pre-wires them to the component
export function createIndexPatternSelect(savedObjectsClient: SavedObjectsClientContract) {
return (props: Omit<IndexPatternSelectProps, 'savedObjectsClient'>) => (
<IndexPatternSelect {...props} savedObjectsClient={savedObjectsClient} />
);
}

View file

@ -17,5 +17,22 @@
* under the License.
*/
export { FilterBar } from './filter_bar';
export { FilterLabel } from './filter_editor/lib/filter_label';
import React from 'react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import type { IndexPatternSelectProps } from './index_pattern_select';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazyIndexPatternSelect = React.lazy(() => import('./index_pattern_select'));
export const IndexPatternSelect = (props: IndexPatternSelectProps) => (
<React.Suspense fallback={<Fallback />}>
<LazyIndexPatternSelect {...props} />
</React.Suspense>
);
export * from './create_index_pattern_select';
export type { IndexPatternSelectProps } from './index_pattern_select';

View file

@ -23,11 +23,10 @@ import React, { Component } from 'react';
import { Required } from '@kbn/utility-types';
import { EuiComboBox, EuiComboBoxProps } from '@elastic/eui';
import { SavedObjectsClientContract, SimpleSavedObject } from '../../../../../core/public';
import { SavedObjectsClientContract, SimpleSavedObject } from 'src/core/public';
import { getTitle } from '../../../common/index_patterns/lib';
export type IndexPatternSelectProps = Required<
// Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions' | 'append' | 'prepend' | 'sortMatchesBy'>,
Omit<EuiComboBoxProps<any>, 'isLoading' | 'onSearchChange' | 'options' | 'selectedOptions'>,
'onChange' | 'placeholder'
> & {
@ -59,14 +58,9 @@ const getIndexPatterns = async (
return resp.savedObjects;
};
// Takes in stateful runtime dependencies and pre-wires them to the component
export function createIndexPatternSelect(savedObjectsClient: SavedObjectsClientContract) {
return (props: Omit<IndexPatternSelectProps, 'savedObjectsClient'>) => (
<IndexPatternSelect {...props} savedObjectsClient={savedObjectsClient} />
);
}
export class IndexPatternSelect extends Component<IndexPatternSelectProps> {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default class IndexPatternSelect extends Component<IndexPatternSelectProps> {
private isMounted: boolean = false;
state: IndexPatternSelectState;

View file

@ -0,0 +1,45 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import { withKibana } from '../../../../kibana_react/public';
import type { QueryBarTopRowProps } from './query_bar_top_row';
import type { QueryStringInputProps } from './query_string_input';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazyQueryBarTopRow = React.lazy(() => import('./query_bar_top_row'));
export const QueryBarTopRow = (props: QueryBarTopRowProps) => (
<React.Suspense fallback={<Fallback />}>
<LazyQueryBarTopRow {...props} />
</React.Suspense>
);
const LazyQueryStringInputUI = withKibana(React.lazy(() => import('./query_string_input')));
export const QueryStringInput = (props: QueryStringInputProps) => (
<React.Suspense fallback={<Fallback />}>
<LazyQueryStringInputUI {...props} />
</React.Suspense>
);
export type { QueryStringInputProps };

View file

@ -21,7 +21,10 @@ import { mockPersistedLogFactory } from './query_string_input.test.mocks';
import React from 'react';
import { mount } from 'enzyme';
import { QueryBarTopRow } from './query_bar_top_row';
import { waitFor } from '@testing-library/dom';
import { render } from '@testing-library/react';
import { QueryBarTopRow } from './';
import { coreMock } from '../../../../../core/public/mocks';
import { dataPluginMock } from '../../mocks';
@ -120,8 +123,8 @@ describe('QueryBarTopRowTopRow', () => {
jest.clearAllMocks();
});
it('Should render query and time picker', () => {
const component = mount(
it('Should render query and time picker', async () => {
const { getByText, getByTestId } = render(
wrapQueryBarTopRowInContext({
query: kqlQuery,
screenTitle: 'Another Screen',
@ -131,8 +134,8 @@ describe('QueryBarTopRowTopRow', () => {
})
);
expect(component.find(QUERY_INPUT_SELECTOR).length).toBe(1);
expect(component.find(TIMEPICKER_SELECTOR).length).toBe(1);
await waitFor(() => getByText(kqlQuery.query));
await waitFor(() => getByTestId('superDatePickerShowDatesButton'));
});
it('Should create a unique PersistedLog based on the appName and query language', () => {

View file

@ -37,12 +37,13 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { Toast } from 'src/core/public';
import { IDataPluginServices, IIndexPattern, TimeRange, TimeHistoryContract, Query } from '../..';
import { useKibana, toMountPoint } from '../../../../kibana_react/public';
import { QueryStringInput } from './query_string_input';
import { QueryStringInput } from './';
import { doesKueryExpressionHaveLuceneSyntaxError, UI_SETTINGS } from '../../../common';
import { PersistedLog, getQueryLog } from '../../query';
import { NoDataPopover } from './no_data_popover';
interface Props {
// @internal
export interface QueryBarTopRowProps {
query?: Query;
onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void;
onChange: (payload: { dateRange: TimeRange; query?: Query }) => void;
@ -67,7 +68,9 @@ interface Props {
indicateNoData?: boolean;
}
export function QueryBarTopRow(props: Props) {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default function QueryBarTopRow(props: QueryBarTopRowProps) {
const [isDateRangeInvalid, setIsDateRangeInvalid] = useState(false);
const [isQueryInputFocused, setIsQueryInputFocused] = useState(false);

View file

@ -23,18 +23,24 @@ import {
mockPersistedLogFactory,
} from './query_string_input.test.mocks';
import { EuiTextArea } from '@elastic/eui';
import React from 'react';
import { QueryLanguageSwitcher } from './language_switcher';
import { QueryStringInput, QueryStringInputUI } from './query_string_input';
import { coreMock } from '../../../../../core/public/mocks';
import { dataPluginMock } from '../../mocks';
const startMock = coreMock.createStart();
import { stubIndexPatternWithFields } from '../../stubs';
import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
import { I18nProvider } from '@kbn/i18n/react';
import { mount } from 'enzyme';
import { waitFor } from '@testing-library/dom';
import { render } from '@testing-library/react';
import { EuiTextArea } from '@elastic/eui';
import { QueryLanguageSwitcher } from './language_switcher';
import { QueryStringInput } from './';
import type QueryStringInputUI from './query_string_input';
import { coreMock } from '../../../../../core/public/mocks';
import { dataPluginMock } from '../../mocks';
import { stubIndexPatternWithFields } from '../../stubs';
import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
const startMock = coreMock.createStart();
const noop = () => {
return;
@ -94,16 +100,17 @@ describe('QueryStringInput', () => {
jest.clearAllMocks();
});
it('Should render the given query', () => {
const component = mount(
it('Should render the given query', async () => {
const { getByText } = render(
wrapQueryStringInputInContext({
query: kqlQuery,
onSubmit: noop,
indexPatterns: [stubIndexPatternWithFields],
})
);
expect(component.find(EuiTextArea).props().value).toBe(kqlQuery.query);
expect(component.find(QueryLanguageSwitcher).prop('language')).toBe(kqlQuery.language);
await waitFor(() => getByText(kqlQuery.query));
await waitFor(() => getByText('KQL'));
});
it('Should pass the query language to the language switcher', () => {

View file

@ -39,7 +39,7 @@ import { Toast } from 'src/core/public';
import { IDataPluginServices, IIndexPattern, Query } from '../..';
import { QuerySuggestion, QuerySuggestionTypes } from '../../autocomplete';
import { withKibana, KibanaReactContextValue, toMountPoint } from '../../../../kibana_react/public';
import { KibanaReactContextValue, toMountPoint } from '../../../../kibana_react/public';
import { fetchIndexPatterns } from './fetch_index_patterns';
import { QueryLanguageSwitcher } from './language_switcher';
import { PersistedLog, getQueryLog, matchPairs, toUser, fromUser } from '../../query';
@ -93,7 +93,9 @@ const KEY_CODES = {
END: 35,
};
export class QueryStringInputUI extends Component<Props, State> {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default class QueryStringInputUI extends Component<Props, State> {
public state: State = {
isSuggestionsVisible: false,
index: null,
@ -546,7 +548,7 @@ export class QueryStringInputUI extends Component<Props, State> {
public componentWillUnmount() {
if (this.abortController) this.abortController.abort();
this.updateSuggestions.cancel();
if (this.updateSuggestions.cancel) this.updateSuggestions.cancel();
this.componentIsUnmounting = true;
window.removeEventListener('resize', this.handleAutoHeight);
window.removeEventListener('scroll', this.handleListUpdate, { capture: true });
@ -690,5 +692,3 @@ export class QueryStringInputUI extends Component<Props, State> {
);
}
}
export const QueryStringInput: React.FC<QueryStringInputProps> = withKibana(QueryStringInputUI);

View file

@ -17,4 +17,5 @@
* under the License.
*/
// @internal
export { SavedQueryMeta, SaveQueryForm } from '../saved_query_form/save_query_form';

View file

@ -23,7 +23,7 @@ import { CoreStart } from 'src/core/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
import { KibanaContextProvider } from '../../../../kibana_react/public';
import { QueryStart, SavedQuery } from '../../query';
import { SearchBarOwnProps, SearchBar } from './search_bar';
import { SearchBar, SearchBarOwnProps } from './';
import { useFilterManager } from './lib/use_filter_manager';
import { useTimefilter } from './lib/use_timefilter';
import { useSavedQuery } from './lib/use_saved_query';

View file

@ -17,5 +17,25 @@
* under the License.
*/
export { SearchBar, SearchBarProps } from './search_bar';
import React from 'react';
import { injectI18n } from '@kbn/i18n/react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import { withKibana } from '../../../../kibana_react/public';
import type { SearchBarProps } from './search_bar';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={3} />
</EuiDelayRender>
);
const LazySearchBar = React.lazy(() => import('./search_bar'));
const WrappedSearchBar = (props: SearchBarProps) => (
<React.Suspense fallback={<Fallback />}>
<LazySearchBar {...props} />
</React.Suspense>
);
export const SearchBar = injectI18n(withKibana(WrappedSearchBar));
export { StatefulSearchBarProps } from './create_search_bar';
export type { SearchBarProps, SearchBarOwnProps } from './search_bar';

View file

@ -18,7 +18,10 @@
*/
import React from 'react';
import { SearchBar } from './search_bar';
import { waitFor } from '@testing-library/dom';
import { render } from '@testing-library/react';
import { SearchBar } from './';
import { KibanaContextProvider } from 'src/plugins/kibana_react/public';
import { I18nProvider } from '@kbn/i18n/react';
@ -26,7 +29,6 @@ import { I18nProvider } from '@kbn/i18n/react';
import { coreMock } from '../../../../../core/public/mocks';
const startMock = coreMock.createStart();
import { mount } from 'enzyme';
import { IIndexPattern } from '../..';
const mockTimeHistory = {
@ -41,7 +43,7 @@ jest.mock('..', () => {
};
});
jest.mock('../query_string_input/query_bar_top_row', () => {
jest.mock('../query_string_input', () => {
return {
QueryBarTopRow: () => <div className="queryBar" />,
};
@ -116,41 +118,46 @@ function wrapSearchBarInContext(testProps: any) {
}
describe('SearchBar', () => {
const SEARCH_BAR_TEST_ID = 'globalQueryBar';
const SEARCH_BAR_ROOT = '.globalQueryBar';
const FILTER_BAR = '.filterBar';
const FILTER_BAR = '.globalFilterBar';
const QUERY_BAR = '.queryBar';
beforeEach(() => {
jest.clearAllMocks();
});
it('Should render query bar when no options provided (in reality - timepicker)', () => {
const component = mount(
it('Should render query bar when no options provided (in reality - timepicker)', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(0);
expect(component.find(QUERY_BAR).length).toBe(1);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(0);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(1);
});
it('Should render empty when timepicker is off and no options provided', () => {
const component = mount(
it('Should render empty when timepicker is off and no options provided', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
showDatePicker: false,
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(0);
expect(component.find(QUERY_BAR).length).toBe(0);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(0);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(0);
});
it('Should render filter bar, when required fields are provided', () => {
const component = mount(
it('Should render filter bar, when required fields are provided', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
showDatePicker: false,
@ -159,13 +166,15 @@ describe('SearchBar', () => {
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(1);
expect(component.find(QUERY_BAR).length).toBe(0);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(1);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(0);
});
it('Should NOT render filter bar, if disabled', () => {
const component = mount(
it('Should NOT render filter bar, if disabled', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
showFilterBar: false,
@ -175,13 +184,15 @@ describe('SearchBar', () => {
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(0);
expect(component.find(QUERY_BAR).length).toBe(0);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(0);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(0);
});
it('Should render query bar, when required fields are provided', () => {
const component = mount(
it('Should render query bar, when required fields are provided', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
screenTitle: 'test screen',
@ -190,13 +201,15 @@ describe('SearchBar', () => {
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(0);
expect(component.find(QUERY_BAR).length).toBe(1);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(0);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(1);
});
it('Should NOT render query bar, if disabled', () => {
const component = mount(
it('Should NOT render query bar, if disabled', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
screenTitle: 'test screen',
@ -206,13 +219,15 @@ describe('SearchBar', () => {
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(0);
expect(component.find(QUERY_BAR).length).toBe(0);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(0);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(0);
});
it('Should render query bar and filter bar', () => {
const component = mount(
it('Should render query bar and filter bar', async () => {
const { container, getByTestId } = render(
wrapSearchBarInContext({
indexPatterns: [mockIndexPattern],
screenTitle: 'test screen',
@ -223,8 +238,10 @@ describe('SearchBar', () => {
})
);
expect(component.find(SEARCH_BAR_ROOT).length).toBe(1);
expect(component.find(FILTER_BAR).length).toBe(1);
expect(component.find(QUERY_BAR).length).toBe(1);
await waitFor(() => getByTestId(SEARCH_BAR_TEST_ID));
expect(container.querySelectorAll(SEARCH_BAR_ROOT).length).toBe(1);
expect(container.querySelectorAll(FILTER_BAR).length).toBe(1);
expect(container.querySelectorAll(QUERY_BAR).length).toBe(1);
});
});

View file

@ -26,11 +26,13 @@ import { get, isEqual } from 'lodash';
import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public';
import { QueryBarTopRow } from '../query_string_input/query_bar_top_row';
import { QueryBarTopRow } from '../query_string_input';
import { SavedQueryAttributes, TimeHistoryContract, SavedQuery } from '../../query';
import { IDataPluginServices } from '../../types';
import { TimeRange, Query, Filter, IIndexPattern } from '../../../common';
import { SavedQueryMeta, SavedQueryManagementComponent, SaveQueryForm, FilterBar } from '..';
import { FilterBar } from '../filter_bar/filter_bar';
import { SavedQueryMeta, SaveQueryForm } from '../saved_query_form';
import { SavedQueryManagementComponent } from '../saved_query_management';
interface SearchBarInjectedDeps {
kibana: KibanaReactContextValue<IDataPluginServices>;
@ -437,7 +439,7 @@ class SearchBarUI extends Component<SearchBarProps, State> {
}
return (
<div className="globalQueryBar">
<div className="globalQueryBar" data-test-subj="globalQueryBar">
{queryBar}
{filterBar}
@ -465,4 +467,6 @@ class SearchBarUI extends Component<SearchBarProps, State> {
}
}
export const SearchBar = injectI18n(withKibana(SearchBarUI));
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default injectI18n(withKibana(SearchBarUI));

View file

@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import type { ShardFailureOpenModalButtonProps } from './shard_failure_open_modal_button';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazyShardFailureOpenModalButton = React.lazy(
() => import('./shard_failure_open_modal_button')
);
export const ShardFailureOpenModalButton = (props: ShardFailureOpenModalButtonProps) => (
<React.Suspense fallback={<Fallback />}>
<LazyShardFailureOpenModalButton {...props} />
</React.Suspense>
);
export type { ShardFailureRequest } from './shard_failure_types';

View file

@ -19,7 +19,7 @@
import { openModal } from './shard_failure_open_modal_button.test.mocks';
import React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { ShardFailureOpenModalButton } from './shard_failure_open_modal_button';
import ShardFailureOpenModalButton from './shard_failure_open_modal_button';
import { shardFailureRequest } from './__mocks__/shard_failure_request';
import { shardFailureResponse } from './__mocks__/shard_failure_response';
import { findTestSubject } from '@elastic/eui/lib/test';

View file

@ -26,13 +26,20 @@ import { toMountPoint } from '../../../../kibana_react/public';
import { ShardFailureModal } from './shard_failure_modal';
import { ShardFailureRequest } from './shard_failure_types';
interface Props {
// @internal
export interface ShardFailureOpenModalButtonProps {
request: ShardFailureRequest;
response: SearchResponse<any>;
title: string;
}
export function ShardFailureOpenModalButton({ request, response, title }: Props) {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default function ShardFailureOpenModalButton({
request,
response,
title,
}: ShardFailureOpenModalButtonProps) {
function onClick() {
const modal = getOverlays().openModal(
toMountPoint(

View file

@ -17,4 +17,19 @@
* under the License.
*/
export { SuggestionsComponent } from './suggestions_component';
import React from 'react';
import { EuiLoadingContent, EuiDelayRender } from '@elastic/eui';
import type { SuggestionsComponentProps } from './suggestions_component';
const Fallback = () => (
<EuiDelayRender>
<EuiLoadingContent lines={1} />
</EuiDelayRender>
);
const LazySuggestionsComponent = React.lazy(() => import('./suggestions_component'));
export const SuggestionsComponent = (props: SuggestionsComponentProps) => (
<React.Suspense fallback={<Fallback />}>
<LazySuggestionsComponent {...props} />
</React.Suspense>
);

View file

@ -21,7 +21,7 @@ import { mount, shallow } from 'enzyme';
import React from 'react';
import { QuerySuggestion, QuerySuggestionTypes } from '../../autocomplete';
import { SuggestionComponent } from './suggestion_component';
import { SuggestionsComponent } from './suggestions_component';
import SuggestionsComponent from './suggestions_component';
const noop = () => {
return;

View file

@ -29,7 +29,8 @@ import {
SUGGESTIONS_LIST_REQUIRED_WIDTH,
} from './constants';
interface Props {
// @internal
export interface SuggestionsComponentProps {
index: number | null;
onClick: (suggestion: QuerySuggestion) => void;
onMouseEnter: (index: number) => void;
@ -42,7 +43,9 @@ interface Props {
export type SuggestionsListSize = 's' | 'l';
export class SuggestionsComponent extends Component<Props> {
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default class SuggestionsComponent extends Component<SuggestionsComponentProps> {
private childNodes: HTMLDivElement[] = [];
private parentNode: HTMLDivElement | null = null;
@ -107,7 +110,7 @@ export class SuggestionsComponent extends Component<Props> {
);
}
public componentDidUpdate(prevProps: Props) {
public componentDidUpdate(prevProps: SuggestionsComponentProps) {
if (prevProps.index !== this.props.index) {
this.scrollIntoView();
}

View file

@ -20,14 +20,13 @@
import React, { ComponentType } from 'react';
import { injectI18n, InjectedIntlProps } from '@kbn/i18n/react';
import { EuiFormRow } from '@elastic/eui';
import { IndexPatternSelect } from 'src/plugins/data/public';
import { IndexPatternSelectProps } from 'src/plugins/data/public';
export type IndexPatternSelectFormRowUiProps = InjectedIntlProps & {
onChange: (opt: any) => void;
indexPatternId: string;
controlIndex: number;
IndexPatternSelect: ComponentType<IndexPatternSelect['props']>;
IndexPatternSelect: ComponentType<IndexPatternSelectProps>;
};
function IndexPatternSelectFormRowUi(props: IndexPatternSelectFormRowUiProps) {

View file

@ -25,14 +25,14 @@ import { EuiFormRow, EuiFieldNumber, EuiSwitch, EuiSelect } from '@elastic/eui';
import { IndexPatternSelectFormRow } from './index_pattern_select_form_row';
import { FieldSelect } from './field_select';
import { ControlParams, ControlParamsOptions } from '../../editor_utils';
import { IIndexPattern, IFieldType, IndexPatternSelect } from '../../../../data/public';
import { IIndexPattern, IFieldType, IndexPatternSelectProps } from '../../../../data/public';
import { InputControlVisDependencies } from '../../plugin';
interface ListControlEditorState {
isLoadingFieldType: boolean;
isStringField: boolean;
prevFieldName: string;
IndexPatternSelect: ComponentType<IndexPatternSelect['props']> | null;
IndexPatternSelect: ComponentType<IndexPatternSelectProps> | null;
}
interface ListControlEditorProps {

View file

@ -24,7 +24,7 @@ import { FormattedMessage } from '@kbn/i18n/react';
import { IndexPatternSelectFormRow } from './index_pattern_select_form_row';
import { FieldSelect } from './field_select';
import { ControlParams, ControlParamsOptions } from '../../editor_utils';
import { IIndexPattern, IFieldType, IndexPatternSelect } from '../../../../data/public';
import { IIndexPattern, IFieldType, IndexPatternSelectProps } from '../../../../data/public';
import { InputControlVisDependencies } from '../../plugin';
interface RangeControlEditorProps {
@ -42,7 +42,7 @@ interface RangeControlEditorProps {
}
interface RangeControlEditorState {
IndexPatternSelect: ComponentType<IndexPatternSelect['props']> | null;
IndexPatternSelect: ComponentType<IndexPatternSelectProps> | null;
}
function filterField(field: IFieldType) {

View file

@ -6,7 +6,7 @@
import { mount } from 'enzyme';
import React from 'react';
import { waitFor } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import { coreMock } from '../../../../../../../src/core/public/mocks';
import { DEFAULT_FROM, DEFAULT_TO } from '../../../../common/constants';
import { TestProviders, mockIndexPattern } from '../../mock';
@ -20,6 +20,20 @@ describe('QueryBar ', () => {
const mockOnSubmitQuery = jest.fn();
const mockOnSavedQuery = jest.fn();
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
// The data plugin's `SearchBar` is lazy loaded, so we need to ensure it is
// available before we mount our component with Enzyme.
const getWrapper = async (Component: ReturnType<typeof Proxy>) => {
const { getByTestId } = render(Component);
await waitFor(() => getByTestId('queryInput')); // check for presence of query input
return mount(Component);
};
beforeEach(() => {
mockOnChangeQuery.mockClear();
mockOnSubmitQuery.mockClear();
@ -169,14 +183,8 @@ describe('QueryBar ', () => {
});
describe('state', () => {
test('clears draftQuery when filterQueryDraft has been cleared', () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
test('clears draftQuery when filterQueryDraft has been cleared', async () => {
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}
@ -209,14 +217,8 @@ describe('QueryBar ', () => {
});
describe('#onQueryChange', () => {
test(' is the only reference that changed when filterQueryDraft props get updated', () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
test(' is the only reference that changed when filterQueryDraft props get updated', async () => {
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}
@ -247,14 +249,8 @@ describe('QueryBar ', () => {
});
describe('#onQuerySubmit', () => {
test(' is the only reference that changed when filterQuery props get updated', () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
test(' is the only reference that changed when filterQuery props get updated', async () => {
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}
@ -282,14 +278,8 @@ describe('QueryBar ', () => {
expect(onSavedQueryRef).toEqual(wrapper.find(SearchBar).props().onSavedQueryUpdated);
});
test(' is only reference that changed when timelineId props get updated', () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
test(' is only reference that changed when timelineId props get updated', async () => {
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}
@ -319,14 +309,8 @@ describe('QueryBar ', () => {
});
describe('#onSavedQueryUpdated', () => {
test('is only reference that changed when dataProviders props get updated', () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
test('is only reference that changed when dataProviders props get updated', async () => {
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}
@ -357,13 +341,7 @@ describe('QueryBar ', () => {
describe('SavedQueryManagementComponent state', () => {
test('popover should hidden when "Save current query" button was clicked', async () => {
const Proxy = (props: QueryBarComponentProps) => (
<TestProviders>
<QueryBar {...props} />
</TestProviders>
);
const wrapper = mount(
const wrapper = await getWrapper(
<Proxy
dateRangeFrom={DEFAULT_FROM}
dateRangeTo={DEFAULT_TO}

View file

@ -27,7 +27,8 @@ export default function ({ getPageObjects, getService }) {
it('should request documents when zoomed to smaller regions showing less data', async () => {
const hits = await PageObjects.maps.getHits();
expect(hits).to.equal('33');
// Allow a range of hits to account for variances in browser window size.
expect(parseInt(hits)).to.be.within(30, 40);
});
it('should request clusters when zoomed to larger regions showing lots of data', async () => {