From 982aaa40381f015f921e142a315dc72872f910ac Mon Sep 17 00:00:00 2001 From: Anan Zhuang Date: Thu, 21 Sep 2023 16:13:49 -0700 Subject: [PATCH] [Data Explorer][Discover 2.0] Implement saved search embeddable (#5081) * [Data Explorer][Discover 2.0] Implement saved search embeddable Issue Resolve https://github.com/opensearch-project/OpenSearch-Dashboards/issues/4233 --------- Signed-off-by: ananzh --- .../discover/public/embeddable/constants.ts | 31 ++ .../discover/public/embeddable/index.ts | 33 ++ .../public/embeddable/search_embeddable.tsx | 408 ++++++++++++++++++ .../search_embeddable_component.tsx | 58 +++ .../embeddable/search_embeddable_factory.tsx | 114 +++++ .../discover/public/embeddable/types.ts | 62 +++ src/plugins/discover/public/index.ts | 4 +- src/plugins/discover/public/plugin.ts | 12 +- yarn.lock | 5 - 9 files changed, 713 insertions(+), 14 deletions(-) create mode 100644 src/plugins/discover/public/embeddable/constants.ts create mode 100644 src/plugins/discover/public/embeddable/index.ts create mode 100644 src/plugins/discover/public/embeddable/search_embeddable.tsx create mode 100644 src/plugins/discover/public/embeddable/search_embeddable_component.tsx create mode 100644 src/plugins/discover/public/embeddable/search_embeddable_factory.tsx create mode 100644 src/plugins/discover/public/embeddable/types.ts diff --git a/src/plugins/discover/public/embeddable/constants.ts b/src/plugins/discover/public/embeddable/constants.ts new file mode 100644 index 000000000000..82f428ea4e4b --- /dev/null +++ b/src/plugins/discover/public/embeddable/constants.ts @@ -0,0 +1,31 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * 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. + */ + +export const SEARCH_EMBEDDABLE_TYPE = 'search'; diff --git a/src/plugins/discover/public/embeddable/index.ts b/src/plugins/discover/public/embeddable/index.ts new file mode 100644 index 000000000000..ecb5e98f43c1 --- /dev/null +++ b/src/plugins/discover/public/embeddable/index.ts @@ -0,0 +1,33 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * 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. + */ + +export { SEARCH_EMBEDDABLE_TYPE } from './constants'; +export * from './types'; +export * from './search_embeddable_factory'; diff --git a/src/plugins/discover/public/embeddable/search_embeddable.tsx b/src/plugins/discover/public/embeddable/search_embeddable.tsx new file mode 100644 index 000000000000..76b6b9f449c4 --- /dev/null +++ b/src/plugins/discover/public/embeddable/search_embeddable.tsx @@ -0,0 +1,408 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * 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 { isEqual } from 'lodash'; +import * as Rx from 'rxjs'; +import { Subscription } from 'rxjs'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { i18n } from '@osd/i18n'; +import { UiActionsStart, APPLY_FILTER_TRIGGER } from '../../../ui_actions/public'; +import { RequestAdapter, Adapters } from '../../../inspector/public'; +import { + opensearchFilters, + Filter, + TimeRange, + FilterManager, + getTime, + Query, + IFieldType, +} from '../../../data/public'; +import { Container, Embeddable } from '../../../embeddable/public'; +import { ISearchEmbeddable, SearchInput, SearchOutput } from './types'; +import { getDefaultSort } from '../application/view_components/utils/get_default_sort'; +import { getSortForSearchSource } from '../application/view_components/utils/get_sort_for_search_source'; +import { + getRequestInspectorStats, + getResponseInspectorStats, + getServices, + IndexPattern, + ISearchSource, +} from '../opensearch_dashboards_services'; +import { SEARCH_EMBEDDABLE_TYPE } from './constants'; +import { SortOrder } from '../saved_searches/types'; +import { SavedSearch } from '../saved_searches'; +import { + SAMPLE_SIZE_SETTING, + SORT_DEFAULT_ORDER_SETTING, + DOC_HIDE_TIME_COLUMN_SETTING, +} from '../../common'; +import { SearchEmbeddableComponent } from './search_embeddable_component'; +import { DiscoverServices } from '../build_services'; +import * as columnActions from '../application/utils/state_management/common'; +import { buildColumns } from '../application/utils/columns'; + +export interface SearchProps { + columns?: string[]; + description?: string; + sort?: SortOrder[]; + onSort?: (sort: SortOrder[]) => void; + sharedItemTitle?: string; + inspectorAdapters?: Adapters; + onSetColumns?: (columns: string[]) => void; + onRemoveColumn?: (column: string) => void; + onAddColumn?: (column: string) => void; + onMoveColumn?: (column: string, index: number) => void; + onFilter?: (field: IFieldType, value: string[], operator: string) => void; + rows?: any[]; + indexPattern?: IndexPattern; + totalHitCount?: number; + isLoading?: boolean; + displayTimeColumn?: boolean; + services: DiscoverServices; +} + +interface SearchEmbeddableConfig { + savedSearch: SavedSearch; + editUrl: string; + editPath: string; + indexPatterns?: IndexPattern[]; + editable: boolean; + filterManager: FilterManager; + services: DiscoverServices; +} + +export class SearchEmbeddable + extends Embeddable + implements ISearchEmbeddable { + private readonly savedSearch: SavedSearch; + private inspectorAdaptors: Adapters; + private searchProps?: SearchProps; + private panelTitle: string = ''; + private filtersSearchSource?: ISearchSource; + private autoRefreshFetchSubscription?: Subscription; + private subscription?: Subscription; + public readonly type = SEARCH_EMBEDDABLE_TYPE; + private services: DiscoverServices; + private filterManager: FilterManager; + private abortController?: AbortController; + + private prevTimeRange?: TimeRange; + private prevFilters?: Filter[]; + private prevQuery?: Query; + + private node?: HTMLElement; + + constructor( + { + savedSearch, + editUrl, + editPath, + indexPatterns, + editable, + filterManager, + services, + }: SearchEmbeddableConfig, + initialInput: SearchInput, + private readonly executeTriggerActions: UiActionsStart['executeTriggerActions'], + parent?: Container + ) { + super( + initialInput, + { + defaultTitle: savedSearch.title, + editUrl, + editPath, + editApp: 'discover', + indexPatterns, + editable, + }, + parent + ); + + this.services = services; + this.filterManager = filterManager; + this.savedSearch = savedSearch; + this.inspectorAdaptors = { + requests: new RequestAdapter(), + }; + this.initializeSearchProps(); + + this.autoRefreshFetchSubscription = getServices() + .timefilter.getAutoRefreshFetch$() + .subscribe(this.fetch); + + this.subscription = Rx.merge(this.getOutput$(), this.getInput$()).subscribe(() => { + this.panelTitle = this.output.title || ''; + + if (this.searchProps) { + this.pushContainerStateParamsToProps(this.searchProps); + } + }); + } + + public getInspectorAdapters() { + return this.inspectorAdaptors; + } + + public getSavedSearch() { + return this.savedSearch; + } + + /** + * + * @param {Element} domNode + */ + public render(node: HTMLElement) { + if (!this.searchProps) { + throw new Error('Search scope not defined'); + } + if (this.node) { + ReactDOM.unmountComponentAtNode(this.node); + } + this.node = node; + } + + public destroy() { + super.destroy(); + if (this.searchProps) { + delete this.searchProps; + } + if (this.subscription) { + this.subscription.unsubscribe(); + } + if (this.node) { + ReactDOM.unmountComponentAtNode(this.node); + } + if (this.autoRefreshFetchSubscription) { + this.autoRefreshFetchSubscription.unsubscribe(); + } + if (this.abortController) this.abortController.abort(); + } + + private initializeSearchProps() { + const { searchSource } = this.savedSearch; + const indexPattern = searchSource.getField('index'); + if (!indexPattern) { + return; + } + + const sort = getDefaultSort( + indexPattern, + this.services.uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc') + ); + this.savedSearch.sort = sort; + + const searchProps: SearchProps = { + columns: this.savedSearch.columns, + sort: [], + inspectorAdapters: this.inspectorAdaptors, + rows: [], + description: this.savedSearch.description, + services: this.services, + indexPattern, + isLoading: false, + displayTimeColumn: !this.services.uiSettings.get(DOC_HIDE_TIME_COLUMN_SETTING, false), + }; + + const timeRangeSearchSource = searchSource.create(); + timeRangeSearchSource.setField('filter', () => { + if (!this.searchProps || !this.input.timeRange) return; + return getTime(indexPattern, this.input.timeRange); + }); + + this.filtersSearchSource = searchSource.create(); + this.filtersSearchSource.setParent(timeRangeSearchSource); + + searchSource.setParent(this.filtersSearchSource); + + searchProps.onSort = (newSort) => { + this.updateInput({ sort: newSort }); + }; + + searchProps.onAddColumn = (columnName: string) => { + if (!searchProps.columns) { + return; + } + const updatedColumns = buildColumns( + columnActions.addColumn(searchProps.columns, { column: columnName }) + ); + this.updateInput({ columns: updatedColumns }); + }; + + searchProps.onRemoveColumn = (columnName: string) => { + if (!searchProps.columns) { + return; + } + const updatedColumns = columnActions.removeColumn(searchProps.columns, columnName); + const updatedSort = + searchProps.sort && searchProps.sort.length + ? searchProps.sort.filter((s) => s[0] !== columnName) + : []; + this.updateInput({ sort: updatedSort, columns: updatedColumns }); + }; + + searchProps.onMoveColumn = (columnName, newIndex: number) => { + if (!searchProps.columns) { + return; + } + const oldIndex = searchProps.columns.indexOf(columnName); + const updatedColumns = columnActions.reorderColumn(searchProps.columns, oldIndex, newIndex); + this.updateInput({ columns: updatedColumns }); + }; + + searchProps.onSetColumns = (columnNames: string[]) => { + const columns = buildColumns(columnNames); + this.updateInput({ columns }); + }; + + searchProps.onFilter = async (field, value, operator) => { + let filters = opensearchFilters.generateFilters( + this.filterManager, + field, + value, + operator, + indexPattern.id! + ); + filters = filters.map((filter) => ({ + ...filter, + $state: { store: opensearchFilters.FilterStateStore.APP_STATE }, + })); + + await this.executeTriggerActions(APPLY_FILTER_TRIGGER, { + embeddable: this, + filters, + }); + }; + + this.pushContainerStateParamsToProps(searchProps); + } + + public reload() { + if (this.searchProps) { + this.pushContainerStateParamsToProps(this.searchProps); + } + } + + private fetch = async () => { + if (!this.searchProps) return; + + const { searchSource } = this.savedSearch; + + // Abort any in-progress requests + if (this.abortController) this.abortController.abort(); + this.abortController = new AbortController(); + + searchSource.setField('size', getServices().uiSettings.get(SAMPLE_SIZE_SETTING)); + searchSource.setField( + 'sort', + getSortForSearchSource( + this.searchProps.sort, + this.searchProps.indexPattern, + getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING) + ) + ); + + // Log request to inspector + this.inspectorAdaptors.requests.reset(); + const title = i18n.translate('discover.embeddable.inspectorRequestDataTitle', { + defaultMessage: 'Data', + }); + const description = i18n.translate('discover.embeddable.inspectorRequestDescription', { + defaultMessage: 'This request queries OpenSearch to fetch the data for the search.', + }); + const inspectorRequest = this.inspectorAdaptors.requests.start(title, { description }); + inspectorRequest.stats(getRequestInspectorStats(searchSource)); + searchSource.getSearchRequestBody().then((body: Record) => { + inspectorRequest.json(body); + }); + this.updateOutput({ loading: true, error: undefined }); + this.searchProps!.isLoading = true; + + try { + // Make the request + const resp = await searchSource.fetch({ + abortSignal: this.abortController.signal, + }); + this.updateOutput({ loading: false, error: undefined }); + + // Log response to inspector + inspectorRequest.stats(getResponseInspectorStats(resp, searchSource)).ok({ json: resp }); + + this.searchProps!.rows = resp.hits.hits; + this.searchProps!.totalHitCount = resp.hits.total; + this.searchProps!.isLoading = false; + } catch (error) { + this.updateOutput({ loading: false, error }); + this.searchProps!.isLoading = false; + } + }; + + private renderComponent(node: HTMLElement, searchProps: SearchProps) { + if (!this.searchProps) { + return; + } + const props = { + searchProps, + }; + ReactDOM.render(, node); + } + + private async pushContainerStateParamsToProps(searchProps: SearchProps) { + const isFetchRequired = + !opensearchFilters.onlyDisabledFiltersChanged(this.input.filters, this.prevFilters) || + !isEqual(this.prevQuery, this.input.query) || + !isEqual(this.prevTimeRange, this.input.timeRange) || + !isEqual(searchProps.sort, this.input.sort || this.savedSearch.sort); + + // If there is column or sort data on the panel, that means the original columns or sort settings have + // been overridden in a dashboard. + searchProps.columns = this.input.columns || this.savedSearch.columns; + searchProps.sort = this.input.sort || this.savedSearch.sort; + searchProps.sharedItemTitle = this.panelTitle; + + if (isFetchRequired) { + this.filtersSearchSource!.setField('filter', this.input.filters); + this.filtersSearchSource!.setField('query', this.input.query); + this.prevFilters = this.input.filters; + this.prevQuery = this.input.query; + this.prevTimeRange = this.input.timeRange; + this.searchProps = searchProps; + + await this.fetch(); + } else if (this.searchProps) { + this.searchProps = searchProps; + } + + if (this.node) { + this.renderComponent(this.node, this.searchProps!); + } + } +} diff --git a/src/plugins/discover/public/embeddable/search_embeddable_component.tsx b/src/plugins/discover/public/embeddable/search_embeddable_component.tsx new file mode 100644 index 000000000000..c9a08844e9a0 --- /dev/null +++ b/src/plugins/discover/public/embeddable/search_embeddable_component.tsx @@ -0,0 +1,58 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { I18nProvider } from '@osd/i18n/react'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { SearchProps } from './search_embeddable'; +import { + DataGridTable, + DataGridTableProps, +} from '../application/components/data_grid/data_grid_table'; +import { VisualizationNoResults } from '../../../visualizations/public'; + +interface SearchEmbeddableProps { + searchProps: SearchProps; +} +export interface DiscoverEmbeddableProps extends DataGridTableProps { + totalHitCount: number; +} + +export const DataGridTableMemoized = React.memo((props: DataGridTableProps) => ( + +)); + +export function SearchEmbeddableComponent({ searchProps }: SearchEmbeddableProps) { + const discoverEmbeddableProps = { + columns: searchProps.columns, + indexPattern: searchProps.indexPattern, + onAddColumn: searchProps.onAddColumn, + onFilter: searchProps.onFilter, + onRemoveColumn: searchProps.onRemoveColumn, + onSort: searchProps.onSort, + rows: searchProps.rows, + onSetColumns: searchProps.onSetColumns, + sort: searchProps.sort, + displayTimeColumn: searchProps.displayTimeColumn, + services: searchProps.services, + totalHitCount: searchProps.totalHitCount, + } as DiscoverEmbeddableProps; + + return ( + + + {discoverEmbeddableProps.totalHitCount !== 0 ? ( + + + + ) : ( + + + + )} + + + ); +} diff --git a/src/plugins/discover/public/embeddable/search_embeddable_factory.tsx b/src/plugins/discover/public/embeddable/search_embeddable_factory.tsx new file mode 100644 index 000000000000..8d99b87fbeb2 --- /dev/null +++ b/src/plugins/discover/public/embeddable/search_embeddable_factory.tsx @@ -0,0 +1,114 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * 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 { i18n } from '@osd/i18n'; +import { UiActionsStart } from 'src/plugins/ui_actions/public'; +import { getServices } from '../opensearch_dashboards_services'; +import { + EmbeddableFactoryDefinition, + Container, + ErrorEmbeddable, +} from '../../../embeddable/public'; +import { TimeRange } from '../../../data/public'; +import { SearchEmbeddable } from './search_embeddable'; +import { SearchInput, SearchOutput } from './types'; +import { SEARCH_EMBEDDABLE_TYPE } from './constants'; + +interface StartServices { + executeTriggerActions: UiActionsStart['executeTriggerActions']; + isEditable: () => boolean; +} + +export class SearchEmbeddableFactory + implements EmbeddableFactoryDefinition { + public readonly type = SEARCH_EMBEDDABLE_TYPE; + public readonly savedObjectMetaData = { + name: i18n.translate('discover.savedSearch.savedObjectName', { + defaultMessage: 'Saved search', + }), + type: 'search', + getIconForSavedObject: () => 'search', + }; + + constructor(private getStartServices: () => Promise) {} + + public canCreateNew() { + return false; + } + + public isEditable = async () => { + return (await this.getStartServices()).isEditable(); + }; + + public getDisplayName() { + return i18n.translate('discover.embeddable.search.displayName', { + defaultMessage: 'search', + }); + } + + public createFromSavedObject = async ( + savedObjectId: string, + input: Partial & { id: string; timeRange: TimeRange }, + parent?: Container + ): Promise => { + const services = getServices(); + const filterManager = services.filterManager; + const url = await services.getSavedSearchUrlById(savedObjectId); + const editUrl = services.addBasePath(`/app/data-explorer/discover${url}`); + + try { + const savedObject = await services.getSavedSearchById(savedObjectId); + const indexPattern = savedObject.searchSource.getField('index'); + const { executeTriggerActions } = await this.getStartServices(); + const { SearchEmbeddable: SearchEmbeddableClass } = await import('./search_embeddable'); + return new SearchEmbeddableClass( + { + savedSearch: savedObject, + editUrl, + editPath: url, + filterManager, + editable: services.capabilities.discover.save as boolean, + indexPatterns: indexPattern ? [indexPattern] : [], + services, + }, + input, + executeTriggerActions, + parent + ); + } catch (e) { + console.error(e); // eslint-disable-line no-console + return new ErrorEmbeddable(e, input, parent); + } + }; + + public async create(input: SearchInput) { + return new ErrorEmbeddable('Saved searches can only be created from a saved object', input); + } +} diff --git a/src/plugins/discover/public/embeddable/types.ts b/src/plugins/discover/public/embeddable/types.ts new file mode 100644 index 000000000000..24a1aac92b49 --- /dev/null +++ b/src/plugins/discover/public/embeddable/types.ts @@ -0,0 +1,62 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Any modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +/* + * 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 { + Embeddable, + EmbeddableInput, + EmbeddableOutput, + IEmbeddable, +} from 'src/plugins/embeddable/public'; +import { Filter, IIndexPattern, TimeRange, Query } from '../../../../data/public'; +import { SortOrder } from '../saved_searches/types'; +import { SavedSearch } from '../saved_searches'; + +export interface SearchInput extends EmbeddableInput { + timeRange: TimeRange; + query?: Query; + filters?: Filter[]; + hidePanelTitles?: boolean; + columns?: string[]; + sort?: SortOrder[]; +} + +export interface SearchOutput extends EmbeddableOutput { + editUrl: string; + indexPatterns?: IIndexPattern[]; + editable: boolean; +} + +export interface ISearchEmbeddable extends IEmbeddable { + getSavedSearch(): SavedSearch; +} + +export interface SearchEmbeddable extends Embeddable { + type: string; +} diff --git a/src/plugins/discover/public/index.ts b/src/plugins/discover/public/index.ts index 191ecf14cbbf..164aea1fb5bc 100644 --- a/src/plugins/discover/public/index.ts +++ b/src/plugins/discover/public/index.ts @@ -37,6 +37,6 @@ export function plugin(initializerContext: PluginInitializerContext) { } export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches'; -// TODO: Fix embeddable after removing Angular -// export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable'; + +export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './embeddable'; export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator'; diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts index e14272e090ba..4d28083b8892 100644 --- a/src/plugins/discover/public/plugin.ts +++ b/src/plugins/discover/public/plugin.ts @@ -59,7 +59,7 @@ import { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGenerator, } from './url_generator'; -// import { SearchEmbeddableFactory } from './application/embeddable'; +import { SearchEmbeddableFactory } from './embeddable'; import { PLUGIN_ID } from '../common'; import { DataExplorerPluginSetup } from '../../data_explorer/public'; import { registerFeature } from './register_feature'; @@ -338,7 +338,7 @@ export class DiscoverPlugin Context: lazy(() => import('./application/view_components/context')), }); - // this.registerEmbeddable(core, plugins); + this.registerEmbeddable(core, plugins); return { docViews: { @@ -384,9 +384,8 @@ export class DiscoverPlugin } } - // TODO: Use this registration when legacy discover is removed /** - * register embeddable with a slimmer embeddable version of inner angular + * register embeddable */ private registerEmbeddable(core: CoreSetup, plugins: DiscoverSetupPlugins) { const getStartServices = async () => { @@ -397,8 +396,7 @@ export class DiscoverPlugin }; }; - // TODO: Refactor to remove angular - // const factory = new SearchEmbeddableFactory(getStartServices, this.getEmbeddableInjector); - // plugins.embeddable.registerEmbeddableFactory(factory.type, factory); + const factory = new SearchEmbeddableFactory(getStartServices); + plugins.embeddable.registerEmbeddableFactory(factory.type, factory); } } diff --git a/yarn.lock b/yarn.lock index 6df97ecb5926..98c4cd2b4219 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13047,11 +13047,6 @@ next-tick@1, next-tick@^1.1.0: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== -ngreact@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/ngreact/-/ngreact-0.5.2.tgz#d48180b578b186ad70861a3de9ba508b3f22b2ae" - integrity sha512-FCQGtTkDrnI3ywhvK9wUf7C6SYfqKDdRW+cPvy358GFe3AnA4rfvWisDVUQyf5YwNr439ito9xUuuEv80QXhSQ== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"