[Unified search] Create unified search plugin (#127651)

* [Unified search] Create unified search plugin

* add unified_search into USES_STYLED_COMPONENTS

* fix JEST group 4

* update limits for data plugin

* fix: remove unifiedSearch plugin from x-pack/plugins/file_upload

* feat: updated .github/CODEOWNERS and set @elastic/kibana-app-services as a code owner

* apply PR comments

* [CI] Auto-commit changed files from 'node scripts/build_plugin_list_docs'

* feat: moved filter bar, apply filters folders and apply filter action from Data plugin to unified search plugin

* fix Checks

* fix Checks

* fix Linting and Default CI Group #16

* fix Checks

* fix Checks

* fix Linting (with types)

* fix show FILTER_BAR

* fix Jest Tests

* feat replece indexPatternsContranct in setIndexPatterns to DataViewsContract

* feat: removed unnecessary interface in unified search

* fix Checks

* fix Checks

* fix Jest Tests, Checks

* fix Checks

* resolve comments

Co-authored-by: Alexey Antonov <alexwizp@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nodir Latipov 2022-04-05 12:23:31 +05:00 committed by GitHub
parent 9b85ae95fb
commit 3e2761d981
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
262 changed files with 1467 additions and 1058 deletions

1
.github/CODEOWNERS vendored
View file

@ -82,6 +82,7 @@
/src/plugins/bfetch/ @elastic/kibana-app-services
/src/plugins/data_view_management/ @elastic/kibana-app-services
/src/plugins/inspector/ @elastic/kibana-app-services
/src/plugins/unified_search/ @elastic/kibana-app-services
/x-pack/examples/ui_actions_enhanced_examples/ @elastic/kibana-app-services
/x-pack/plugins/data_enhanced/ @elastic/kibana-app-services
/x-pack/plugins/embeddable_enhanced/ @elastic/kibana-app-services

View file

@ -90,7 +90,8 @@
"visTypeVega": "src/plugins/vis_types/vega",
"visTypeVislib": "src/plugins/vis_types/vislib",
"visTypeXy": "src/plugins/vis_types/xy",
"visualizations": "src/plugins/visualizations"
"visualizations": "src/plugins/visualizations",
"unifiedSearch": "src/plugins/unified_search"
},
"translations": []
}

View file

@ -291,6 +291,10 @@ In general this plugin provides:
- Exposing a context menu for the user to choose the appropriate action when there are multiple actions attached to a single trigger.
|{kib-repo}blob/{branch}/src/plugins/unified_search/README.md[unifiedSearch]
|Contains all the components of Kibana's unified search experience. Specifically:
|{kib-repo}blob/{branch}/src/plugins/url_forwarding/README.md[urlForwarding]
|This plugins contains helpers to redirect legacy URLs. It can be used to forward old URLs to their new counterparts.

View file

@ -9,7 +9,7 @@
"description": "Example plugin of how to use data plugin search services",
"server": true,
"ui": true,
"requiredPlugins": ["navigation", "data", "developerExamples", "kibanaUtils", "share"],
"requiredPlugins": ["navigation", "data", "developerExamples", "kibanaUtils", "share", "unifiedSearch"],
"optionalPlugins": [],
"requiredBundles": ["kibanaReact"],
"owner": {

View file

@ -39,7 +39,7 @@ const LINKS: ExampleLink[] = [
export const renderApp = (
{ notifications, savedObjects, http, application }: CoreStart,
{ data, navigation }: AppPluginStartDependencies,
{ data, navigation, unifiedSearch }: AppPluginStartDependencies,
{ element, history }: AppMountParameters
) => {
ReactDOM.render(
@ -53,6 +53,7 @@ export const renderApp = (
navigation={navigation}
data={data}
http={http}
unifiedSearch={unifiedSearch}
/>
</Route>
<Route path={LINKS[1].path}>
@ -63,6 +64,7 @@ export const renderApp = (
navigation={navigation}
notifications={notifications}
data={data}
unifiedSearch={unifiedSearch}
/>
</Route>

View file

@ -44,6 +44,7 @@ import {
isCompleteResponse,
isErrorResponse,
} from '../../../../src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from '../../../../src/plugins/unified_search/public';
import type { DataViewField, DataView } from '../../../../src/plugins/data_views/public';
import { IMyStrategyResponse } from '../../common/types';
import { AbortError } from '../../../../src/plugins/kibana_utils/common';
@ -53,6 +54,7 @@ interface SearchExamplesAppDeps {
http: CoreStart['http'];
navigation: NavigationPublicPluginStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}
function getNumeric(fields?: DataViewField[]) {
@ -85,8 +87,9 @@ export const SearchExamplesApp = ({
notifications,
navigation,
data,
unifiedSearch,
}: SearchExamplesAppDeps) => {
const { IndexPatternSelect } = data.ui;
const { IndexPatternSelect } = unifiedSearch.ui;
const [getCool, setGetCool] = useState<boolean>(false);
const [fibonacciN, setFibonacciN] = useState<number>(10);
const [timeTook, setTimeTook] = useState<number | undefined>();

View file

@ -49,6 +49,7 @@ import {
SearchSessionState,
TimeRange,
} from '../../../../src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from '../../../../src/plugins/unified_search/public';
import type { DataView, DataViewField } from '../../../../src/plugins/data_views/public';
import {
createStateContainer,
@ -60,6 +61,7 @@ interface SearchSessionsExampleAppDeps {
notifications: CoreStart['notifications'];
navigation: NavigationPublicPluginStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}
/**
@ -89,8 +91,9 @@ export const SearchSessionsExampleApp = ({
notifications,
navigation,
data,
unifiedSearch,
}: SearchSessionsExampleAppDeps) => {
const { IndexPatternSelect } = data.ui;
const { IndexPatternSelect } = unifiedSearch.ui;
const [isSearching, setIsSearching] = useState<boolean>(false);
const [request, setRequest] = useState<IEsSearchRequest | null>(null);

View file

@ -8,6 +8,7 @@
import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public';
import { DataPublicPluginStart } from '../../../src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from '../../../src/plugins/unified_search/public';
import { DeveloperExamplesSetup } from '../../developer_examples/public';
import { SharePluginSetup } from '../../../src/plugins/share/public';
@ -24,4 +25,5 @@ export interface AppPluginSetupDependencies {
export interface AppPluginStartDependencies {
navigation: NavigationPublicPluginStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}

View file

@ -13,7 +13,7 @@ module.exports = {
*/
USES_STYLED_COMPONENTS: [
/packages[\/\\]kbn-ui-shared-deps-(npm|src)[\/\\]/,
/src[\/\\]plugins[\/\\](data|kibana_react)[\/\\]/,
/src[\/\\]plugins[\/\\](unified_search|kibana_react)[\/\\]/,
/x-pack[\/\\]plugins[\/\\](apm|beats_management|cases|fleet|infra|lists|observability|osquery|security_solution|timelines|uptime|ux)[\/\\]/,
/x-pack[\/\\]test[\/\\]plugin_functional[\/\\]plugins[\/\\]resolver_test[\/\\]/,
],

View file

@ -99,7 +99,6 @@ pageLoadAssetSize:
visTypeMetric: 23332
bfetch: 22837
kibanaUtils: 79713
data: 491273
dataViews: 43532
expressions: 140958
fieldFormats: 65209
@ -124,5 +123,7 @@ pageLoadAssetSize:
sessionView: 77750
cloudSecurityPosture: 19109
visTypeGauge: 24113
unifiedSearch: 49195
data: 454087
expressionXY: 26500
eventAnnotation: 19334

View file

@ -6,8 +6,6 @@
* Side Public License, v 1.
*/
export type { ApplyGlobalFilterActionContext } from './apply_filter_action';
export { ACTION_GLOBAL_APPLY_FILTER, createFilterAction } from './apply_filter_action';
export { createFiltersFromValueClickAction } from './filters/create_filters_from_value_click';
export { createFiltersFromRangeSelectAction } from './filters/create_filters_from_range_select';
export * from './select_range_action';

View file

@ -51,8 +51,6 @@ import {
getEsQueryConfig,
} from '../common';
import { FilterLabel, FilterItem } from './ui';
import {
getDisplayValueFromFilter,
generateFilters,
@ -90,9 +88,6 @@ const convertRangeFilterToTimeRangeString = oldConvertRangeFilterToTimeRangeStri
* @removeBy 8.1
*/
export const esFilters = {
FilterLabel,
FilterItem,
FILTERS,
FilterStateStore,

View file

@ -1,2 +1 @@
@import './ui/index';
@import './utils/table_inspector_view/index';

View file

@ -19,7 +19,6 @@ export * from './deprecated';
*/
export { getEsQueryConfig, FilterStateStore } from '../common';
export { FilterLabel, FilterItem } from './ui';
export {
getDisplayValueFromFilter,
generateFilters,
@ -259,15 +258,6 @@ export const search = {
* UI components
*/
export type {
SearchBarProps,
StatefulSearchBarProps,
IndexPatternSelectProps,
QueryStringInputProps,
} from './ui';
export { QueryStringInput, SearchBar } from './ui';
/**
* Types to be shared externally
* @public
@ -281,6 +271,8 @@ export {
getDefaultQuery,
FilterManager,
TimeHistory,
getQueryLog,
mapAndFlattenFilters,
} from './query';
export type {
@ -293,6 +285,9 @@ export type {
QueryStateChange,
QueryStart,
AutoRefreshDoneFn,
PersistedLog,
QueryStringContract,
QuerySetup,
} from './query';
export type { AggsStart } from './search/aggs';
@ -303,8 +298,6 @@ export type { SavedObject } from '../common';
export { isTimeRange, isQuery, flattenHit, calculateBounds, tabifyAggResponse } from '../common';
export type { ApplyGlobalFilterActionContext } from './actions';
export { ACTION_GLOBAL_APPLY_FILTER } from './actions';
export { APPLY_FILTER_TRIGGER } from './triggers';
/*
@ -321,7 +314,6 @@ export type {
DataPublicPluginSetup,
DataPublicPluginStart,
IDataPluginServices,
DataPublicPluginStartUi,
DataPublicPluginStartActions,
} from './types';

View file

@ -63,10 +63,6 @@ const createStartContract = (): Start => {
search: searchServiceMock.createStartContract(),
fieldFormats: fieldFormatsServiceMock.createStartContract(),
query: queryStartMock,
ui: {
IndexPatternSelect: jest.fn(),
SearchBar: jest.fn().mockReturnValue(null),
},
dataViews,
/**
* @deprecated Use dataViews service instead. All index pattern interfaces were renamed.

View file

@ -20,7 +20,6 @@ import type {
import { AutocompleteService } from './autocomplete';
import { SearchService } from './search/search_service';
import { QueryService } from './query';
import { createIndexPatternSelect } from './ui/index_pattern_select';
import {
setIndexPatterns,
setNotifications,
@ -29,17 +28,13 @@ import {
setUiSettings,
setTheme,
} from './services';
import { createSearchBar } from './ui/search_bar/create_search_bar';
import {
ACTION_GLOBAL_APPLY_FILTER,
createFilterAction,
createFiltersFromValueClickAction,
createFiltersFromRangeSelectAction,
createValueClickAction,
createSelectRangeAction,
} from './actions';
import { APPLY_FILTER_TRIGGER, applyFilterTrigger } from './triggers';
import { UsageCollectionSetup } from '../../usage_collection/public';
import { applyFilterTrigger } from './triggers';
import { getTableViewDescription } from './utils/table_inspector_view';
import { NowProvider, NowProviderInternalContract } from './now_provider';
import { getAggsFormats, DatatableUtilitiesService } from '../common';
@ -57,7 +52,6 @@ export class DataPublicPlugin
private readonly searchService: SearchService;
private readonly queryService: QueryService;
private readonly storage: IStorageWrapper;
private usageCollection: UsageCollectionSetup | undefined;
private readonly nowProvider: NowProviderInternalContract;
constructor(initializerContext: PluginInitializerContext<ConfigSchema>) {
@ -82,7 +76,6 @@ export class DataPublicPlugin
): DataPublicPluginSetup {
const startServices = createStartServicesGetter(core.getStartServices);
this.usageCollection = usageCollection;
setTheme(core.theme);
const searchService = this.searchService.setup(core, {
@ -99,9 +92,6 @@ export class DataPublicPlugin
});
uiActions.registerTrigger(applyFilterTrigger);
uiActions.registerAction(
createFilterAction(queryService.filterManager, queryService.timefilter.timefilter, core.theme)
);
inspector.registerView(
getTableViewDescription(() => ({
@ -161,11 +151,6 @@ export class DataPublicPlugin
}))
);
uiActions.addTriggerAction(
APPLY_FILTER_TRIGGER,
uiActions.getAction(ACTION_GLOBAL_APPLY_FILTER)
);
const datatableUtilities = new DatatableUtilitiesService(search.aggs, dataViews, fieldFormats);
const dataServices = {
actions: {
@ -182,20 +167,7 @@ export class DataPublicPlugin
nowProvider: this.nowProvider,
};
const SearchBar = createSearchBar({
core,
data: dataServices,
storage: this.storage,
usageCollection: this.usageCollection,
});
return {
...dataServices,
ui: {
IndexPatternSelect: createIndexPatternSelect(dataViews),
SearchBar,
},
};
return dataServices;
}
public stop() {

View file

@ -14,3 +14,4 @@ export * from './timefilter';
export * from './saved_query';
export * from './persisted_log';
export * from './state_sync';
export type { QueryStringContract } from './query_string';

View file

@ -7,9 +7,5 @@
*/
export * from './add_to_query_log';
export * from './from_user';
export * from './get_default_query';
export * from './get_query_log';
export * from './match_pairs';
export * from './to_user';
export * from './to_user';

View file

@ -10,7 +10,7 @@ import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
import { IKibanaSearchResponse } from 'src/plugins/data/common';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
import { ShardFailureOpenModalButton } from '../../shard_failure_modal';
import { ThemeServiceStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
import { getNotifications } from '../../services';

View file

@ -59,3 +59,5 @@ export { handleResponse } from './fetch';
export type { SearchInterceptorDeps } from './search_interceptor';
export { SearchInterceptor } from './search_interceptor';
export * from './errors';
export { SearchService } from './search_service';

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import { setOverlays } from '../../services';
import { setOverlays } from '../services';
import { OverlayStart } from 'kibana/public';
export const openModal = jest.fn();

View file

@ -10,10 +10,9 @@ import React from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiButton, EuiTextAlign } from '@elastic/eui';
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { getOverlays } from '../../services';
import { ThemeServiceStart } from '../../../../../core/public';
import { toMountPoint } from '../../../../kibana_react/public';
import { getOverlays } from '../services';
import { ThemeServiceStart } from '../../../../core/public';
import { toMountPoint } from '../../../kibana_react/public';
import { ShardFailureModal } from './shard_failure_modal';
import { ShardFailureRequest } from './shard_failure_types';

View file

@ -6,7 +6,6 @@
* Side Public License, v 1.
*/
import React from 'react';
import { CoreStart } from 'src/core/public';
import { BfetchPublicSetup } from 'src/plugins/bfetch/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
@ -20,7 +19,6 @@ import { createFiltersFromRangeSelectAction, createFiltersFromValueClickAction }
import type { ISearchSetup, ISearchStart } from './search';
import { QuerySetup, QueryStart } from './query';
import { DataViewsContract } from './data_views';
import { IndexPatternSelectProps, StatefulSearchBarProps } from './ui';
import { UsageCollectionSetup, UsageCollectionStart } from '../../usage_collection/public';
import { Setup as InspectorSetup } from '../../inspector/public';
import { NowProviderPublicContract } from './now_provider';
@ -49,14 +47,6 @@ export interface DataPublicPluginSetup {
query: QuerySetup;
}
/**
* Data plugin prewired UI components
*/
export interface DataPublicPluginStartUi {
IndexPatternSelect: React.ComponentType<IndexPatternSelectProps>;
SearchBar: React.ComponentType<StatefulSearchBarProps>;
}
/**
* utilities to generate filters from action context
*/
@ -110,11 +100,6 @@ export interface DataPublicPluginStart {
* {@link QueryStart}
*/
query: QueryStart;
/**
* prewired UI components
* {@link DataPublicPluginStartUi}
*/
ui: DataPublicPluginStartUi;
nowProvider: NowProviderPublicContract;
}

View file

@ -1,143 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import FilterLabel from './filter_label';
import { render } from '@testing-library/react';
import { phraseFilter } from '../../../../stubs';
test('alias', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
},
};
const { container } = render(<FilterLabel filter={filter} />);
expect(container).toMatchInlineSnapshot(`
<div>
geo.coordinates in US
</div>
`);
});
test('negated alias', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
negate: true,
},
};
const { container } = render(<FilterLabel filter={filter} />);
expect(container).toMatchInlineSnapshot(`
<div>
<span
class="euiTextColor euiTextColor--danger"
>
NOT
</span>
geo.coordinates in US
</div>
`);
});
test('alias with warning status', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
negate: true,
},
};
const { container } = render(
<FilterLabel filter={filter} valueLabel={'Warning'} filterLabelStatus={'warn'} />
);
expect(container).toMatchInlineSnapshot(`
<div>
<span
class="euiTextColor euiTextColor--danger"
>
NOT
</span>
geo.coordinates in US
:
<span
class="globalFilterLabel__value"
>
Warning
</span>
</div>
`);
});
test('alias with error status', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
negate: true,
},
};
const { container } = render(
<FilterLabel filter={filter} valueLabel={'Error'} filterLabelStatus={'error'} />
);
expect(container).toMatchInlineSnapshot(`
<div>
<span
class="euiTextColor euiTextColor--danger"
>
NOT
</span>
geo.coordinates in US
:
<span
class="globalFilterLabel__value"
>
Error
</span>
</div>
`);
});
test('warning', () => {
const { container } = render(<FilterLabel filter={phraseFilter} valueLabel={'Warning'} />);
expect(container).toMatchInlineSnapshot(`
<div>
machine.os
:
<span
class="globalFilterLabel__value"
>
Warning
</span>
</div>
`);
});
test('error', () => {
const { container } = render(<FilterLabel filter={phraseFilter} valueLabel={'Error'} />);
expect(container).toMatchInlineSnapshot(`
<div>
machine.os
:
<span
class="globalFilterLabel__value"
>
Error
</span>
</div>
`);
});

View file

@ -1,15 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export type { IndexPatternSelectProps } from './index_pattern_select';
export { FilterLabel, FilterItem } from './filter_bar';
export type { QueryStringInputProps } from './query_string_input';
export { QueryStringInput } from './query_string_input';
export type { SearchBarProps, StatefulSearchBarProps } from './search_bar';
export { SearchBar } from './search_bar';
export { SuggestionsComponent } from './typeahead';

View file

@ -12,7 +12,7 @@
"server/**/*",
"config.ts",
"common/**/*.json",
"public/**/*.json"
"public/**/*.json",
],
"references": [
{ "path": "../../core/tsconfig.json" },

View file

@ -3,7 +3,7 @@
"version": "kibana",
"server": true,
"ui": true,
"requiredPlugins": ["management", "data", "urlForwarding", "dataViewFieldEditor", "dataViewEditor", "dataViews", "fieldFormats"],
"requiredPlugins": ["management", "data", "urlForwarding", "dataViewFieldEditor", "dataViewEditor", "dataViews", "fieldFormats", "unifiedSearch"],
"requiredBundles": ["kibanaReact", "kibanaUtils"],
"optionalPlugins": ["spaces"],
"owner": {

View file

@ -224,7 +224,7 @@ export class TestScript extends Component<TestScriptProps, TestScriptState> {
</EuiFormRow>
<div className="testScript__searchBar">
<this.context.services.data.ui.SearchBar
<this.context.services.unifiedSearch.ui.SearchBar
appName={'indexPatternManagement'}
showFilterBar={false}
showDatePicker={false}

View file

@ -40,7 +40,7 @@ export async function mountManagementSection(
) {
const [
{ application, chrome, uiSettings, notifications, overlays, http, docLinks, theme },
{ data, dataViewFieldEditor, dataViewEditor, dataViews, fieldFormats, spaces },
{ data, dataViewFieldEditor, dataViewEditor, dataViews, fieldFormats, unifiedSearch, spaces },
indexPatternManagementStart,
] = await getStartServices();
const canSave = dataViews.getCanSaveSync();
@ -55,6 +55,7 @@ export async function mountManagementSection(
uiSettings,
notifications,
overlays,
unifiedSearch,
http,
docLinks,
data,

View file

@ -11,6 +11,7 @@ import { coreMock } from '../../../core/public/mocks';
import { managementPluginMock } from '../../management/public/mocks';
import { urlForwardingPluginMock } from '../../url_forwarding/public/mocks';
import { dataPluginMock } from '../../data/public/mocks';
import { unifiedSearchPluginMock } from '../../unified_search/public/mocks';
import { indexPatternFieldEditorPluginMock } from '../../data_view_field_editor/public/mocks';
import { indexPatternEditorPluginMock } from '../../data_view_editor/public/mocks';
import { dataViewPluginMocks } from '../../data_views/public/mocks';
@ -60,6 +61,7 @@ const createIndexPatternManagmentContext = (): {
const data = dataPluginMock.createStartContract();
const dataViewFieldEditor = indexPatternFieldEditorPluginMock.createStartContract();
const dataViews = dataViewPluginMocks.createStartContract();
const unifiedSearch = unifiedSearchPluginMock.createStartContract();
return {
application,
@ -71,6 +73,7 @@ const createIndexPatternManagmentContext = (): {
docLinks,
data,
dataViews,
unifiedSearch,
dataViewFieldEditor,
indexPatternManagementStart: createStartContract(),
setBreadcrumbs: () => {},

View file

@ -17,6 +17,7 @@ import { IndexPatternFieldEditorStart } from '../../data_view_field_editor/publi
import { DataViewEditorStart } from '../../data_view_editor/public';
import { DataViewsPublicPluginStart } from '../../data_views/public';
import { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public';
import { UnifiedSearchPublicPluginStart } from '../../unified_search/public';
export interface IndexPatternManagementSetupDependencies {
management: ManagementSetup;
@ -30,6 +31,7 @@ export interface IndexPatternManagementStartDependencies {
dataViews: DataViewsPublicPluginStart;
fieldFormats: FieldFormatsStart;
spaces?: SpacesPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface

View file

@ -16,6 +16,7 @@ import {
ApplicationStart,
} from 'src/core/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from '../../unified_search/public';
import { ManagementAppMountParams } from '../../management/public';
import { IndexPatternManagementStart } from './index';
import { KibanaReactContextValue } from '../../kibana_react/public';
@ -34,6 +35,7 @@ export interface IndexPatternManagmentContext {
http: HttpSetup;
docLinks: DocLinksStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
dataViews: DataViewsPublicPluginStart;
dataViewFieldEditor: IndexPatternFieldEditorStart;
indexPatternManagementStart: IndexPatternManagementStart;

View file

@ -20,6 +20,7 @@
{ "path": "../es_ui_shared/tsconfig.json" },
{ "path": "../data_view_field_editor/tsconfig.json" },
{ "path": "../data_view_editor/tsconfig.json" },
{ "path": "../unified_search/tsconfig.json" },
{ "path": "../../../x-pack/plugins/spaces/tsconfig.json" }
]
}

View file

@ -9,6 +9,6 @@
"kibanaVersion": "kibana",
"server": false,
"ui": true,
"requiredPlugins": ["data", "expressions", "visDefaultEditor", "visualizations"],
"requiredPlugins": ["data", "expressions", "visDefaultEditor", "visualizations", "unifiedSearch"],
"requiredBundles": ["kibanaReact"]
}

View file

@ -9,7 +9,7 @@
import React, { ComponentType } from 'react';
import { injectI18n, InjectedIntlProps } from '@kbn/i18n-react';
import { EuiFormRow } from '@elastic/eui';
import { IndexPatternSelectProps } from 'src/plugins/data/public';
import { IndexPatternSelectProps } from '../../../../unified_search/public';
export type IndexPatternSelectFormRowUiProps = InjectedIntlProps & {
onChange: (opt: any) => void;

View file

@ -14,7 +14,7 @@ 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 { IndexPatternSelectProps } from '../../../../data/public';
import { IndexPatternSelectProps } from '../../../../unified_search/public';
import { DataView, DataViewField } from '../../../../data_views/public';
import { InputControlVisDependencies } from '../../plugin';
@ -93,9 +93,9 @@ export class ListControlEditor extends PureComponent<
};
async getIndexPatternSelect() {
const [, { data }] = await this.props.deps.core.getStartServices();
const [, { unifiedSearch }] = await this.props.deps.core.getStartServices();
this.setState({
IndexPatternSelect: data.ui.IndexPatternSelect,
IndexPatternSelect: unifiedSearch.ui.IndexPatternSelect,
});
}

View file

@ -14,7 +14,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 { IndexPatternSelectProps } from '../../../../data/public';
import { IndexPatternSelectProps } from '../../../../unified_search/public';
import { DataView, DataViewField } from '../../../../data_views/public';
import { InputControlVisDependencies } from '../../plugin';
@ -53,9 +53,9 @@ export class RangeControlEditor extends Component<
}
async getIndexPatternSelect() {
const [, { data }] = await this.props.deps.core.getStartServices();
const [, { unifiedSearch }] = await this.props.deps.core.getStartServices();
this.setState({
IndexPatternSelect: data.ui.IndexPatternSelect,
IndexPatternSelect: unifiedSearch.ui.IndexPatternSelect,
});
}

View file

@ -9,6 +9,7 @@
import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'kibana/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from 'src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from 'src/plugins/unified_search/public';
import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public';
import { VisualizationsSetup, VisualizationsStart } from '../../visualizations/public';
import { createInputControlVisFn } from './input_control_fn';
@ -40,6 +41,7 @@ export interface InputControlVisPluginStartDependencies {
expressions: ReturnType<ExpressionsPublicPlugin['start']>;
visualizations: VisualizationsStart;
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}
/** @internal */

View file

@ -31,15 +31,17 @@ export const getDepsMock = ({
search: {
searchSource,
},
ui: {
IndexPatternSelect: () => (<div />) as any,
},
indexPatterns: {
get: () => ({
fields,
}),
},
},
unifiedSearch: {
ui: {
IndexPatternSelect: () => (<div />) as any,
},
},
},
]),
},

View file

@ -17,5 +17,6 @@
{ "path": "../expressions/tsconfig.json" },
{ "path": "../visualizations/tsconfig.json" },
{ "path": "../vis_default_editor/tsconfig.json" },
{ "path": "../unified_search/tsconfig.json" }
]
}

View file

@ -7,6 +7,6 @@
"version": "kibana",
"server": false,
"ui": true,
"requiredPlugins": ["data"],
"requiredPlugins": ["unifiedSearch"],
"requiredBundles": ["kibanaReact"]
}

View file

@ -32,13 +32,13 @@ export class NavigationPublicPlugin
public start(
{ i18n }: CoreStart,
{ data }: NavigationPluginStartDependencies
{ unifiedSearch }: NavigationPluginStartDependencies
): NavigationPublicPluginStart {
const extensions = this.topNavMenuExtensionsRegistry.getAll();
return {
ui: {
TopNavMenu: createTopNav(data, extensions, i18n),
TopNavMenu: createTopNav(unifiedSearch, extensions, i18n),
},
};
}

View file

@ -8,12 +8,12 @@
import React from 'react';
import { I18nStart } from 'kibana/public';
import { DataPublicPluginStart } from 'src/plugins/data/public';
import { UnifiedSearchPublicPluginStart } from 'src/plugins/unified_search/public';
import { TopNavMenuProps, TopNavMenu } from './top_nav_menu';
import { RegisteredTopNavMenuData } from './top_nav_menu_data';
export function createTopNav(
data: DataPublicPluginStart,
unifiedSearch: UnifiedSearchPublicPluginStart,
extraConfig: RegisteredTopNavMenuData[],
i18n: I18nStart
) {
@ -25,7 +25,7 @@ export function createTopNav(
return (
<i18n.Context>
<TopNavMenu {...props} data={data} config={config} />
<TopNavMenu {...props} unifiedSearch={unifiedSearch} config={config} />
</i18n.Context>
);
};

View file

@ -13,12 +13,13 @@ import { MountPoint } from 'kibana/public';
import { TopNavMenu } from './top_nav_menu';
import { TopNavMenuData } from './top_nav_menu_data';
import { shallowWithIntl, mountWithIntl } from '@kbn/test-jest-helpers';
import type { UnifiedSearchPublicPluginStart } from '../../../unified_search/public';
const dataShim = {
const unifiedSearch = {
ui: {
SearchBar: () => <div className="searchBar" />,
},
};
} as unknown as UnifiedSearchPublicPluginStart;
describe('TopNavMenu', () => {
const WRAPPER_SELECTOR = '.kbnTopNavMenu__wrapper';
@ -72,7 +73,7 @@ describe('TopNavMenu', () => {
it('Should render search bar', () => {
const component = shallowWithIntl(
<TopNavMenu appName={'test'} showSearchBar={true} data={dataShim as any} />
<TopNavMenu appName={'test'} showSearchBar={true} unifiedSearch={unifiedSearch} />
);
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(0);
@ -81,7 +82,12 @@ describe('TopNavMenu', () => {
it('Should render menu items and search bar', () => {
const component = shallowWithIntl(
<TopNavMenu appName={'test'} config={menuItems} showSearchBar={true} data={dataShim as any} />
<TopNavMenu
appName={'test'}
config={menuItems}
showSearchBar={true}
unifiedSearch={unifiedSearch}
/>
);
expect(component.find(WRAPPER_SELECTOR).length).toBe(1);
expect(component.find(TOP_NAV_ITEM_SELECTOR).length).toBe(menuItems.length);
@ -94,7 +100,7 @@ describe('TopNavMenu', () => {
appName={'test'}
config={menuItems}
showSearchBar={true}
data={dataShim as any}
unifiedSearch={unifiedSearch}
className={'myCoolClass'}
/>
);
@ -142,7 +148,7 @@ describe('TopNavMenu', () => {
appName={'test'}
config={menuItems}
showSearchBar={true}
data={dataShim as any}
unifiedSearch={unifiedSearch}
setMenuMountPoint={setMountPoint}
/>
);

View file

@ -12,11 +12,8 @@ import classNames from 'classnames';
import { MountPoint } from '../../../../core/public';
import { MountPointPortal } from '../../../kibana_react/public';
import {
StatefulSearchBarProps,
DataPublicPluginStart,
SearchBarProps,
} from '../../../data/public';
import { UnifiedSearchPublicPluginStart } from '../../../unified_search/public';
import { StatefulSearchBarProps, SearchBarProps } from '../../../unified_search/public';
import { TopNavMenuData } from './top_nav_menu_data';
import { TopNavMenuItem } from './top_nav_menu_item';
@ -29,7 +26,7 @@ export type TopNavMenuProps = StatefulSearchBarProps &
showQueryInput?: boolean;
showDatePicker?: boolean;
showFilterBar?: boolean;
data?: DataPublicPluginStart;
unifiedSearch?: UnifiedSearchPublicPluginStart;
className?: string;
/**
* If provided, the menu part of the component will be rendered as a portal inside the given mount point.
@ -64,7 +61,7 @@ export type TopNavMenuProps = StatefulSearchBarProps &
export function TopNavMenu(props: TopNavMenuProps): ReactElement | null {
const { config, badges, showSearchBar, ...searchBarProps } = props;
if ((!config || config.length === 0) && (!showSearchBar || !props.data)) {
if ((!config || config.length === 0) && (!showSearchBar || !props.unifiedSearch)) {
return null;
}
@ -102,8 +99,8 @@ export function TopNavMenu(props: TopNavMenuProps): ReactElement | null {
function renderSearchBar(): ReactElement | null {
// Validate presense of all required fields
if (!showSearchBar || !props.data) return null;
const { SearchBar } = props.data.ui;
if (!showSearchBar || !props.unifiedSearch) return null;
const { SearchBar } = props.unifiedSearch.ui;
return <SearchBar {...searchBarProps} />;
}

View file

@ -7,7 +7,7 @@
*/
import { TopNavMenuProps, TopNavMenuExtensionsRegistrySetup } from './top_nav_menu';
import { DataPublicPluginStart } from '../../data/public';
import { UnifiedSearchPublicPluginStart } from '../../unified_search/public';
export interface NavigationPublicPluginSetup {
registerMenuItem: TopNavMenuExtensionsRegistrySetup['register'];
@ -20,5 +20,5 @@ export interface NavigationPublicPluginStart {
}
export interface NavigationPluginStartDependencies {
data: DataPublicPluginStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}

View file

@ -11,5 +11,6 @@
{ "path": "../../core/tsconfig.json" },
{ "path": "../kibana_react/tsconfig.json" },
{ "path": "../data/tsconfig.json" },
{ "path": "../unified_search/tsconfig.json" }
]
}

View file

@ -0,0 +1,12 @@
# unifiedSearch
Contains all the components of Kibana's unified search experience. Specifically:
- UI components for rendering unified search bar;
- Current state of the search (`data view`, `applied filters, …);
- Saved queries management.
---
## Development
See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({});
export type ConfigSchema = TypeOf<typeof configSchema>;

View file

@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/src/plugins/unified_search'],
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/src/plugins/unified_search',
coverageReporters: ['text', 'html'],
collectCoverageFrom: ['<rootDir>/src/plugins/unified_search/public/**/*.{ts,tsx}'],
};

View file

@ -0,0 +1,14 @@
{
"id": "unifiedSearch",
"version": "1.0.0",
"description": "Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience.",
"kibanaVersion": "kibana",
"owner": {
"name": "Unified Search",
"githubTeam": "kibana-app-services"
},
"server": false,
"ui": true,
"requiredPlugins": ["dataViews", "data", "uiActions"],
"requiredBundles": ["kibanaUtils", "kibanaReact", "data"]
}

View file

@ -11,8 +11,8 @@ import { ThemeServiceSetup } from 'kibana/public';
import { toMountPoint } from '../../../kibana_react/public';
import { Action, createAction, IncompatibleActionError } from '../../../ui_actions/public';
import { getOverlays, getIndexPatterns } from '../services';
import { applyFiltersPopover } from '../ui/apply_filters';
import { Filter, FilterManager, TimefilterContract, esFilters } from '..';
import { applyFiltersPopover } from '../apply_filters';
import { Filter, FilterManager, TimefilterContract, esFilters } from '../../../data/public';
export const ACTION_GLOBAL_APPLY_FILTER = 'ACTION_GLOBAL_APPLY_FILTER';
@ -42,7 +42,7 @@ export function createFilterAction(
order: 100,
getIconType: () => 'filter',
getDisplayName: () => {
return i18n.translate('data.filter.applyFilterActionTitle', {
return i18n.translate('unifiedSearch.filter.applyFilterActionTitle', {
defaultMessage: 'Apply filter to current view',
});
},

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export type { ApplyGlobalFilterActionContext } from './apply_filter_action';
export { ACTION_GLOBAL_APPLY_FILTER } from './apply_filter_action';

View file

@ -19,10 +19,9 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { Component } from 'react';
import { IIndexPattern } from '../..';
import { Filter } from '../../../common';
import { getDisplayValueFromFilter, mapAndFlattenFilters } from '../../../data/public';
import { FilterLabel } from '../filter_bar';
import { mapAndFlattenFilters, getDisplayValueFromFilter } from '../../query';
import { Filter, IIndexPattern } from '../../../data/common';
interface Props {
filters: Filter[];
@ -80,7 +79,7 @@ export default class ApplyFiltersPopoverContent extends Component<Props, State>
<EuiModalHeader>
<EuiModalHeaderTitle>
<FormattedMessage
id="data.filter.applyFilters.popupHeader"
id="unifiedSearch.filter.applyFilters.popupHeader"
defaultMessage="Select filters to apply"
/>
</EuiModalHeaderTitle>
@ -91,13 +90,13 @@ export default class ApplyFiltersPopoverContent extends Component<Props, State>
<EuiModalFooter>
<EuiButtonEmpty onClick={this.props.onCancel}>
<FormattedMessage
id="data.filter.applyFiltersPopup.cancelButtonLabel"
id="unifiedSearch.filter.applyFiltersPopup.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
<EuiButton onClick={this.onSubmit} data-test-subj="applyFiltersPopoverButton" fill>
<FormattedMessage
id="data.filter.applyFiltersPopup.saveButtonLabel"
id="unifiedSearch.filter.applyFiltersPopup.saveButtonLabel"
defaultMessage="Apply"
/>
</EuiButton>

View file

@ -7,7 +7,7 @@
*/
import React from 'react';
import { IIndexPattern, Filter } from '../..';
import { IIndexPattern, Filter } from '../../../data/common';
type CancelFnType = () => void;
type SubmitFnType = (filters: Filter[]) => void;

View file

@ -25,10 +25,9 @@ import { METRIC_TYPE } from '@kbn/analytics';
import { FilterEditor } from './filter_editor';
import { FILTER_EDITOR_WIDTH, FilterItem } from './filter_item';
import { FilterOptions } from './filter_options';
import { useKibana } from '../../../../kibana_react/public';
import { IDataPluginServices, IIndexPattern } from '../..';
import { UI_SETTINGS } from '../../../common';
import { useKibana } from '../../../kibana_react/public';
import { IIndexPattern, UI_SETTINGS } from '../../../data/common';
import { IDataPluginServices } from '../../../data/public';
export interface Props {
filters: Filter[];
@ -89,7 +88,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
>
+{' '}
<FormattedMessage
id="data.filter.filterBar.addFilterButtonLabel"
id="unifiedSearch.filter.filterBar.addFilterButtonLabel"
defaultMessage="Add filter"
/>
</EuiButtonEmpty>
@ -228,4 +227,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
);
});
export const FilterBar = injectI18n(FilterBarUI);
const FilterBar = injectI18n(FilterBarUI);
// Needed for React.lazy
// eslint-disable-next-line import/no-default-export
export default FilterBar;

View file

@ -10,8 +10,8 @@ import { registerTestBed, TestBed } from '@kbn/test-jest-helpers';
import { FilterEditor, Props } from '.';
import React from 'react';
jest.mock('../../../../../kibana_react/public', () => {
const original = jest.requireActual('../../../../../kibana_react/public');
jest.mock('../../../../kibana_react/public', () => {
const original = jest.requireActual('../../../../kibana_react/public');
return {
...original,

View file

@ -44,9 +44,9 @@ import { Operator } from './lib/filter_operators';
import { PhraseValueInput } from './phrase_value_input';
import { PhrasesValuesInput } from './phrases_values_input';
import { RangeValueInput } from './range_value_input';
import { getIndexPatternFromFilter } from '../../../query';
import { IIndexPattern, IFieldType } from '../../..';
import { CodeEditor } from '../../../../../kibana_react/public';
import { IIndexPattern, IFieldType } from '../../../../data/common';
import { getIndexPatternFromFilter } from '../../../../data/public';
import { CodeEditor } from '../../../../kibana_react/public';
export interface Props {
filter: Filter;
@ -90,7 +90,7 @@ class FilterEditorUI extends Component<Props, State> {
<EuiFlexGroup alignItems="baseline" responsive={false}>
<EuiFlexItem>
<FormattedMessage
id="data.filter.filterEditor.editFilterPopupTitle"
id="unifiedSearch.filter.filterEditor.editFilterPopupTitle"
defaultMessage="Edit filter"
/>
</EuiFlexItem>
@ -103,12 +103,12 @@ class FilterEditorUI extends Component<Props, State> {
>
{this.state.isCustomEditorOpen ? (
<FormattedMessage
id="data.filter.filterEditor.editFilterValuesButtonLabel"
id="unifiedSearch.filter.filterEditor.editFilterValuesButtonLabel"
defaultMessage="Edit filter values"
/>
) : (
<FormattedMessage
id="data.filter.filterEditor.editQueryDslButtonLabel"
id="unifiedSearch.filter.filterEditor.editQueryDslButtonLabel"
defaultMessage="Edit as Query DSL"
/>
)}
@ -129,7 +129,7 @@ class FilterEditorUI extends Component<Props, State> {
id="filterEditorCustomLabelSwitch"
data-test-subj="createCustomLabel"
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.createCustomLabelSwitchLabel',
id: 'unifiedSearch.filter.filterEditor.createCustomLabelSwitchLabel',
defaultMessage: 'Create custom label?',
})}
checked={this.state.useCustomLabel}
@ -141,7 +141,7 @@ class FilterEditorUI extends Component<Props, State> {
<EuiSpacer size="m" />
<EuiFormRow
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.createCustomLabelInputLabel',
id: 'unifiedSearch.filter.filterEditor.createCustomLabelInputLabel',
defaultMessage: 'Custom label',
})}
fullWidth
@ -166,7 +166,7 @@ class FilterEditorUI extends Component<Props, State> {
data-test-subj="saveFilter"
>
<FormattedMessage
id="data.filter.filterEditor.saveButtonLabel"
id="unifiedSearch.filter.filterEditor.saveButtonLabel"
defaultMessage="Save"
/>
</EuiButton>
@ -178,7 +178,7 @@ class FilterEditorUI extends Component<Props, State> {
data-test-subj="cancelSaveFilter"
>
<FormattedMessage
id="data.filter.filterEditor.cancelButtonLabel"
id="unifiedSearch.filter.filterEditor.cancelButtonLabel"
defaultMessage="Cancel"
/>
</EuiButtonEmpty>
@ -212,14 +212,14 @@ class FilterEditorUI extends Component<Props, State> {
<EuiFormRow
fullWidth
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.indexPatternSelectLabel',
id: 'unifiedSearch.filter.filterEditor.indexPatternSelectLabel',
defaultMessage: 'Index Pattern',
})}
>
<IndexPatternComboBox
fullWidth
placeholder={this.props.intl.formatMessage({
id: 'data.filter.filterBar.indexPatternSelectPlaceholder',
id: 'unifiedSearch.filter.filterBar.indexPatternSelectPlaceholder',
defaultMessage: 'Select an index pattern',
})}
options={this.props.indexPatterns}
@ -259,7 +259,7 @@ class FilterEditorUI extends Component<Props, State> {
<EuiFormRow
fullWidth
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.fieldSelectLabel',
id: 'unifiedSearch.filter.filterEditor.fieldSelectLabel',
defaultMessage: 'Field',
})}
>
@ -268,7 +268,7 @@ class FilterEditorUI extends Component<Props, State> {
id="fieldInput"
isDisabled={!selectedIndexPattern}
placeholder={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.fieldSelectPlaceholder',
id: 'unifiedSearch.filter.filterEditor.fieldSelectPlaceholder',
defaultMessage: 'Select a field first',
})}
options={fields}
@ -290,7 +290,7 @@ class FilterEditorUI extends Component<Props, State> {
<EuiFormRow
fullWidth
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.operatorSelectLabel',
id: 'unifiedSearch.filter.filterEditor.operatorSelectLabel',
defaultMessage: 'Operator',
})}
>
@ -300,11 +300,11 @@ class FilterEditorUI extends Component<Props, State> {
placeholder={
selectedField
? this.props.intl.formatMessage({
id: 'data.filter.filterEditor.operatorSelectPlaceholderSelect',
id: 'unifiedSearch.filter.filterEditor.operatorSelectPlaceholderSelect',
defaultMessage: 'Select',
})
: this.props.intl.formatMessage({
id: 'data.filter.filterEditor.operatorSelectPlaceholderWaiting',
id: 'unifiedSearch.filter.filterEditor.operatorSelectPlaceholderWaiting',
defaultMessage: 'Waiting',
})
}
@ -324,7 +324,7 @@ class FilterEditorUI extends Component<Props, State> {
return (
<EuiFormRow
fullWidth
label={i18n.translate('data.filter.filterEditor.queryDslLabel', {
label={i18n.translate('unifiedSearch.filter.filterEditor.queryDslLabel', {
defaultMessage: 'Elasticsearch Query DSL',
})}
>
@ -335,7 +335,7 @@ class FilterEditorUI extends Component<Props, State> {
value={this.state.queryDsl}
onChange={this.onQueryDslChange}
data-test-subj="customEditorInput"
aria-label={i18n.translate('data.filter.filterEditor.queryDslAriaLabel', {
aria-label={i18n.translate('unifiedSearch.filter.filterEditor.queryDslAriaLabel', {
defaultMessage: 'Elasticsearch Query DSL editor',
})}
/>

View file

@ -0,0 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`alias 1`] = `
<div>
geo.coordinates in US
</div>
`;
exports[`alias with error status 1`] = `
<div>
<span
class="euiTextColor euiTextColor--danger"
>
NOT
</span>
geo.coordinates in US
:
<span
class="globalFilterLabel__value"
>
Error
</span>
</div>
`;
exports[`alias with warning status 1`] = `
<div>
<span
class="euiTextColor euiTextColor--danger"
>
NOT
</span>
geo.coordinates in US
:
<span
class="globalFilterLabel__value"
>
Warning
</span>
</div>
`;
exports[`error 1`] = `
<div>
machine.os
:
<span
class="globalFilterLabel__value"
>
Error
</span>
</div>
`;
exports[`warning 1`] = `
<div>
machine.os
:
<span
class="globalFilterLabel__value"
>
Warning
</span>
</div>
`;

View file

@ -13,8 +13,8 @@ import {
rangeFilter,
stubIndexPattern,
stubFields,
} from '../../../../stubs';
import { toggleFilterNegated } from '../../../../../common';
} from '../../../../../data/common/stubs';
import { toggleFilterNegated } from '../../../../../data/common';
import {
getFieldFromFilter,
getFilterableFields,

View file

@ -11,7 +11,7 @@ import { Filter, FieldFilter } from '@kbn/es-query';
import { ES_FIELD_TYPES } from '@kbn/field-types';
import isSemverValid from 'semver/functions/valid';
import { FILTER_OPERATORS, Operator } from './filter_operators';
import { isFilterable, IIndexPattern, IFieldType, IpAddress } from '../../../../../common';
import { isFilterable, IIndexPattern, IFieldType, IpAddress } from '../../../../../data/common';
export function getFieldFromFilter(filter: FieldFilter, indexPattern: IIndexPattern) {
return indexPattern.fields.find((field) => field.name === filter.meta.key);

View file

@ -0,0 +1,64 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import FilterLabel from './filter_label';
import { render } from '@testing-library/react';
import { phraseFilter } from '../../../../../data/common/stubs';
test('alias', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
},
};
const { container } = render(<FilterLabel filter={filter} />);
expect(container).toMatchSnapshot();
});
test('alias with warning status', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
negate: true,
},
};
const { container } = render(
<FilterLabel filter={filter} valueLabel={'Warning'} filterLabelStatus={'warn'} />
);
expect(container).toMatchSnapshot();
});
test('alias with error status', () => {
const filter = {
...phraseFilter,
meta: {
...phraseFilter.meta,
alias: 'geo.coordinates in US',
negate: true,
},
};
const { container } = render(
<FilterLabel filter={filter} valueLabel={'Error'} filterLabelStatus={'error'} />
);
expect(container).toMatchSnapshot();
});
test('warning', () => {
const { container } = render(<FilterLabel filter={phraseFilter} valueLabel={'Warning'} />);
expect(container).toMatchSnapshot();
});
test('error', () => {
const { container } = render(<FilterLabel filter={phraseFilter} valueLabel={'Error'} />);
expect(container).toMatchSnapshot();
});

View file

@ -10,7 +10,7 @@ import React, { Fragment } from 'react';
import { EuiTextColor } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { existsOperator, isOneOfOperator } from './filter_operators';
import { Filter, FILTERS } from '../../../../../common';
import { Filter, FILTERS } from '../../../../../data/common';
import type { FilterLabelStatus } from '../../filter_item';
export interface FilterLabelProps {
@ -29,7 +29,7 @@ export default function FilterLabel({
hideAlias,
}: FilterLabelProps) {
const prefixText = filter.meta.negate
? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', {
? ` ${i18n.translate('unifiedSearch.filter.filterBar.negatedFilterPrefix', {
defaultMessage: 'NOT ',
})}`
: '';

View file

@ -9,7 +9,7 @@
import { i18n } from '@kbn/i18n';
import { FILTERS } from '@kbn/es-query';
import { ES_FIELD_TYPES } from '@kbn/field-types';
import { IFieldType } from '../../../../../../data_views/common';
import { IFieldType } from '../../../../../data_views/common';
export interface Operator {
message: string;
@ -29,7 +29,7 @@ export interface Operator {
}
export const isOperator = {
message: i18n.translate('data.filter.filterEditor.isOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isOperatorOptionLabel', {
defaultMessage: 'is',
}),
type: FILTERS.PHRASE,
@ -37,7 +37,7 @@ export const isOperator = {
};
export const isNotOperator = {
message: i18n.translate('data.filter.filterEditor.isNotOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isNotOperatorOptionLabel', {
defaultMessage: 'is not',
}),
type: FILTERS.PHRASE,
@ -45,7 +45,7 @@ export const isNotOperator = {
};
export const isOneOfOperator = {
message: i18n.translate('data.filter.filterEditor.isOneOfOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isOneOfOperatorOptionLabel', {
defaultMessage: 'is one of',
}),
type: FILTERS.PHRASES,
@ -54,7 +54,7 @@ export const isOneOfOperator = {
};
export const isNotOneOfOperator = {
message: i18n.translate('data.filter.filterEditor.isNotOneOfOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isNotOneOfOperatorOptionLabel', {
defaultMessage: 'is not one of',
}),
type: FILTERS.PHRASES,
@ -63,7 +63,7 @@ export const isNotOneOfOperator = {
};
export const isBetweenOperator = {
message: i18n.translate('data.filter.filterEditor.isBetweenOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isBetweenOperatorOptionLabel', {
defaultMessage: 'is between',
}),
type: FILTERS.RANGE,
@ -79,7 +79,7 @@ export const isBetweenOperator = {
};
export const isNotBetweenOperator = {
message: i18n.translate('data.filter.filterEditor.isNotBetweenOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.isNotBetweenOperatorOptionLabel', {
defaultMessage: 'is not between',
}),
type: FILTERS.RANGE,
@ -95,7 +95,7 @@ export const isNotBetweenOperator = {
};
export const existsOperator = {
message: i18n.translate('data.filter.filterEditor.existsOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.existsOperatorOptionLabel', {
defaultMessage: 'exists',
}),
type: FILTERS.EXISTS,
@ -103,7 +103,7 @@ export const existsOperator = {
};
export const doesNotExistOperator = {
message: i18n.translate('data.filter.filterEditor.doesNotExistOperatorOptionLabel', {
message: i18n.translate('unifiedSearch.filter.filterEditor.doesNotExistOperatorOptionLabel', {
defaultMessage: 'does not exist',
}),
type: FILTERS.EXISTS,

View file

@ -9,9 +9,9 @@
import React from 'react';
import { debounce } from 'lodash';
import { withKibana, KibanaReactContextValue } from '../../../../../kibana_react/public';
import { IDataPluginServices, IIndexPattern, IFieldType } from '../../..';
import { UI_SETTINGS } from '../../../../common';
import { withKibana, KibanaReactContextValue } from '../../../../kibana_react/public';
import { IIndexPattern, IFieldType, UI_SETTINGS } from '../../../../data/common';
import { IDataPluginServices } from '../../../../data/public';
export interface PhraseSuggestorProps {
kibana: KibanaReactContextValue<IDataPluginServices>;

View file

@ -13,7 +13,7 @@ import React from 'react';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import { PhraseSuggestorUI, PhraseSuggestorProps } from './phrase_suggestor';
import { ValueInputType } from './value_input_type';
import { withKibana } from '../../../../../kibana_react/public';
import { withKibana } from '../../../../kibana_react/public';
interface Props extends PhraseSuggestorProps {
value?: string;
@ -28,7 +28,7 @@ class PhraseValueInputUI extends PhraseSuggestorUI<Props> {
<EuiFormRow
fullWidth={this.props.fullWidth}
label={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.valueInputLabel',
id: 'unifiedSearch.filter.filterEditor.valueInputLabel',
defaultMessage: 'Value',
})}
>
@ -38,7 +38,7 @@ class PhraseValueInputUI extends PhraseSuggestorUI<Props> {
<ValueInputType
fullWidth={this.props.fullWidth}
placeholder={this.props.intl.formatMessage({
id: 'data.filter.filterEditor.valueInputPlaceholder',
id: 'unifiedSearch.filter.filterEditor.valueInputPlaceholder',
defaultMessage: 'Enter a value',
})}
value={this.props.value}
@ -60,7 +60,7 @@ class PhraseValueInputUI extends PhraseSuggestorUI<Props> {
<StringComboBox
fullWidth={fullWidth}
placeholder={intl.formatMessage({
id: 'data.filter.filterEditor.valueSelectPlaceholder',
id: 'unifiedSearch.filter.filterEditor.valueSelectPlaceholder',
defaultMessage: 'Select a value',
})}
options={options}

View file

@ -12,7 +12,7 @@ import { uniq } from 'lodash';
import React from 'react';
import { GenericComboBox, GenericComboBoxProps } from './generic_combo_box';
import { PhraseSuggestorUI, PhraseSuggestorProps } from './phrase_suggestor';
import { withKibana } from '../../../../../kibana_react/public';
import { withKibana } from '../../../../kibana_react/public';
interface Props extends PhraseSuggestorProps {
values?: string[];
@ -30,14 +30,14 @@ class PhrasesValuesInputUI extends PhraseSuggestorUI<Props> {
<EuiFormRow
fullWidth={fullWidth}
label={intl.formatMessage({
id: 'data.filter.filterEditor.valuesSelectLabel',
id: 'unifiedSearch.filter.filterEditor.valuesSelectLabel',
defaultMessage: 'Values',
})}
>
<StringComboBox
fullWidth={fullWidth}
placeholder={intl.formatMessage({
id: 'data.filter.filterEditor.valuesSelectPlaceholder',
id: 'unifiedSearch.filter.filterEditor.valuesSelectPlaceholder',
defaultMessage: 'Select values',
})}
options={options}

View file

@ -11,8 +11,8 @@ import { EuiFormControlLayoutDelimited } from '@elastic/eui';
import { InjectedIntl, injectI18n } from '@kbn/i18n-react';
import { get } from 'lodash';
import React from 'react';
import { useKibana } from '../../../../../kibana_react/public';
import { IFieldType } from '../../..';
import { useKibana } from '../../../../kibana_react/public';
import { IFieldType } from '../../../../data/common';
import { ValueInputType } from './value_input_type';
interface RangeParams {
@ -62,7 +62,7 @@ function RangeValueInputUI(props: Props) {
<EuiFormControlLayoutDelimited
fullWidth={props.fullWidth}
aria-label={props.intl.formatMessage({
id: 'data.filter.filterEditor.rangeInputLabel',
id: 'unifiedSearch.filter.filterEditor.rangeInputLabel',
defaultMessage: 'Range',
})}
startControl={
@ -75,7 +75,7 @@ function RangeValueInputUI(props: Props) {
onFromChange(formatDateChange(value));
}}
placeholder={props.intl.formatMessage({
id: 'data.filter.filterEditor.rangeStartInputPlaceholder',
id: 'unifiedSearch.filter.filterEditor.rangeStartInputPlaceholder',
defaultMessage: 'Start of the range',
})}
/>
@ -90,7 +90,7 @@ function RangeValueInputUI(props: Props) {
onToChange(formatDateChange(value));
}}
placeholder={props.intl.formatMessage({
id: 'data.filter.filterEditor.rangeEndInputPlaceholder',
id: 'unifiedSearch.filter.filterEditor.rangeEndInputPlaceholder',
defaultMessage: 'End of the range',
})}
/>

View file

@ -11,7 +11,7 @@ import { InjectedIntl, injectI18n } from '@kbn/i18n-react';
import { isEmpty } from 'lodash';
import React, { Component } from 'react';
import { validateParams } from './lib/filter_editor_utils';
import { IFieldType } from '../../../../../data_views/common';
import { IFieldType } from '../../../../data_views/common';
interface Props {
value?: string | number;
@ -94,14 +94,14 @@ class ValueInputTypeUI extends Component<Props> {
{
value: 'true',
text: this.props.intl.formatMessage({
id: 'data.filter.filterEditor.trueOptionLabel',
id: 'unifiedSearch.filter.filterEditor.trueOptionLabel',
defaultMessage: 'true',
}),
},
{
value: 'false',
text: this.props.intl.formatMessage({
id: 'data.filter.filterEditor.falseOptionLabel',
id: 'unifiedSearch.filter.filterEditor.falseOptionLabel',
defaultMessage: 'false',
}),
},

View file

@ -20,9 +20,9 @@ import React, { MouseEvent, useState, useEffect, HTMLAttributes } from 'react';
import { IUiSettingsClient } from 'src/core/public';
import { FilterEditor } from './filter_editor';
import { FilterView } from './filter_view';
import { IIndexPattern } from '../..';
import { getDisplayValueFromFilter, getIndexPatternFromFilter } from '../../query';
import { getIndexPatterns } from '../../services';
import { IIndexPattern } from '../../../data/common';
import { getIndexPatternFromFilter, getDisplayValueFromFilter } from '../../../data/public';
import { getIndexPatterns } from '../services';
type PanelOptions = 'pinFilter' | 'editFilter' | 'negateFilter' | 'disableFilter' | 'deleteFilter';
@ -164,11 +164,11 @@ export function FilterItem(props: FilterItemProps) {
{
name: isFilterPinned(filter)
? props.intl.formatMessage({
id: 'data.filter.filterBar.unpinFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.unpinFilterButtonLabel',
defaultMessage: 'Unpin',
})
: props.intl.formatMessage({
id: 'data.filter.filterBar.pinFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.pinFilterButtonLabel',
defaultMessage: 'Pin across all apps',
}),
icon: 'pin',
@ -180,7 +180,7 @@ export function FilterItem(props: FilterItemProps) {
},
{
name: props.intl.formatMessage({
id: 'data.filter.filterBar.editFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.editFilterButtonLabel',
defaultMessage: 'Edit filter',
}),
icon: 'pencil',
@ -190,11 +190,11 @@ export function FilterItem(props: FilterItemProps) {
{
name: negate
? props.intl.formatMessage({
id: 'data.filter.filterBar.includeFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.includeFilterButtonLabel',
defaultMessage: 'Include results',
})
: props.intl.formatMessage({
id: 'data.filter.filterBar.excludeFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.excludeFilterButtonLabel',
defaultMessage: 'Exclude results',
}),
icon: negate ? 'plusInCircle' : 'minusInCircle',
@ -207,11 +207,11 @@ export function FilterItem(props: FilterItemProps) {
{
name: disabled
? props.intl.formatMessage({
id: 'data.filter.filterBar.enableFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.enableFilterButtonLabel',
defaultMessage: 'Re-enable',
})
: props.intl.formatMessage({
id: 'data.filter.filterBar.disableFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.disableFilterButtonLabel',
defaultMessage: 'Temporarily disable',
}),
icon: `${disabled ? 'eye' : 'eyeClosed'}`,
@ -223,7 +223,7 @@ export function FilterItem(props: FilterItemProps) {
},
{
name: props.intl.formatMessage({
id: 'data.filter.filterBar.deleteFilterButtonLabel',
id: 'unifiedSearch.filter.filterBar.deleteFilterButtonLabel',
defaultMessage: 'Delete',
}),
icon: 'trash',
@ -298,12 +298,12 @@ export function FilterItem(props: FilterItemProps) {
if (indexPatternExists === false) {
label.status = FILTER_ITEM_ERROR;
label.title = props.intl.formatMessage({
id: 'data.filter.filterBar.labelErrorText',
id: 'unifiedSearch.filter.filterBar.labelErrorText',
defaultMessage: `Error`,
});
label.message = props.intl.formatMessage(
{
id: 'data.filter.filterBar.labelErrorInfo',
id: 'unifiedSearch.filter.filterBar.labelErrorInfo',
defaultMessage: 'Index pattern {indexPattern} not found',
},
{
@ -316,7 +316,7 @@ export function FilterItem(props: FilterItemProps) {
} catch (e) {
label.status = FILTER_ITEM_ERROR;
label.title = props.intl.formatMessage({
id: 'data.filter.filterBar.labelErrorText',
id: 'unifiedSearch.filter.filterBar.labelErrorText',
defaultMessage: `Error`,
});
label.message = e.message;
@ -324,12 +324,12 @@ export function FilterItem(props: FilterItemProps) {
} else {
label.status = FILTER_ITEM_WARNING;
label.title = props.intl.formatMessage({
id: 'data.filter.filterBar.labelWarningText',
id: 'unifiedSearch.filter.filterBar.labelWarningText',
defaultMessage: `Warning`,
});
label.message = props.intl.formatMessage(
{
id: 'data.filter.filterBar.labelWarningInfo',
id: 'unifiedSearch.filter.filterBar.labelWarningInfo',
defaultMessage: 'Field {fieldName} does not exist in current view',
},
{

View file

@ -50,7 +50,7 @@ class FilterOptionsUI extends Component<Props, State> {
items: [
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.enableAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.enableAllFiltersButtonLabel',
defaultMessage: 'Enable all',
}),
icon: 'eye',
@ -62,7 +62,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.disableAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.disableAllFiltersButtonLabel',
defaultMessage: 'Disable all',
}),
icon: 'eyeClosed',
@ -74,7 +74,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.pinAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.pinAllFiltersButtonLabel',
defaultMessage: 'Pin all',
}),
icon: 'pin',
@ -86,7 +86,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.unpinAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.unpinAllFiltersButtonLabel',
defaultMessage: 'Unpin all',
}),
icon: 'pin',
@ -98,7 +98,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.invertNegatedFiltersButtonLabel',
id: 'unifiedSearch.filter.options.invertNegatedFiltersButtonLabel',
defaultMessage: 'Invert inclusion',
}),
icon: 'invert',
@ -110,7 +110,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.invertDisabledFiltersButtonLabel',
id: 'unifiedSearch.filter.options.invertDisabledFiltersButtonLabel',
defaultMessage: 'Invert enabled/disabled',
}),
icon: 'eye',
@ -122,7 +122,7 @@ class FilterOptionsUI extends Component<Props, State> {
},
{
name: this.props.intl.formatMessage({
id: 'data.filter.options.deleteAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.deleteAllFiltersButtonLabel',
defaultMessage: 'Remove all',
}),
icon: 'trash',
@ -146,11 +146,11 @@ class FilterOptionsUI extends Component<Props, State> {
onClick={this.togglePopover}
iconType="filter"
aria-label={this.props.intl.formatMessage({
id: 'data.filter.options.changeAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.changeAllFiltersButtonLabel',
defaultMessage: 'Change all filters',
})}
title={this.props.intl.formatMessage({
id: 'data.filter.options.changeAllFiltersButtonLabel',
id: 'unifiedSearch.filter.options.changeAllFiltersButtonLabel',
defaultMessage: 'Change all filters',
})}
data-test-subj="showFilterActions"
@ -163,7 +163,7 @@ class FilterOptionsUI extends Component<Props, State> {
>
<EuiPopoverTitle paddingSize="m">
<FormattedMessage
id="data.filter.searchBar.changeAllFiltersTitle"
id="unifiedSearch.filter.searchBar.changeAllFiltersTitle"
defaultMessage="Change all filters"
/>
</EuiPopoverTitle>

View file

@ -38,18 +38,18 @@ export const FilterView: FC<Props> = ({
let title =
errorMessage ||
i18n.translate('data.filter.filterBar.moreFilterActionsMessage', {
i18n.translate('unifiedSearch.filter.filterBar.moreFilterActionsMessage', {
defaultMessage: 'Filter: {innerText}. Select for more filter actions.',
values: { innerText },
});
if (isFilterPinned(filter)) {
title = `${i18n.translate('data.filter.filterBar.pinnedFilterPrefix', {
title = `${i18n.translate('unifiedSearch.filter.filterBar.pinnedFilterPrefix', {
defaultMessage: 'Pinned',
})} ${title}`;
}
if (filter.meta.disabled) {
title = `${i18n.translate('data.filter.filterBar.disabledFilterPrefix', {
title = `${i18n.translate('unifiedSearch.filter.filterBar.disabledFilterPrefix', {
defaultMessage: 'Disabled',
})} ${title}`;
}
@ -59,9 +59,12 @@ export const FilterView: FC<Props> = ({
title,
color: 'hollow',
onClick,
onClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemReadOnlyBadgeAriaLabel', {
defaultMessage: 'Filter entry',
}),
onClickAriaLabel: i18n.translate(
'unifiedSearch.filter.filterBar.filterItemReadOnlyBadgeAriaLabel',
{
defaultMessage: 'Filter entry',
}
),
iconOnClick,
}
: {
@ -75,14 +78,20 @@ export const FilterView: FC<Props> = ({
tabIndex: -1,
},
iconOnClick,
iconOnClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemBadgeIconAriaLabel', {
defaultMessage: 'Delete {filter}',
values: { filter: innerText },
}),
iconOnClickAriaLabel: i18n.translate(
'unifiedSearch.filter.filterBar.filterItemBadgeIconAriaLabel',
{
defaultMessage: 'Delete {filter}',
values: { filter: innerText },
}
),
onClick,
onClickAriaLabel: i18n.translate('data.filter.filterBar.filterItemBadgeAriaLabel', {
defaultMessage: 'Filter actions',
}),
onClickAriaLabel: i18n.translate(
'unifiedSearch.filter.filterBar.filterItemBadgeAriaLabel',
{
defaultMessage: 'Filter actions',
}
),
};
return (

View file

@ -10,6 +10,13 @@ import React from 'react';
const Fallback = () => <div />;
const LazyFilterBar = React.lazy(() => import('./filter_bar'));
export const FilterBar = (props: React.ComponentProps<typeof LazyFilterBar>) => (
<React.Suspense fallback={<Fallback />}>
<LazyFilterBar {...props} />
</React.Suspense>
);
const LazyFilterLabel = React.lazy(() => import('./filter_editor/lib/filter_label'));
export const FilterLabel = (props: React.ComponentProps<typeof LazyFilterLabel>) => (
<React.Suspense fallback={<Fallback />}>

View file

@ -1,10 +1,7 @@
@import './filter_bar/index';
@import './typeahead/index';
@import './saved_query_management/index';
@import './query_string_input/index';
@import './shard_failure_modal/shard_failure_modal';
@import './filter_bar/index';

View file

@ -0,0 +1,27 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { PluginInitializerContext } from '../../../core/public';
import { ConfigSchema } from '../config';
import { UnifiedSearchPublicPlugin } from './plugin';
export type { IndexPatternSelectProps } from './index_pattern_select';
export type { QueryStringInputProps } from './query_string_input';
export { QueryStringInput } from './query_string_input';
export type { StatefulSearchBarProps, SearchBarProps } from './search_bar';
export type { UnifiedSearchPublicPluginStart } from './types';
export { SearchBar } from './search_bar';
export { FilterLabel, FilterItem } from './filter_bar';
export type { ApplyGlobalFilterActionContext } from './actions';
export { ACTION_GLOBAL_APPLY_FILTER } from './actions';
// This exports static code and TypeScript types,
// as well as, Kibana Platform `plugin()` initializer.
export function plugin(initializerContext: PluginInitializerContext<ConfigSchema>) {
return new UnifiedSearchPublicPlugin(initializerContext);
}

View file

@ -9,7 +9,7 @@
import _ from 'lodash';
import React from 'react';
import { IndexPatternsContract } from 'src/plugins/data/public';
import { IndexPatternsContract } from '../../../data/public';
import { IndexPatternSelect, IndexPatternSelectProps } from './';
// Takes in stateful runtime dependencies and pre-wires them to the component

View file

@ -11,8 +11,7 @@ import React, { Component } from 'react';
import { Required } from '@kbn/utility-types';
import { EuiComboBox, EuiComboBoxProps } from '@elastic/eui';
import { IndexPatternsContract } from 'src/plugins/data/public';
import { IndexPatternsContract } from '../../../data/public';
export type IndexPatternSelectProps = Required<
Omit<

Some files were not shown because too many files have changed in this diff Show more